/// <summary> /// Simply return the Identity from the XML string representation. /// </summary> /// <returns>The next SIF Event; null if there are parsing errors with the message.</returns> public SifEvent <Identity> GetNextEvent() { SifEvent <Identity> sifEvent = null; try { Identity identity = (Identity)sifParser.Parse(messages[eventMessageCount]); if (log.IsDebugEnabled) { log.Debug("Next Identity event record:\n" + identity.ToXml()); } sifEvent = new SifEvent <Identity>(identity, EventAction.Change); } catch (AdkParsingException e) { if (log.IsWarnEnabled) { log.Warn("The following event message from IdentityIterator has been ignored due to parsing errors: " + messages[eventMessageCount] + ".", e); } } finally { eventMessageCount++; } return(sifEvent); }
/// <summary> /// Process an event for the Identity SIF Object. /// </summary> /// <param name="sifEvent">Identity event received.</param> /// <param name="zone">Zone used.</param> protected override void ProcessEvent(SifEvent <Identity> sifEvent, IZone zone) { if (log.IsDebugEnabled) { log.Debug("Received a " + sifEvent.EventAction.ToString() + " event for Identity in Zone " + zone.ZoneId + ":\n" + sifEvent.SifDataObject.ToXml()); } }
/// <summary> /// Simply return the SchoolInfo from the XML string representation. /// </summary> /// <returns>The next SIF Event; null if there are parsing errors with the message.</returns> public SifEvent <SchoolInfo> GetNextEvent() { SifEvent <SchoolInfo> sifEvent = null; try { SchoolInfo schoolInfo = (SchoolInfo)sifParser.Parse(messages[eventMessageCount]); if (log.IsDebugEnabled) { log.Debug("Next SchoolInfo event record:\n" + schoolInfo.ToXml()); } sifEvent = new SifEvent <SchoolInfo>(schoolInfo, EventAction.Change); } catch (AdkParsingException e) { if (log.IsWarnEnabled) { log.Warn("The following event message from SchoolInfoIterator has been ignored due to parsing errors: " + messages[eventMessageCount] + ".", e); } } finally { eventMessageCount++; } return(sifEvent); }
/// <summary> /// Simply return the StaffPersonal from the XML string representation. /// </summary> /// <returns>The next SIF Event; null if there are parsing errors with the message.</returns> public SifEvent <StaffPersonal> GetNextEvent() { SifEvent <StaffPersonal> sifEvent = null; try { StaffPersonal staffPersonal = (StaffPersonal)sifParser.Parse(messages[eventMessageCount]); if (log.IsDebugEnabled) { log.Debug("Next StaffPersonal event record:\n" + staffPersonal.ToXml()); } sifEvent = new SifEvent <StaffPersonal>(staffPersonal, EventAction.Change); } catch (AdkParsingException e) { if (log.IsWarnEnabled) { log.Warn("The following event message from StaffPersonalIterator has been ignored due to parsing errors: " + messages[eventMessageCount] + ".", e); } } finally { eventMessageCount++; } return(sifEvent); }
/// <summary> /// Process an event for the StudentPersonal SIF Object. /// </summary> /// <param name="sifEvent">StudentPersonal event received.</param> /// <param name="zone">Zone used.</param> protected override void ProcessEvent(SifEvent<StudentPersonal> sifEvent, IZone zone) { if (!receivedSifRefIds.Contains(sifEvent.SifDataObject.RefId)) { receivedSifRefIds.Add(sifEvent.SifDataObject.RefId); } if (log.IsDebugEnabled) log.Debug("Received a " + sifEvent.EventAction.ToString() + " event for StudentPersonal in Zone " + zone.ZoneId + " with a SifRefId of " + sifEvent.SifDataObject.RefId + ":\n" + sifEvent.SifDataObject.ToXml()); }
/// <summary> /// This implementation will simply print the received StudentPersonal record to the console. /// </summary> /// <param name="sifEvent">SIF Event received.</param> /// <param name="zone">Zone the SIF Event was received from.</param> protected override void ProcessEvent(SifEvent <StudentPersonal> sifEvent, IZone zone) { if (log.IsDebugEnabled) { log.Debug(sifEvent.SifDataObject.ToXml()); } if (log.IsDebugEnabled) { log.Debug("Received a " + sifEvent.EventAction.ToString() + " event for StudentPersonal in Zone " + zone.ZoneId + "."); } }
/// <summary> /// Process an event for the SchoolInfo SIF Object. /// </summary> /// <param name="sifEvent">SchoolInfo event received.</param> /// <param name="zone">Zone used.</param> protected override void ProcessEvent(SifEvent <SchoolInfo> sifEvent, IZone zone) { if (!receivedSifRefIds.Contains(sifEvent.SifDataObject.RefId)) { receivedSifRefIds.Add(sifEvent.SifDataObject.RefId); } if (log.IsDebugEnabled) { log.Debug("Received a " + sifEvent.EventAction.ToString() + " event for SchoolInfo in Zone " + zone.ZoneId + " with a SifRefId of " + sifEvent.SifDataObject.RefId + ":\n" + sifEvent.SifDataObject.ToXml()); } }
/// <summary> /// This method is called when a SIF Event is received by the Subscriber. /// </summary> /// <param name="evnt">SIF Event received.</param> /// <param name="zone">Zone that SIF Event was received.</param> /// <param name="info">Information on the received message.</param> void ISubscriber.OnEvent(Event evnt, IZone zone, IMessageInfo info) { // Although not generally the case, it is possible that more than 1 SIF Data Object is received with the // SIF Event. while (evnt.Data.Available) { T sifDataObject = (T)evnt.Data.ReadDataObject(); EventAction eventAction = evnt.Action; SifEvent <T> sifEvent = new SifEvent <T>(sifDataObject, eventAction); if (PreProcessEvent(sifEvent, zone)) { ProcessEvent(sifEvent, zone); } } }
/// <summary> /// This method will check the cache for cached objects whose dependent objects have been received, and /// process them accordingly. /// </summary> /// <param name="zones">Zones that the cached objects will be processed against.</param> private void ProcessObjectsWithoutDependents(IZone[] zones) { ICollection <CachedObject> cachedObjects = cacheService.RetrieveByNoDependencies(SifObjectType.Name, ApplicationId, AgentConfiguration.SourceId); if (log.IsDebugEnabled) { log.Debug(this.GetType().Name + " found " + cachedObjects.Count + " objects with no dependencies for application " + ApplicationId + " and Agent " + AgentConfiguration.SourceId + "."); } IDictionary <string, IZone> zonesMap = new Dictionary <string, IZone>(); // Create an indexed list of Zones for easy access. foreach (IZone zone in zones) { zonesMap.Add(zone.ZoneId, zone); } foreach (CachedObject cachedObject in cachedObjects) { T sifDataObject = SifDataObjectMetadata <T> .CreateFromXml(cachedObject.ObjectXml); IZone zone; if (cachedObject.IsEvent) { EventAction eventAction = (EventAction)Enum.Parse(typeof(EventAction), cachedObject.EventType, true); SifEvent <T> sifEvent = new SifEvent <T>(sifDataObject, eventAction); if (zonesMap.TryGetValue(cachedObject.ZoneId, out zone)) { ProcessEvent(sifEvent, zone); } } else { if (zonesMap.TryGetValue(cachedObject.ZoneId, out zone)) { ProcessResponse(sifDataObject, zone); } } cacheService.DeleteCachedObject(cachedObject); if (log.IsDebugEnabled) { log.Debug("Processed " + cachedObject.SifObjectName + " (" + cachedObject.ObjectKeyValue + ") and removed from cache."); } } }
/// <summary> /// This method will publish a SIF Event to the Zone. /// </summary> /// <param name="sifEvent">SIF Event to publish.</param> /// <param name="zone">Zone to broadcast SIF Event to.</param> /// <exception cref="Systemic.Sif.Framework.Publisher.PublisherException">An error occurred publishing the SIF Event to the Zone.</exception> protected virtual void BroadcastEvent(SifEvent <T> sifEvent, IZone zone) { try { zone.ReportEvent(sifEvent.SifDataObject, sifEvent.EventAction); } catch (Exception e) { string message = "The " + sifEvent.EventAction.ToString() + " event for object ...\n" + sifEvent.SifDataObject.ToXml() + "\nwas not sent to Zone " + zone.ZoneId + " because it returned the following error ...\n" + e.Message; if (log.IsErrorEnabled) { log.Error(message, e); } ; throw new PublisherException(message, e); } }
public SifEvent <List <StudentPersonal> > GetNext() { SifEvent <List <StudentPersonal> > sifEvent = null; if (studentIndex < students.Count) { sifEvent = new SifEvent <List <StudentPersonal> >() { EventAction = EventAction.UPDATE_FULL, Id = Guid.NewGuid(), SifObjects = students.Skip(studentIndex).Take(7).ToList() }; studentIndex += 7; } return(sifEvent); }
/// <summary> /// This method will perform pre-processing of the received event. /// </summary> /// <param name="sifEvent">SIF Event received.</param> /// <param name="zone">Zone that the SIF Event was received from.</param> /// <returns>True if the event needs to be processed further; false otherwise.</returns> protected override bool PreProcessEvent(SifEvent <T> sifEvent, IZone zone) { if (sifEvent == null) { throw new ArgumentNullException("sifEvent"); } bool processFurther = true; if (CacheEnabled) { // The cache does not manage Undefined or Delete events. if (EventAction.Add.Equals(sifEvent.EventAction) || EventAction.Change.Equals(sifEvent.EventAction)) { processFurther = PreProcessSifDataObject(sifEvent.SifDataObject, sifEvent.EventAction, zone); } } return(processFurther); }
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> /// This method is used to process a SIF Event. /// </summary> /// <param name="sifEvent">SIF Event received.</param> /// <param name="zone">Zone that the SIF Event came from.</param> protected abstract void ProcessEvent(SifEvent <T> sifEvent, IZone zone);
/// <summary> /// Process an event for the Identity SIF Object. /// </summary> /// <param name="sifEvent">Identity event received.</param> /// <param name="zone">Zone used.</param> protected override void ProcessEvent(SifEvent<Identity> sifEvent, IZone zone) { if (log.IsDebugEnabled) log.Debug("Received a " + sifEvent.EventAction.ToString() + " event for Identity in Zone " + zone.ZoneId + ":\n" + sifEvent.SifDataObject.ToXml()); }
protected override void ProcessEvent(SifEvent<StudentSchoolEnrollment> sifEvent, IZone zone) { if (log.IsDebugEnabled) log.Debug(sifEvent.SifDataObject.ToXml()); if (log.IsDebugEnabled) log.Debug("Received a " + sifEvent.EventAction.ToString() + " event for StudentSchoolEnrollment in Zone " + zone.ZoneId + "."); }
public virtual IHttpActionResult BroadcastEvents(string zoneId = null, string contextId = null) { IEventService <TMultiple> 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.ProviderRegistrationService; 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 { // Retrieve the current Authorisation Token. registrationService.Register(); AuthorisationToken token = registrationService.AuthorisationToken; // Retrieve the EventsConnector endpoint URL. Environment environmentTemplate = EnvironmentUtils.LoadFromSettings(SettingsManager.ProviderSettings); string storedSessionToken = SessionsManager.ProviderSessionService.RetrieveSessionToken( environmentTemplate.ApplicationInfo.ApplicationKey, environmentTemplate.SolutionId, environmentTemplate.UserToken, environmentTemplate.InstanceId); Environment environment = authService.GetEnvironmentBySessionToken(storedSessionToken); string url = EnvironmentUtils.ParseServiceUrl(environment, ServiceType.UTILITY, InfrastructureServiceNames.eventsConnector) + "/" + TypeName + "s"; while (eventIterator.HasNext()) { SifEvent <TMultiple> sifEvent = eventIterator.GetNext(); NameValueCollection headerFields = new NameValueCollection() { { HttpUtils.RequestHeader.eventAction.ToDescription(), sifEvent.EventAction.ToDescription() }, { HttpUtils.RequestHeader.messageId.ToDescription(), sifEvent.Id.ToString() }, { HttpUtils.RequestHeader.messageType.ToDescription(), "EVENT" }, { HttpUtils.RequestHeader.serviceName.ToDescription(), $"{TypeName}s" } }; switch (sifEvent.EventAction) { case EventAction.UPDATE_FULL: headerFields.Add(HttpUtils.RequestHeader.Replacement.ToDescription(), "FULL"); break; case EventAction.UPDATE_PARTIAL: headerFields.Add(HttpUtils.RequestHeader.Replacement.ToDescription(), "PARTIAL"); break; } string body = SerialiseEvents(sifEvent.SifObjects); string xml = HttpUtils.PostRequest(url, token, body, headerFields: headerFields); } } result = Ok(); } } catch (Exception e) { result = InternalServerError(e); } return(result); }
/// <summary> /// This method is used to perform any custom preprocessing of a received SIF Event. If this method determines /// that the SIF Event should not be processed further, false should be returned. Returning false would mean /// that the SIF Event is discarded. /// </summary> /// <param name="sifEvent">SIF Event received.</param> /// <param name="zone">Zone that the SIF Event came from.</param> /// <returns>True is the SIF Event should be processed further; false otherwise.</returns> /// <exception cref="System.ArgumentNullException">A parameter is null.</exception> protected virtual bool PreProcessEvent(SifEvent <T> sifEvent, IZone zone) { return(true); }
/// <summary> /// This method will publish a SIF Event to each of the Zones. /// </summary> /// <param name="zones">Zones to broadcast SIF Events to.</param> private void BroadcastEvents(IZone[] zones) { foreach (IZone zone in zones) { try { ISifEventIterator <T> iterator = GetSifEvents(); if (iterator == null) { if (log.IsWarnEnabled) { log.Warn("Iterator of SIF Events for Publisher " + this.GetType().Name + " returned null."); } } else { int successCount = 0; int failureCount = 0; while (iterator.HasNextEvent()) { SifEvent <T> sifEvent = null; try { sifEvent = iterator.GetNextEvent(); if (sifEvent == null) { if (log.IsWarnEnabled) { log.Warn("iterator.hasNextEvent() has returned True, but iterator.getNextEvent() has returned null. The SIF Event has been ignored."); } failureCount++; } else { try { BroadcastEvent(sifEvent, zone); successCount++; } catch (PublisherException) { failureCount++; } } } catch (Exception e) { if (log.IsWarnEnabled) { log.Warn("SIF Event has been ignored because iterator.getNextEvent() failed.", e); } failureCount++; } } if (successCount == 0 && failureCount == 0) { if (log.IsInfoEnabled) { log.Info("No SIF Events of type " + SifObjectType.Name + " found for Zone " + zone.ZoneId + "."); } } else { if (log.IsInfoEnabled) { log.Info(this.GetType().Name + " successfully sent " + successCount + " SIF Events for " + this.SifObjectType.Name + " to zone " + zone.ZoneId + "."); } if (log.IsInfoEnabled && failureCount > 0) { log.Info(failureCount + " SIF Events failed to be sent for " + this.SifObjectType.Name + " to zone " + zone.ZoneId + "."); } } } iterator.AfterEvent(); } catch (IteratorException e) { if (log.IsErrorEnabled) { log.Error("Error with Iterator of SIF Events: " + e.Message, e); } ; } } }