//--//

        /// <summary>
        /// Creates and instance of the HostedService class.
        /// </summary>
        public DpwsHostedService(ProtocolVersion v)
        {
            m_threadLock        = new object();
            m_endpointRefs      = new WsWsaEndpointRefs();
            m_serviceOperations = new WsServiceOperations();
            m_eventSources      = new DpwsWseEventSources();
            m_prefixCounter     = 0;
            m_blockingCall      = true;
            m_version           = v;
        }
示例#2
0
        //--//

        /// <summary>
        /// Creates and instance of the HostedService class.
        /// </summary>
        public DpwsHostedService(ProtocolVersion v)
        {
            m_threadLock        = new object();
            m_endpointRefs      = new WsWsaEndpointRefs();
            m_serviceOperations = new WsServiceOperations();
            m_eventSources      = new DpwsWseEventSources();
            m_prefixCounter     = 0;
            m_blockingCall      = true;
            m_version           = v;
        }
        /// <summary>
        /// Iterates a collection of event sources an looks for an event sink by ID.
        /// </summary>
        /// <param name="eventSources">A collection of event sources.</param>
        /// <param name="eventSinkID">An event sink ID.</param>
        /// <returns>An event sink object if found otherwise null.</returns>
        private DpwsWseEventSink GetEventSink(DpwsWseEventSources eventSources, string eventSinkID)
        {
            DpwsWseEventSink eventSink;
            // Look for matching event in hosted services event sources
            int count = eventSources.Count;

            for (int i = 0; i < count; i++)
            {
                if ((eventSink = eventSources[i].EventSinks[eventSinkID]) != null)
                {
                    return(eventSink);
                }
            }

            return(null);
        }
        /// <summary>
        /// Iterates a collection of event sources an looks for an event sink by ID.
        /// </summary>
        /// <param name="eventSources">A collection of event sources.</param>
        /// <param name="eventSinkID">An event sink ID.</param>
        /// <returns>An event sink object if found otherwise null.</returns>
        private DpwsWseEventSink GetEventSink(DpwsWseEventSources eventSources, string eventSinkID)
        {
            DpwsWseEventSink eventSink;
            // Look for matching event in hosted services event sources
            int count = eventSources.Count;
            for (int i = 0; i < count; i++)
            {
                if ((eventSink = eventSources[i].EventSinks[eventSinkID]) != null)
                {
                    return eventSink;
                }
            }

            return null;
        }
示例#5
0
        public MFTestResults ServicesTest4_DpwsWseEventSources()
        {
            /// <summary>
            /// 1. Verifies the properties of a DpwsWseEventSources object
            /// 2. Adds elements to it
            /// 3. Re-verifies
            /// 4. Empties the object
            /// 5. Re-verifies
            /// </summary>
            ///
            bool testResult = true;
            try
            {
                DpwsWseEventSources testDWESs = new DpwsWseEventSources();

                if (testDWESs.Count != 0)
                    throw new Exception("Count did not set correctly on new");

                try
                {
                    if (testDWESs.Count != 0)
                        throw new Exception("Current did not set correctly on new");
                }
                catch (IndexOutOfRangeException) { }
                catch (InvalidOperationException) { }


                testDWESs.Add(new DpwsWseEventSource(
                    "testPrefix1", "urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b51", "testName1"));

                testDWESs.Add(new DpwsWseEventSource(
                    "testPrefix2", "urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b52", "testName2"));

                if (testDWESs.Count != 2)
                    throw new Exception("Count did not set correctly on new");

            }
            catch (Exception e)
            {
                Log.Comment("Exception: " + e.ToString());
                testResult = false;
            }
            return (testResult ? MFTestResults.Pass : MFTestResults.Fail);
        }
        /// <summary>
        /// Eventing UnSubscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Unsubscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an UnSubscribe response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public WsMessage Unsubscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            // Parse Unsubscribe Request
            ///////////////////////////////
            // there's no info in Unsubscribe that we actually need, just get the identifier from header
            String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

            bool eventSourceFound = false;

            if (eventSinkID != null)
            {
                // Parse urn:uuid from the To address
                string endpointAddress = FixToAddress(header.To);

                // Iterate the list of hosted services at the specified endpoint and unsubscribe from each event source
                // that matches the eventSinkID

                DpwsHostedService serv = (DpwsHostedService)Device.HostedServices[endpointAddress];

                if (serv != null)
                {
                    DpwsWseEventSources eventSources = serv.EventSources;

                    // Delete Subscription
                    // Look for matching event in hosted services event sources
                    DpwsWseEventSource eventSource;
                    DpwsWseEventSinks  eventSinks;
                    DpwsWseEventSink   eventSink;
                    int eventSourcesCount = eventSources.Count;
                    int eventSinksCount;
                    for (int i = 0; i < eventSourcesCount; i++)
                    {
                        eventSource     = eventSources[i];
                        eventSinks      = eventSource.EventSinks;
                        eventSinksCount = eventSinks.Count;

                        eventSink = eventSinks[eventSinkID];

                        if (eventSink != null)
                        {
                            eventSourceFound = true;
                            eventSource.EventSinks.Remove(eventSink);
                        }
                    }
                }

                if (eventSourceFound)
                {
                    // Generate Response
                    using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
                    {
                        WsWsaHeader responseHeader = new WsWsaHeader(
                            WsWellKnownUri.WseNamespaceUri + "/UnsubscribeResponse", // Action
                            header.MessageID,                                        // RelatesTo
                            header.ReplyTo.Address.AbsoluteUri,                      // To
                            null, null, null);

                        WsMessage msg = new WsMessage(responseHeader, null, WsPrefix.Wse, null,
                                                      new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

                        WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version);
                        smw.WriteSoapMessageStart(xmlWriter, msg);
                        smw.WriteSoapMessageEnd(xmlWriter);

                        // Return stream buffer
                        msg.Body = xmlWriter.ToArray();

                        return(msg);
                    }
                }
            }

            // Something went wrong
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess);
        }
        /// <summary>
        /// Global eventing Subscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Subscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the event source specified in the filter.</param>
        /// <returns>Byte array containing a Subscribe response.</returns>
        internal WsMessage Subscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            WsMessage msg = null;

            // Parse Subscribe Request
            /////////////////////////////
            DpwsWseEventSink eventSink = new DpwsWseEventSink();

            try
            {
                reader.ReadStartElement("Subscribe", WsWellKnownUri.WseNamespaceUri);

                if (reader.IsStartElement("EndTo", WsWellKnownUri.WseNamespaceUri))
                {
                    eventSink.EndTo = new WsWsaEndpointRef(reader, m_version.AddressingNamespace);
                }

                reader.ReadStartElement("Delivery", WsWellKnownUri.WseNamespaceUri);
                if (reader.IsStartElement("NotifyTo", WsWellKnownUri.WseNamespaceUri))
                {
                    eventSink.NotifyTo = new WsWsaEndpointRef(reader, m_version.AddressingNamespace);
                }
                else
                {
                    throw new WsFaultException(header, WsFaultType.WseDeliverModeRequestedUnavailable);
                }

                reader.ReadEndElement();

                if (reader.IsStartElement("Expires", WsWellKnownUri.WseNamespaceUri))
                {
                    long expires = new WsDuration(reader.ReadElementString()).DurationInSeconds;

                    if (expires > 0)
                    {
                        eventSink.Expires = expires;
                    }
                    else
                    {
                        throw new WsFaultException(header, WsFaultType.WseInvalidExpirationTime);
                    }
                }
                else
                {
                    // Never Expires
                    eventSink.Expires = -1;
                }

                if (reader.IsStartElement("Filter", WsWellKnownUri.WseNamespaceUri))
                {
                    if (reader.MoveToAttribute("Dialect") == false || reader.Value != m_version.WsdpNamespaceUri + "/Action")
                    {
                        throw new WsFaultException(header, WsFaultType.WseFilteringRequestedUnavailable);
                    }

                    reader.MoveToElement();

                    String filters = reader.ReadElementString();

                    if (filters != String.Empty)
                    {
                        eventSink.Filters = filters.Split(' ');
                    }
                }

                XmlReaderHelper.SkipAllSiblings(reader);

                reader.ReadEndElement(); // Subscribe
            }
            catch (XmlException e)
            {
                throw new WsFaultException(header, WsFaultType.WseInvalidMessage, e.ToString());
            }

            // Parse urn:uuid from the To address
            string endpointAddress = FixToAddress(header.To);

            // Build a temporary collection of device services that match the specified endpoint address.
            WsServiceEndpoints matchingServices = new WsServiceEndpoints();

            for (int i = 0; i < serviceEndpoints.Count; ++i)
            {
                if (serviceEndpoints[i].EndpointAddress == endpointAddress)
                {
                    matchingServices.Add(serviceEndpoints[i]);
                }
            }

            // For each service with a matching endpoint and event sources add an event sink to the
            // event source collection
            for (int i = 0; i < matchingServices.Count; ++i)
            {
                DpwsWseEventSources eventSources = ((DpwsHostedService)matchingServices[i]).EventSources;

                // Set the EventSinkID
                eventSink.ID = "urn:uuid:" + Guid.NewGuid().ToString();

                // If subscribing to all event sources
                if (eventSink.Filters == null)
                {
                    int count = eventSources.Count;
                    for (int ii = 0; i < count; i++)
                    {
                        DpwsWseEventSource eventSource = eventSources[ii];
                        eventSink.StartTime = DateTime.Now.Ticks;
                        eventSource.EventSinks.Add(eventSink);
                    }
                }
                else
                {
                    // If subscribing to a specific event based on an event filter.
                    DpwsWseEventSource eventSource;
                    string[]           filterList = eventSink.Filters;
                    int length = filterList.Length;
                    for (int ii = 0; i < length; i++)
                    {
                        if ((eventSource = eventSources[filterList[ii]]) != null)
                        {
                            eventSink.StartTime = DateTime.Now.Ticks;
                            eventSource.EventSinks.Add(eventSink);
                        }
                        else
                        {
                            throw new Exception("Event source " + filterList[ii] + " was not found.");
                        }
                    }
                }
            }

            // Generate Response
            //////////////////////////
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader responseHeader = new WsWsaHeader(
                    WsWellKnownUri.WseNamespaceUri + "/SubscribeResponse",  // Action
                    header.MessageID,                                       // RelatesTo
                    header.ReplyTo.Address.AbsoluteUri,                     // To
                    null, null, null);                                      // ReplyTo, From, Any

                msg = new WsMessage(responseHeader, null, WsPrefix.Wse, null,
                                    new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

                WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version);
                smw.WriteSoapMessageStart(xmlWriter, msg);

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscribeResponse", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscriptionManager", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                // Create a uri. Use the path (by default will be a uuid) for the sub manager endpoint
                Uri subMgrUri = new Uri(((DpwsHostedService)matchingServices[0]).EndpointAddress);
                xmlWriter.WriteString("http://" + Device.IPV4Address + ":" + Device.Port + "/" + subMgrUri.AbsolutePath);
                xmlWriter.WriteEndElement(); // End Address
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "ReferenceParameters", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Identifier", null);
                xmlWriter.WriteString(eventSink.ID);
                xmlWriter.WriteEndElement(); // End Identifier
                xmlWriter.WriteEndElement(); // End ReferenceParameters
                xmlWriter.WriteEndElement(); // End SubscriptionManager
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null);
                xmlWriter.WriteString(new WsDuration(eventSink.Expires).DurationString);
                xmlWriter.WriteEndElement(); // End Expires
                xmlWriter.WriteEndElement(); // End SubscribeResponse

                smw.WriteSoapMessageEnd(xmlWriter);

                // Return stream buffer
                msg.Body = xmlWriter.ToArray();
            }

            return(msg);
        }
        /// <summary>
        /// Eventing UnSubscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Unsubscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an UnSubscribe response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public byte[] Unsubscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            // Parse Unsubscribe Request
            ///////////////////////////////
            // there's no info in Unsubscribe that we actually need, just get the identifier from header
            String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

            bool eventSourceFound = false;

            if (eventSinkID != null)
            {
                // Parse urn:uuid from the To address
                string endpointAddress = FixToAddress(header.To);

                // Iterate the list of hosted services at the specified endpoint and unsubscribe from each event source
                // that matches the eventSinkID
                for (int i = 0; i < Device.HostedServices.Count; ++i)
                {
                    if (serviceEndpoints[i].EndpointAddress == endpointAddress)
                    {
                        // Delete Subscription
                        DpwsWseEventSources eventSources = ((DpwsHostedService)Device.HostedServices[i]).EventSources;

                        // Look for matching event in hosted services event sources
                        DpwsWseEventSource eventSource;
                        DpwsWseEventSinks  eventSinks;
                        DpwsWseEventSink   eventSink;
                        int eventSourcesCount = eventSources.Count;
                        int eventSinksCount;
                        for (int ii = 0; ii < eventSourcesCount; ii++)
                        {
                            eventSource     = eventSources[ii];
                            eventSinks      = eventSource.EventSinks;
                            eventSinksCount = eventSinks.Count;
                            for (int j = 0; j < eventSinksCount; j++)
                            {
                                eventSink = eventSinks[j];
                                if (eventSink.ID == eventSinkID)
                                {
                                    eventSourceFound = true;
                                    eventSource.EventSinks.Remove(eventSink);
                                }
                            }
                        }
                    }
                }

                if (eventSourceFound)
                {
                    // Generate Response

                    MemoryStream soapStream = new MemoryStream();
                    XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

                    WsWsaHeader responseHeader = new WsWsaHeader(
                        WsWellKnownUri.WseNamespaceUri + "/UnsubscribeResponse", // Action
                        header.MessageID,                                        // RelatesTo
                        header.ReplyTo.Address.AbsoluteUri,                      // To
                        null, null, null);

                    WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                                                              WsSoapMessageWriter.Prefixes.Wse,                                                              // Prefix
                                                              null,                                                                                          // Additional Prefix
                                                              responseHeader,                                                                                // Header
                                                              new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

                    WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

                    // Flush and close writer. Return stream buffer
                    xmlWriter.Flush();
                    xmlWriter.Close();
                    return(soapStream.ToArray());
                }
            }

            // Something went wrong
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess);
        }