Exemplo n.º 1
0
        // Main function
        public static void Main(string[] args)
        {
            Assembly.Load(new AssemblyName("MARC.Everest.RMIM.CA.R020402"));

            // Instantiate the connector
            WcfServerConnector connector = new WcfServerConnector();

            // Assign the formatter
            connector.Formatter = new MARC.Everest.Formatters.XML.ITS1.Formatter();
            connector.Formatter.GraphAides.Add(
                new DatatypeFormatter()
                );

            // Subscribe to the message available event
            connector.MessageAvailable += new EventHandler <UnsolicitedDataEventArgs>(
                connector_MessageAvailable
                );

            // Open and start the connector
            try
            {
                WcfConnectionStringBuilder builder = new WcfConnectionStringBuilder();
                builder.ServiceName        = "ApplicationService";
                connector.ConnectionString = builder.GenerateConnectionString();
                connector.Open();
                connector.Start();

                Console.WriteLine("Server started, press any key to close...");
                Console.ReadKey();

                // Teardown
                connector.Stop();
                connector.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
Exemplo n.º 2
0
        public System.ServiceModel.Channels.Message ProcessInboundMessage(System.ServiceModel.Channels.Message m)
        {
            #if DEBUG
            Trace.TraceInformation("Received message on transport...");
            #endif

            if (ListenConnector == null && OperationContext.Current.Host is WcfServiceHost)
            {
                ListenConnector = (OperationContext.Current.Host as WcfServiceHost).ConnectorHost;
            }

            if (ListenConnector != null) // In process
            {
                // Is this channel one way or two way?
                if (!(OperationContext.Current.Channel is IOutputChannel)) // Input only
                {
                    return(null);
                }

                #if DEBUG
                Trace.TraceInformation("Message handoff to WcfServerConnector completed");
                #endif

                WcfSendResult processResult = ListenConnector.ProcessMessage(m);
                Message       retVal        = null;

                // There is an error, so the return value must be a fault!
                if (processResult == null || processResult.Code != ResultCode.Accepted && processResult.Code != ResultCode.AcceptedNonConformant)
                {
                    // Web based context?
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode        = System.Net.HttpStatusCode.InternalServerError;
                        WebOperationContext.Current.OutgoingResponse.StatusDescription = "Internal Server Error";
                    }

                    List <String> details = new List <string>();
                    if (processResult != null)
                    {
                        details = new List <String>();
                        foreach (var dtl in processResult.Details)
                        {
                            details.Add(dtl.Message); // Append details
                        }
                    }

                    if (processResult == null)
                    {
                        retVal = Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateReceiverFaultCode(processResult.Code.ToString(), "http://marc.mohawkcollege.ca/hi"), new FaultReason("The receiver has constructed an invalid response that cannot be sent to the sender"), details), m.Headers.Action);
                    }
                    else
                    {
                        retVal = Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateSenderFaultCode("EPIC", "http://marc.mohawkcollege.ca/hi"), new FaultReason("Catastrophic failure occurred in the WcfServer send pipeline. This usually occurs when the connector does not receive a message in the allocated amount of time"), details), m.Headers.Action);
                    }
                }
                else
                {
                    retVal = processResult.Message;

                    if (processResult.Headers != null)
                    {
                        retVal.Headers.Clear();
                        retVal.Headers.CopyHeadersFrom(processResult.Headers);
                    }
                }

                #if DEBUG
                Trace.TraceInformation("Message sent to client");
                #endif

                return(retVal);
            }
            else
            {
                // Get settings
                if (settings == null)
                {
                    settings = System.Web.Configuration.WebConfigurationManager.GetSection("marc.everest.connectors.wcf") as MARC.Everest.Connectors.WCF.Configuration.ConfigurationSection;
                }

                // Now format the message and pass it on ...
                MemoryStream         ms = new MemoryStream();
                System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(ms); // Write to message memory stream for classification matching
                m.WriteMessage(xw);
                xw.Flush();                                                // Flush the Xml Writer

                ms.Seek(0, SeekOrigin.Begin);                              // Seek to start
                XPathDocument  xpd = new XPathDocument(ms);                // load xpath document
                XPathNavigator xpn = xpd.CreateNavigator();

                IMessageReceiver receiver = null; // The receiver to use

                // Determine the receiver
                foreach (KeyValuePair <String, IMessageReceiver> kv in settings.Receiver)
                {
                    if (xpn.SelectSingleNode(kv.Key) != null)
                    {
                        receiver = kv.Value;
                        break;
                    }
                }

                // Was a receiver found?
                if (receiver == null)
                {
                    // Create a not implemented exception
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotImplemented;
                    }
                    return(Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateSenderFaultCode(
                                                                                         "NotImplemented", "http://marc.mohawkcollege.ca/hi"), new FaultReason("No receiver understands the request message.")),
                                                 m.Headers.Action));
                }

                // Create a streams for deserialization
                ms = new MemoryStream();
                XmlWriterSettings xws = new XmlWriterSettings();
                xws.Indent = true;
                xw         = XmlWriter.Create(ms, xws);

                // Deserialize body
                WcfReceiveResult rcv = new WcfReceiveResult();
                try
                {
                    // Because of classification, we need to process this in a wierd way,
                    // Basically the formatter will classify the message based on the root element name
                    // it receives. Because a SOAP message's root isn't what we really want to process,
                    // the first child node under the 'body' must be passed to the xml writer
                    xpn.SelectSingleNode("//*[local-name() = 'Body']/child::node()").WriteSubtree(xw);
                    xw.Flush();
                    ms.Seek(0, SeekOrigin.Begin);

                    var serResult = settings.Formatter.Parse(ms);
                    rcv.Structure = serResult.Structure;
                    rcv.Details   = serResult.Details;
                    if (rcv.Details.Count() == 0)
                    {
                        rcv.Code = ResultCode.Accepted;
                    }
                    else
                    {
                        rcv.Code = ResultCode.AcceptedNonConformant;
                    }
                }
                catch (Exception e)
                {
                    rcv.Code    = ResultCode.Error;
                    rcv.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }

                // Process on the receiver
                IGraphable obj = receiver.MessageReceived(rcv.Structure, rcv.Code, rcv.Details);

                // Graph this back
                XmlSerializerSurrogate surrogate = new XmlSerializerSurrogate((IXmlStructureFormatter)settings.Formatter);

                // Serialize the response
                Message result = Message.CreateMessage(m.Version, m.Headers.Action, obj, surrogate);

                // Validate
                surrogate.WriteObject(new MemoryStream(), obj);

                // Surrogate result code is acceptable?
                if (surrogate.ResultCode != ResultCode.Accepted && surrogate.ResultCode != ResultCode.AcceptedNonConformant)
                {
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode        = System.Net.HttpStatusCode.InternalServerError;
                        WebOperationContext.Current.OutgoingResponse.StatusDescription = "Internal Server Error";
                    }

                    List <string> details = new List <String>();
                    foreach (var itm in surrogate.Details)
                    {
                        details.Add(itm.Message); // Append details
                    }
                    return(Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateReceiverFaultCode(surrogate.ResultCode.ToString(), "http://marc.mohawkcollege.ca/hi"), new FaultReason("The receiver has constructed an invalid response that cannot be returned to the sender"), details), m.Headers.Action));
                }
                else
                {
                    return(result);
                }
            }
        }
Exemplo n.º 3
0
        public System.ServiceModel.Channels.Message ProcessInboundMessage(System.ServiceModel.Channels.Message m)
        {

            #if DEBUG
            Trace.TraceInformation("Received message on transport...");
            #endif

            if (ListenConnector == null && OperationContext.Current.Host is WcfServiceHost)
                ListenConnector = (OperationContext.Current.Host as WcfServiceHost).ConnectorHost;

            if (ListenConnector != null) // In process
            {
                // Is this channel one way or two way?
                if (!(OperationContext.Current.Channel is IOutputChannel)) // Input only
                    return null;

                #if DEBUG
                Trace.TraceInformation("Message handoff to WcfServerConnector completed");
                #endif

                WcfSendResult processResult = ListenConnector.ProcessMessage(m);
                Message retVal = null;

                // There is an error, so the return value must be a fault!
                if (processResult == null || processResult.Code != ResultCode.Accepted && processResult.Code != ResultCode.AcceptedNonConformant)
                {
                    // Web based context?
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.InternalServerError;
                        WebOperationContext.Current.OutgoingResponse.StatusDescription = "Internal Server Error";
                    }

                    List<String> details = new List<string>();
                    if (processResult != null)
                    {
                        details = new List<String>();
                        foreach(var dtl in processResult.Details)
                            details.Add(dtl.Message); // Append details
                    }

                    if (processResult == null)
                        retVal = Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateReceiverFaultCode(processResult.Code.ToString(), "http://marc.mohawkcollege.ca/hi"), new FaultReason("The receiver has constructed an invalid response that cannot be sent to the sender"), details), m.Headers.Action);
                    else
                        retVal = Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateSenderFaultCode("EPIC", "http://marc.mohawkcollege.ca/hi"), new FaultReason("Catastrophic failure occurred in the WcfServer send pipeline. This usually occurs when the connector does not receive a message in the allocated amount of time"), details), m.Headers.Action);
                }
                else
                {
                    retVal = processResult.Message;

                    if (processResult.Headers != null)
                    {
                        retVal.Headers.Clear();
                        retVal.Headers.CopyHeadersFrom(processResult.Headers);
                    }
                }
                                
                #if DEBUG
                Trace.TraceInformation("Message sent to client");
                #endif

                return retVal;
            }
            else
            {
                // Get settings
                if(settings == null) settings = System.Web.Configuration.WebConfigurationManager.GetSection("marc.everest.connectors.wcf") as MARC.Everest.Connectors.WCF.Configuration.ConfigurationSection;

                // Now format the message and pass it on ...
                MemoryStream ms = new MemoryStream();
                System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(ms); // Write to message memory stream for classification matching
                m.WriteMessage(xw);
                xw.Flush(); // Flush the Xml Writer

                ms.Seek(0, SeekOrigin.Begin);                  // Seek to start
                XPathDocument xpd = new XPathDocument(ms); // load xpath document
                XPathNavigator xpn = xpd.CreateNavigator();

                IMessageReceiver receiver = null; // The receiver to use

                // Determine the receiver
                foreach (KeyValuePair<String, IMessageReceiver> kv in settings.Receiver)
                    if (xpn.SelectSingleNode(kv.Key) != null)
                    {
                        receiver = kv.Value;
                        break;
                    }

                // Was a receiver found?
                if (receiver == null)
                { 
                    // Create a not implemented exception
                    if(WebOperationContext.Current != null)
                        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotImplemented;
                    return Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateSenderFaultCode(
                        "NotImplemented", "http://marc.mohawkcollege.ca/hi"), new FaultReason("No receiver understands the request message.")),
                        m.Headers.Action);
                }

                // Create a streams for deserialization
                ms = new MemoryStream();
                XmlWriterSettings xws = new XmlWriterSettings();
                xws.Indent = true;
                xw = XmlWriter.Create(ms, xws); 

                // Deserialize body
                WcfReceiveResult rcv = new WcfReceiveResult();
                try
                {
                    // Because of classification, we need to process this in a wierd way, 
                    // Basically the formatter will classify the message based on the root element name
                    // it receives. Because a SOAP message's root isn't what we really want to process, 
                    // the first child node under the 'body' must be passed to the xml writer
                    xpn.SelectSingleNode("//*[local-name() = 'Body']/child::node()").WriteSubtree(xw);
                    xw.Flush();
                    ms.Seek(0, SeekOrigin.Begin);

                    var serResult = settings.Formatter.Parse(ms);
                    rcv.Structure = serResult.Structure;
                    rcv.Details = serResult.Details;
                    if (rcv.Details.Count() == 0)
                        rcv.Code = ResultCode.Accepted;
                    else
                        rcv.Code = ResultCode.AcceptedNonConformant;
                }
                catch (Exception e)
                {
                    rcv.Code = ResultCode.Error;
                    rcv.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }

                // Process on the receiver
                IGraphable obj = receiver.MessageReceived(rcv.Structure, rcv.Code, rcv.Details);

                // Graph this back
                XmlSerializerSurrogate surrogate = new XmlSerializerSurrogate((IXmlStructureFormatter)settings.Formatter);

                // Serialize the response
                Message result = Message.CreateMessage(m.Version, m.Headers.Action, obj, surrogate);
                
                // Validate
                surrogate.WriteObject(new MemoryStream(), obj);

                // Surrogate result code is acceptable?
                if (surrogate.ResultCode != ResultCode.Accepted && surrogate.ResultCode != ResultCode.AcceptedNonConformant)
                {
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.InternalServerError;
                        WebOperationContext.Current.OutgoingResponse.StatusDescription = "Internal Server Error";
                    }

                    List<string> details = new List<String>();
                    foreach(var itm in surrogate.Details)
                        details.Add(itm.Message); // Append details
                    return Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateReceiverFaultCode(surrogate.ResultCode.ToString(), "http://marc.mohawkcollege.ca/hi"), new FaultReason("The receiver has constructed an invalid response that cannot be returned to the sender"), details), m.Headers.Action);
                }
                else
                    return result;

            }
        }
Exemplo n.º 4
0
        // Delegate handles the message available event
        static void connector_MessageAvailable(object sender,
                                               UnsolicitedDataEventArgs e)
        {
            // Cast connector
            WcfServerConnector connector = sender as WcfServerConnector;

            connector.InvalidResponse += new
                                         EventHandler <MessageEventArgs>(connector_InvalidResponse);
            // Receive the structure
            WcfReceiveResult rcvResult = connector.Receive() as WcfReceiveResult;

            if (rcvResult.Structure != null)
            {
                Console.WriteLine(rcvResult.Structure.GetType().Name);
            }

            // Prepare acknowledgement structure
            Acknowledgement acknowledgement = new Acknowledgement();

            // Assign the correlation
            acknowledgement.TargetMessage = new TargetMessage(
                (rcvResult.Structure as IIdentifiable).Id
                );

            // Determine the deserialization outcome
            if (rcvResult.Code != ResultCode.Accepted &&
                rcvResult.Code != ResultCode.AcceptedNonConformant)
            {
                // There were problems parsing the request message
                acknowledgement.TypeCode =
                    AcknowledgementType.AcceptAcknowledgementCommitError;
            }
            else
            {
                // Message is all good
                acknowledgement.TypeCode =
                    AcknowledgementType.AcceptAcknowledgementCommitAccept;
            }

            // Append all details
            foreach (IResultDetail dtl in rcvResult.Details)
            {
                AcknowledgementDetail detail = new AcknowledgementDetail(
                    AcknowledgementDetailType.Information,
                    AcknowledgementDetailCode.SyntaxError,
                    dtl.Message,
                    new SET <ST>((ST)dtl.Location)
                    );
                acknowledgement.AcknowledgementDetail.Add(detail);
            }

            // Create a response
            MCCI_IN000002CA response = new MCCI_IN000002CA(
                new II(Guid.NewGuid()),
                DateTime.Now,
                ResponseMode.Immediate,
                MCCI_IN000002CA.GetInteractionId(),
                MCCI_IN000002CA.GetProfileId(),
                ProcessingID.Production,
                AcknowledgementCondition.Never,
                new Receiver(
                    new Device2(
                        new II()
                        )
                    ),
                new Sender(
                    new
                    Device1(
                        new II("1.1.1.1.1")
                        )
                    ),
                acknowledgement
                );

            // Send the result
            connector.Send(response, rcvResult);
        }