示例#1
0
        /// <summary>
        /// Close the connection
        /// </summary>
        public void Close()
        {
#if WINDOWS_PHONE
            wcfClient.Abort();
#else
            wcfConfiguration = null;
            wcfClient.Close();
#endif
        }
示例#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);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Close the connection
        /// </summary>
        public void Close()
        {
#if WINDOWS_PHONE
            wcfClient.Abort();
#else
            wcfConfiguration = null;
            wcfClient.Close();
#endif
        }
示例#4
0
        /// <summary>
        /// Sets up the connector so it is able to open connections to the remote endpoint, and opens the channel.
        /// </summary>
        public void Open()
        {
            //TODO: Check if the connector is already open, or if the connector is in a faulted state.

            // Connection string
            if (ConnectionString == null)
                throw new ConnectorException(ConnectorException.MSG_NULL_CONNECTION_STRING, ConnectorException.ReasonType.NullConnectionString);
            else if (Formatter == null)
                throw new ConnectorException(ConnectorException.MSG_NULL_FORMATTER, ConnectorException.ReasonType.NullFormatter);

            Dictionary<string, List<string>> parameters = ConnectionStringParser.ParseConnectionString(ConnectionString);
            string endpointName = null, endpointAddress = null, bindingClass = null, bindingConfiguration = null;

            // Parameters
            foreach (KeyValuePair<string, List<string>> parm in parameters)
                switch (parm.Key)
                {
                    case "binding":
                        bindingClass = parm.Value[0];
                        break;
                    case "bindingConfiguration":
                        bindingConfiguration = parm.Value[0];
                        break;
                    case "endpointname":
                        endpointName = parm.Value[0];
                        break;
                    case "endpointaddress":
                        endpointAddress = parm.Value[0];
                        break;
                }

            if (bindingClass != null)
            { 
                Binding binding = null;
                switch (bindingClass)
                {
                    case "wsHttpBinding":
                        if (!String.IsNullOrEmpty(bindingConfiguration))
                            binding = new WSHttpBinding(bindingConfiguration);
                        else
                            binding = new WSHttpBinding(SecurityMode.None, false);
                        break;
                    case "basicHttpBinding":
                        if (!String.IsNullOrEmpty(bindingConfiguration))
                            binding = new BasicHttpBinding(bindingConfiguration);
                        else
                            binding = new BasicHttpBinding();
                        break;
                    default:
                        throw new InvalidOperationException("Could not understand binding");
                }
                if (endpointAddress == null)
                    throw new InvalidOperationException("When manually specifying binding you must specify an endpointAddress");
                else
                    wcfClient = new ConnectorServiceClient(binding, new EndpointAddress(endpointAddress));
            }
            // Create the client
            else if (endpointName == null)
                throw new InvalidOperationException("The connection string must include the 'endpointName' attribute!");
            else if (endpointAddress == null)
                wcfClient = new ConnectorServiceClient(endpointName);
            else
                wcfClient = new ConnectorServiceClient(endpointName, endpointAddress);


#if WINDOWS_PHONE
            ((ICommunicationObject)wcfClient).Open();
#else
            wcfClient.Open();
            // Using the app.config
            wcfConfiguration = ConfigurationManager.GetSection("marc.everest.connectors.wcf") as MARC.Everest.Connectors.WCF.Configuration.ConfigurationSection;
            if (Formatter == null)
                Formatter = (wcfConfiguration.Formatter as ICloneable).Clone() as IStructureFormatter;
#endif
        }
示例#5
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;

            }
        }
示例#6
0
        /// <summary>
        /// Sets up the connector so it is able to open connections to the remote endpoint, and opens the channel.
        /// </summary>
        public void Open()
        {
            //TODO: Check if the connector is already open, or if the connector is in a faulted state.

            // Connection string
            if (ConnectionString == null)
            {
                throw new ConnectorException(ConnectorException.MSG_NULL_CONNECTION_STRING, ConnectorException.ReasonType.NullConnectionString);
            }
            else if (Formatter == null)
            {
                throw new ConnectorException(ConnectorException.MSG_NULL_FORMATTER, ConnectorException.ReasonType.NullFormatter);
            }

            Dictionary <string, List <string> > parameters = ConnectionStringParser.ParseConnectionString(ConnectionString);
            string endpointName = null, endpointAddress = null, bindingClass = null, bindingConfiguration = null;

            // Parameters
            foreach (KeyValuePair <string, List <string> > parm in parameters)
            {
                switch (parm.Key)
                {
                case "binding":
                    bindingClass = parm.Value[0];
                    break;

                case "bindingConfiguration":
                    bindingConfiguration = parm.Value[0];
                    break;

                case "endpointname":
                    endpointName = parm.Value[0];
                    break;

                case "endpointaddress":
                    endpointAddress = parm.Value[0];
                    break;
                }
            }

            if (bindingClass != null)
            {
                Binding binding = null;
                switch (bindingClass)
                {
                case "wsHttpBinding":
                    if (!String.IsNullOrEmpty(bindingConfiguration))
                    {
                        binding = new WSHttpBinding(bindingConfiguration);
                    }
                    else
                    {
                        binding = new WSHttpBinding(SecurityMode.None, false);
                    }
                    break;

                case "basicHttpBinding":
                    if (!String.IsNullOrEmpty(bindingConfiguration))
                    {
                        binding = new BasicHttpBinding(bindingConfiguration);
                    }
                    else
                    {
                        binding = new BasicHttpBinding();
                    }
                    break;

                default:
                    throw new InvalidOperationException("Could not understand binding");
                }
                if (endpointAddress == null)
                {
                    throw new InvalidOperationException("When manually specifying binding you must specify an endpointAddress");
                }
                else
                {
                    wcfClient = new ConnectorServiceClient(binding, new EndpointAddress(endpointAddress));
                }
            }
            // Create the client
            else if (endpointName == null)
            {
                throw new InvalidOperationException("The connection string must include the 'endpointName' attribute!");
            }
            else if (endpointAddress == null)
            {
                wcfClient = new ConnectorServiceClient(endpointName);
            }
            else
            {
                wcfClient = new ConnectorServiceClient(endpointName, endpointAddress);
            }


#if WINDOWS_PHONE
            ((ICommunicationObject)wcfClient).Open();
#else
            wcfClient.Open();
            // Using the app.config
            wcfConfiguration = ConfigurationManager.GetSection("marc.everest.connectors.wcf") as MARC.Everest.Connectors.WCF.Configuration.ConfigurationSection;
            if (Formatter == null)
            {
                Formatter = (wcfConfiguration.Formatter as ICloneable).Clone() as IStructureFormatter;
            }
#endif
        }