/// <summary> /// Initializes a new instance of <see cref="Configuration"/> /// </summary> public Configuration() { Interaction = new InteractionConfiguration(); Management = new ManagementConfiguration(); }
/// <summary> /// Fired whenever a message is available for processing /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void connector_MessageAvailable(object sender, UnsolicitedDataEventArgs e) { // Audit service IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService; #region Setup Audit AuditData audit = new AuditData( DateTime.Now, ActionType.Execute, OutcomeIndicator.Success, EventIdentifierType.ApplicationActivity, new AuditCode("GEN", null) ); audit.Actors.Add(new AuditActorData() { NetworkAccessPointId = Environment.MachineName, NetworkAccessPointType = NetworkAccessPointType.MachineName, UserIdentifier = String.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName) }); audit.Actors.Add(new AuditActorData() { UserIsRequestor = true, NetworkAccessPointId = e.SolicitorEndpoint.ToString(), NetworkAccessPointType = NetworkAccessPointType.IPAddress, UserIdentifier = e.SolicitorEndpoint.ToString() }); audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.Uri, LifecycleType = AuditableObjectLifecycle.Access, Role = AuditableObjectRole.DataRepository, ObjectId = e.ReceiveEndpoint.ToString(), Type = AuditableObjectType.SystemObject }); #endregion try { // Find a receiver capable of processing this var wcfConnector = (sender as IListenWaitConnector); IReceiveResult rcvResult = wcfConnector.Receive(); // get the persistence service from the context IMessagePersistenceService persistenceService = Context.GetService(typeof(IMessagePersistenceService)) as IMessagePersistenceService; // Were we able to process the message Assembly messageTypeAssembly = null; if (rcvResult.Structure != null) { messageTypeAssembly = rcvResult.Structure.GetType().Assembly; } // Find the configuration section that handles the specified revision var curRevision = m_configuration.Revisions.Find(o => o.Listeners.Exists(l => l.ConnectionString == wcfConnector.ConnectionString)); if (curRevision == null) { Trace.TraceError("This service does not seem to have support for the version of message being used"); throw new UninterpretableMessageException("This service doesn't support this standard", rcvResult); } // Do we have a handler for this message interaction? Cast as an interaction // and attempt to find the handler configuration IInteraction interactionStructure = rcvResult.Structure as IInteraction; MessageHandlerConfiguration receiverConfig = null; if (interactionStructure != null && interactionStructure.InteractionId != null && !String.IsNullOrEmpty(interactionStructure.InteractionId.Extension)) { receiverConfig = curRevision.MessageHandlers.Find(o => o.Interactions.Exists(i => i.Id == interactionStructure.InteractionId.Extension)); } else { Trace.TraceWarning("Interaction is missing InteractionId attribute! Assuming default"); // Set interaction id var intId = interactionStructure.GetType().GetMethod("GetInteractionId", BindingFlags.Static | BindingFlags.Public); if (intId == null) { throw new InvalidOperationException("Cannot find the GetInteractionId method, cannot determine interaction"); } interactionStructure.InteractionId = intId.Invoke(null, null) as II; } // Message identifier missing? if (interactionStructure.Id == null) { interactionStructure.Id = Guid.NewGuid(); Trace.TraceWarning("Interaction is missing id. Generated token {0}...", interactionStructure.Id.Root); } IEverestMessageReceiver currentHandler = null, defaultHandler = null; var defaultHandlerConfig = curRevision.MessageHandlers.Find(o => o.Interactions.Exists(i => i.Id == "*")); receiverConfig = receiverConfig ?? defaultHandlerConfig; // find a handler // Receiver configuration if (receiverConfig == null) { throw new InvalidOperationException("Cannot find appropriate handler this message"); } else { var messageState = Core.Services.MessageState.New; IInteraction response = null; InteractionConfiguration interactionConfig = receiverConfig.Interactions.Find(o => o.Id == interactionStructure.InteractionId.Extension); if (interactionConfig != null && interactionConfig.Disclosure) { persistenceService = null; } // check with persistence if (persistenceService != null) { messageState = persistenceService.GetMessageState(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension)); } switch (messageState) { case Core.Services.MessageState.New: // Persist the message if (persistenceService != null) { MemoryStream ms = new MemoryStream(); try { WriteMessageToStream(sender as IFormattedConnector, interactionStructure, ms); persistenceService.PersistMessage(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension), ms); } finally { ms.Dispose(); } } currentHandler = receiverConfig.Handler; defaultHandler = defaultHandlerConfig.Handler; response = currentHandler.HandleMessageReceived(sender, e, rcvResult) as IInteraction; if (persistenceService != null) { MemoryStream ms = new MemoryStream(); try { WriteMessageToStream(sender as IFormattedConnector, response, ms); persistenceService.PersistResultMessage(String.Format(curRevision.MessageIdentifierFormat, response.Id.Root, response.Id.Extension), String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension), ms); } finally { ms.Dispose(); } } break; case Core.Services.MessageState.Complete: var rms = persistenceService.GetMessageResponseMessage(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension)); var parseResult = (sender as IFormattedConnector).Formatter.Parse(rms); response = parseResult.Structure as IInteraction; break; case Core.Services.MessageState.Active: throw new ApplicationException("Message is already being processed"); } // Send back IListenWaitRespondConnector ilwConnector = sender as IListenWaitRespondConnector; if (ilwConnector == null) // no need to send something back { auditService.SendAudit(audit); return; } else { // Invalid message delegate var invalidMessageDelegate = new EventHandler <MessageEventArgs>(delegate(object sndr, MessageEventArgs mea) { audit.Outcome = OutcomeIndicator.MinorFail; InvalidMessageResult res = new InvalidMessageResult() { Code = mea.Code, Details = mea.Details, Structure = rcvResult.Structure }; if (defaultHandler != null) { mea.Alternate = response; } Trace.TraceWarning("Returning a default message because Everest was unable to serialize the response correctly. Error was {0}", mea.Code); Trace.Indent(); foreach (IResultDetail dtl in mea.Details) { Trace.TraceWarning("{0} : {1} : {2}", dtl.Type, dtl.Message, dtl.Location); } Trace.Unindent(); mea.Alternate = response; }); ilwConnector.InvalidResponse += invalidMessageDelegate; try { // Create headers var wcfResult = rcvResult as WcfReceiveResult; if (wcfResult != null && wcfResult.Headers != null) { var rcvrInfo = receiverConfig.Interactions.Find(o => o.Id == interactionStructure.InteractionId.Extension); if (rcvrInfo != null) { wcfResult.ResponseHeaders = CreateResponseHeaders(rcvrInfo.ResponseHeaders, wcfResult.Headers.MessageVersion); } if (wcfResult.ResponseHeaders != null) { wcfResult.ResponseHeaders.RelatesTo = wcfResult.Headers.MessageId; } } ISendResult sndResult = ilwConnector.Send(response, rcvResult); if (sndResult.Code != ResultCode.Accepted && sndResult.Code != ResultCode.AcceptedNonConformant) { Trace.TraceError("Cannot send response back to the solicitor : {0}", sndResult.Code); Trace.Indent(); foreach (IResultDetail dtl in sndResult.Details ?? new IResultDetail[0]) { Trace.TraceError("{0}: {1} : {2}", dtl.Type, dtl.Message, dtl.Location); } Trace.Unindent(); } } finally { if (auditService != null) { auditService.SendAudit(audit); } // Remove the invalid message delegate ilwConnector.InvalidResponse -= invalidMessageDelegate; } } } } catch (System.Exception ex) { #region Audit Failure audit.Outcome = OutcomeIndicator.EpicFail; if (auditService != null) { auditService.SendAudit(audit); } #endregion Trace.TraceError(ex.ToString()); throw; } }