//--// /// <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; }
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); }