/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.Update(TSingle, string, string, RequestParameter[])">Update</see> /// </summary> public virtual void Update( TSingle obj, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append($"/{obj.RefId}") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)) .ToString(); string requestBody = SerialiseSingle(obj); string responseBody = HttpUtils.PutRequest( url, RegistrationService.AuthorisationToken, requestBody, ConsumerSettings.CompressPayload, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug("Response from PUT request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.Delete(TPrimaryKey, string, string, RequestParameter[])">Delete</see> /// </summary> public virtual void Delete( TPrimaryKey refId, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append($"/{refId}") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)).ToString(); string responseBody = HttpUtils.DeleteRequest( url, RegistrationService.AuthorisationToken, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug("Response from DELETE request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.QueryByServicePath(IEnumerable{EqualCondition}, uint?, uint?, string, string, RequestParameter[])">QueryByServicePath</see> /// </summary> public virtual TMultiple QueryByServicePath( IEnumerable <EqualCondition> conditions, uint?navigationPage = null, uint?navigationPageSize = null, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } StringBuilder servicePath = new StringBuilder(); if (conditions != null) { foreach (EqualCondition condition in conditions) { servicePath.Append("/" + condition.Left + "/" + condition.Right); } } string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append(servicePath) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)).ToString(); if (log.IsDebugEnabled) { log.Debug("Service Path URL is " + url); } string responseBody; if (navigationPage.HasValue && navigationPageSize.HasValue) { responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, ServiceType.SERVICEPATH, navigationPage: (int)navigationPage, navigationPageSize: (int)navigationPageSize, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } else { responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, ServiceType.SERVICEPATH, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } return(DeserialiseMultiple(responseBody)); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.Query(TPrimaryKey, string, string, RequestParameter[])">Query</see> /// </summary> public virtual TSingle Query( TPrimaryKey refId, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } TSingle obj = default(TSingle); try { string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append($"/{refId}") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)).ToString(); string responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug("Response from GET request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } obj = DeserialiseSingle(responseBody); } catch (WebException ex) { if (WebExceptionStatus.ProtocolError.Equals(ex.Status) && ex.Response != null) { HttpStatusCode statusCode = ((HttpWebResponse)ex.Response).StatusCode; if (!HttpStatusCode.NotFound.Equals(statusCode)) { throw; } } else { throw; } } catch (Exception) { throw; } return(obj); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.QueryChangesSince(string, out string, uint?, uint?, string, string, RequestParameter[])">QueryChangesSince</see> /// </summary> public virtual TMultiple QueryChangesSince( string changesSinceMarker, out string nextChangesSinceMarker, uint?navigationPage = null, uint?navigationPageSize = null, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } RequestParameter[] messageParameters = (requestParameters ?? (new RequestParameter[0])); messageParameters = string.IsNullOrWhiteSpace(changesSinceMarker) ? messageParameters : messageParameters .Concat(new RequestParameter[] { new ChangesSinceQueryParameter(changesSinceMarker) }) .ToArray(); var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(messageParameters)) .ToString(); WebHeaderCollection responseHeaders; string responseBody; if (navigationPage.HasValue && navigationPageSize.HasValue) { responseBody = HttpUtils.GetRequestAndHeaders( url, RegistrationService.AuthorisationToken, ConsumerSettings.CompressPayload, out responseHeaders, navigationPage: (int)navigationPage, navigationPageSize: (int)navigationPageSize, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } else { responseBody = HttpUtils.GetRequestAndHeaders( url, RegistrationService.AuthorisationToken, ConsumerSettings.CompressPayload, out responseHeaders, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } nextChangesSinceMarker = responseHeaders[ResponseParameterType.changesSinceMarker.ToDescription()]; return(DeserialiseMultiple(responseBody)); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.Delete(IEnumerable{TPrimaryKey}, string, string, RequestParameter[])">Delete</see> /// </summary> public virtual MultipleDeleteResponse Delete( IEnumerable <TPrimaryKey> refIds, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } List <deleteIdType> deleteIds = new List <deleteIdType>(); foreach (TPrimaryKey id in refIds) { deleteIdType deleteId = new deleteIdType { id = id.ToString() }; deleteIds.Add(deleteId); } deleteRequestType request = new deleteRequestType { deletes = deleteIds.ToArray() }; string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)).ToString(); string requestBody = SerialiserFactory.GetSerialiser <deleteRequestType>(ContentType).Serialise(request); string responseBody = HttpUtils.PutRequest( url, RegistrationService.AuthorisationToken, requestBody, methodOverride: "DELETE", contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug("Response from PUT (DELETE) request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } deleteResponseType updateResponseType = SerialiserFactory.GetSerialiser <deleteResponseType>(Accept).Deserialise(responseBody); MultipleDeleteResponse updateResponse = MapperFactory.CreateInstance <deleteResponseType, MultipleDeleteResponse>(updateResponseType); return(updateResponse); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.QueryChangesSince(string, out string, uint?, uint?, string, string, RequestParameter[])">QueryChangesSince</see> /// </summary> public TMultiple DynamicQuery( string whereClause, uint?navigationPage = null, uint?navigationPageSize = null, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } RequestParameter[] messageParameters = (requestParameters ?? (new RequestParameter[0])); messageParameters = string.IsNullOrWhiteSpace(whereClause) ? messageParameters : messageParameters.Concat(new RequestParameter[] { new DynamicQueryParameter(whereClause) }).ToArray(); var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(messageParameters)) .ToString(); string responseBody; if (navigationPage.HasValue && navigationPageSize.HasValue) { responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, ConsumerSettings.CompressPayload, navigationPage: (int)navigationPage, navigationPageSize: (int)navigationPageSize, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } else { responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, ConsumerSettings.CompressPayload, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } return(DeserialiseMultiple(responseBody)); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.Create(TMultiple, bool?, string, string, RequestParameter[])">Create</see> /// </summary> public virtual MultipleCreateResponse Create( TMultiple obj, bool?mustUseAdvisory = null, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)) .ToString(); string requestBody = SerialiseMultiple(obj); string responseBody = HttpUtils.PostRequest( url, RegistrationService.AuthorisationToken, requestBody, ConsumerSettings.CompressPayload, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription(), mustUseAdvisory: mustUseAdvisory); if (log.IsDebugEnabled) { log.Debug("Response from POST request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } createResponseType createResponseType = SerialiserFactory.GetSerialiser <createResponseType>(Accept).Deserialise(responseBody); MultipleCreateResponse createResponse = MapperFactory.CreateInstance <createResponseType, MultipleCreateResponse>(createResponseType); return(createResponse); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.Query(uint?, uint?, string, string, RequestParameter[])">Query</see> /// </summary> public virtual TMultiple Query( uint?navigationPage = null, uint?navigationPageSize = null, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)) .ToString(); string responseBody; if (navigationPage.HasValue && navigationPageSize.HasValue) { responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, ConsumerSettings.CompressPayload, navigationPage: (int)navigationPage, navigationPageSize: (int)navigationPageSize, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } else { responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, ConsumerSettings.CompressPayload, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); } return(DeserialiseMultiple(responseBody)); }
/// <summary> /// Retrieves a Queue that will be used by the Consumer using the subscription id. /// </summary> /// <param name="subscriptionId">The subscription's identifier.</param> /// <returns>Instance of the Subscription if id is valid and subscription is found, null otherwise.</returns> private subscriptionType RetrieveSubscription(string subscriptionId) { string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.subscriptions)}/{subscriptionId}"; string responseBody = HttpUtils.GetRequest( url, RegistrationService.AuthorisationToken, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug($"Response from GET {url} request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } return(DeserialiseSubscription(responseBody)); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.QueryByExample(TSingle, uint?, uint?, string, string, RequestParameter[])">QueryByExample</see> /// </summary> public virtual TMultiple QueryByExample( TSingle obj, uint?navigationPage = null, uint?navigationPageSize = null, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } var url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)) .ToString(); string requestBody = SerialiseSingle(obj); // TODO: Update PostRequest to accept paging parameters. string responseBody = HttpUtils.PostRequest( url, RegistrationService.AuthorisationToken, requestBody, ConsumerSettings.CompressPayload, methodOverride: "GET", contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug("Response from POST (Query by Example) request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } return(DeserialiseMultiple(responseBody)); }
/// <summary> /// Create a Queue that will be used by the Consumer. /// </summary> /// <param name="queue">Queue to create.</param> /// <returns>Instance of the created Queue.</returns> private queueType CreateQueue(queueType queue) { string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}"; string requestBody = SerialiseQueue(queue); string responseBody = HttpUtils.PostRequest( url, RegistrationService.AuthorisationToken, requestBody, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription()); if (log.IsDebugEnabled) { log.Debug($"Response from POST {url} request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } return(DeserialiseQueue(responseBody)); }
/// <summary> /// <see cref="IConsumer{TSingle,TMultiple,TPrimaryKey}.Create(TSingle, bool?, string, string, RequestParameter[])">Create</see> /// </summary> public virtual TSingle Create( TSingle obj, bool?mustUseAdvisory = null, string zoneId = null, string contextId = null, params RequestParameter[] requestParameters) { if (!RegistrationService.Registered) { throw new InvalidOperationException("Consumer has not registered."); } string url = new StringBuilder(EnvironmentUtils.ParseServiceUrl(EnvironmentTemplate)) .Append($"/{TypeName}s") .Append($"/{TypeName}") .Append(HttpUtils.MatrixParameters(zoneId, contextId)) .Append(GenerateQueryParameterString(requestParameters)).ToString(); string requestBody = SerialiseSingle(obj); string responseBody = HttpUtils.PostRequest( url, RegistrationService.AuthorisationToken, requestBody, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription(), mustUseAdvisory: mustUseAdvisory); if (log.IsDebugEnabled) { log.Debug("Response from POST request ..."); } if (log.IsDebugEnabled) { log.Debug(responseBody); } return(DeserialiseSingle(responseBody)); }
public virtual IHttpActionResult BroadcastEvents(string zoneId = null, string contextId = null) { var eventService = Service as IEventService <TMultiple>; bool eventsSupported = (eventService != null); if (!eventsSupported) { return(BadRequest("Support for SIF Events has not been implemented.")); } IHttpActionResult result; try { IRegistrationService registrationService = RegistrationManager.GetProviderRegistrationService( ProviderSettings, sessionService); if (registrationService is NoRegistrationService) { result = BadRequest("SIF Events are only supported in a BROKERED environment."); } else { IEventIterator <TMultiple> eventIterator = eventService.GetEventIterator(zoneId, contextId); if (eventIterator == null) { result = BadRequest("SIF Events implementation is not valid."); } else { Model.Infrastructure.Environment environment = registrationService.Register(); // Retrieve the current Authorisation Token. AuthorisationToken token = registrationService.AuthorisationToken; // Retrieve the EventsConnector endpoint URL. string url = EnvironmentUtils.ParseServiceUrl( environment, ServiceType.UTILITY, InfrastructureServiceNames.eventsConnector); while (eventIterator.HasNext()) { SifEvent <TMultiple> sifEvent = eventIterator.GetNext(); var requestHeaders = new NameValueCollection() { { EventParameterType.eventAction.ToDescription(), sifEvent.EventAction.ToDescription() }, { EventParameterType.messageId.ToDescription(), sifEvent.Id.ToString() }, { EventParameterType.messageType.ToDescription(), "EVENT" }, { EventParameterType.serviceName.ToDescription(), $"{TypeName}s" } }; switch (sifEvent.EventAction) { case EventAction.UPDATE_FULL: requestHeaders.Add(EventParameterType.Replacement.ToDescription(), "FULL"); break; case EventAction.UPDATE_PARTIAL: requestHeaders.Add(EventParameterType.Replacement.ToDescription(), "PARTIAL"); break; } string requestBody = SerialiseEvents(sifEvent.SifObjects); HttpUtils.PostRequest( url, token, requestBody, ProviderSettings.CompressPayload, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription(), requestHeaders: requestHeaders); } result = Ok(); } } } catch (Exception e) { result = InternalServerError(e); } return(result); }
/// <summary> /// Periodically process SIF Events. /// </summary> /// <param name="cancellationToken">Notification that processing should be cancelled.</param> private void ProcessEvents(CancellationToken cancellationToken) { while (true) { if (cancellationToken.IsCancellationRequested) { break; } bool getEvents = true; TimeSpan waitTime = TimeSpan.FromSeconds(SettingsManager.ConsumerSettings.EventProcessingWaitTime); string url = $"{EnvironmentUtils.ParseServiceUrl(Environment, ServiceType.UTILITY, InfrastructureServiceNames.queues)}/{Queue.id}/messages"; string deleteMessageId = null; // Read from the message queue until no more messages are found. do { try { string deleteMessageIdMatrixParameter = (deleteMessageId == null ? "" : $";deleteMessageId={deleteMessageId.Trim()}"); if (log.IsDebugEnabled) { log.Debug($"Making a request for an event message from {url}{deleteMessageIdMatrixParameter}."); } string responseBody = HttpUtils.GetRequestAndHeaders( $"{url}{deleteMessageIdMatrixParameter}", RegistrationService.AuthorisationToken, out WebHeaderCollection responseHeaders, contentTypeOverride: ContentType.ToDescription(), acceptOverride: Accept.ToDescription(), deleteMessageId: deleteMessageId); string contextId = responseHeaders?[EventParameterType.contextId.ToDescription()]; deleteMessageId = responseHeaders?[EventParameterType.messageId.ToDescription()]; string minWaitTimeValue = responseHeaders?[EventParameterType.minWaitTime.ToDescription()]; string zoneId = responseHeaders?[EventParameterType.zoneId.ToDescription()]; if (!string.IsNullOrWhiteSpace(minWaitTimeValue)) { if (double.TryParse(minWaitTimeValue, out double minWaitTime) && (TimeSpan.FromSeconds(minWaitTime) > waitTime)) { waitTime = TimeSpan.FromSeconds(minWaitTime); } } // Call the appropriate event handler for messages read. if (!string.IsNullOrWhiteSpace(responseBody)) { try { TMultiple obj = DeserialiseMultiple(responseBody); string eventAction = responseHeaders?[EventParameterType.eventAction.ToDescription()]; if (EventAction.CREATE.ToDescription().Equals(eventAction)) { if (log.IsDebugEnabled) { log.Debug($"Received create event message."); } OnCreateEvent(obj, zoneId, contextId); } else if (EventAction.DELETE.ToDescription().Equals(eventAction)) { if (log.IsDebugEnabled) { log.Debug($"Received delete event message."); } OnDeleteEvent(obj, zoneId, contextId); } else if ("UPDATE".Equals(eventAction)) { string replacement = responseHeaders?[EventParameterType.Replacement.ToDescription()]; if ("FULL".Equals(replacement)) { if (log.IsDebugEnabled) { log.Debug($"Received update (full) event message."); } OnUpdateEvent(obj, false, zoneId, contextId); } else if ("PARTIAL".Equals(replacement)) { if (log.IsDebugEnabled) { log.Debug($"Received update (partial) event message."); } OnUpdateEvent(obj, true, zoneId, contextId); } else { if (log.IsDebugEnabled) { log.Debug($"Received update (partial) event message."); } OnUpdateEvent(obj, true, zoneId, contextId); } } else { BaseException eventException = new EventException($"Event action {eventAction} not recognised for message received from {url}."); if (log.IsWarnEnabled) { log.Warn(eventException.Message); } ResponseError error = new ResponseError { Id = eventException.ExceptionReference, Code = 500, Message = eventException.Message, Description = responseBody, Scope = TypeName }; OnErrorEvent(error); } } catch (SerializationException e) { BaseException eventException = new EventException($"Event message received from {url} could not be processed due to the following error:\n{e.GetBaseException().Message}.", e); if (log.IsWarnEnabled) { log.Warn(e.Message); } ResponseError error = new ResponseError { Id = eventException.ExceptionReference, Code = 500, Message = e.Message, Description = responseBody, Scope = TypeName }; OnErrorEvent(error); } } else { if (log.IsDebugEnabled) { log.Debug($"No event messages."); } getEvents = false; } } catch (Exception e) { string errorMessage = $"Error processing event messages due to the following error:\n{e.GetBaseException().Message}."; if (log.IsErrorEnabled) { log.Error($"{errorMessage}\n{e.StackTrace}"); } getEvents = false; } } while (getEvents); if (log.IsDebugEnabled) { log.Debug($"Wait time is {waitTime.Seconds} seconds."); } // Wait an appropriate amount of time before reading from the message queue again. Thread.Sleep(waitTime); } }