public MFTestResults UtilitiesTest1_WsDuration() { /// <summary> /// 1. Gets and verifies each of the properties of a WsDuration object /// 2. Sets and re-verifies all properties /// </summary> /// bool testResult = true; try { Log.Comment("Calling Duragtion with Integer"); WsDuration testWD = new WsDuration(10); if (testWD.DurationInSeconds != 10) throw new Exception("Duration In Seconds is incorrect"); Log.Comment("Calling Duragtion with string"); testWD = new WsDuration("P1Y2M3DT4H4M6S"); if (testWD.DurationString != "P1Y2M3DT4H4M6S") throw new Exception("Duration In Seconds is incorrect"); Log.Comment("Calling Duragtion with timespan"); testWD = new WsDuration(new TimeSpan(1000)); if (testWD.Ticks != new TimeSpan(1000).Ticks) throw new Exception("Duration In Seconds is incorrect"); Log.Comment("DurationString"); if (testWD.DurationString != null) if (testWD.DurationString.GetType() != Type.GetType("System.String")) throw new Exception("DurationString wrong type"); } catch (Exception e) { testResult = false; Log.Comment("Incorrect exception caught: " + e.Message); } return (testResult ? MFTestResults.Pass : MFTestResults.Fail); }
/// <summary> /// Event renew stub. /// </summary> /// <param name="header">Header object.</param> /// <param name="reader">An XmlReader positioned at the begining of the Renew 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 Renew response.</returns> /// <remarks>This method is used by the stack framework. Do not use this method.</remarks> public WsMessage Renew(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints) { long newExpiration = 0; String eventSinkId = String.Empty; // Parse Renew request //////////////////////////// try { reader.ReadStartElement("Renew", WsWellKnownUri.WseNamespaceUri); if (reader.IsStartElement("Expires", WsWellKnownUri.WseNamespaceUri)) { newExpiration = new WsDuration(reader.ReadElementString()).DurationInSeconds; if (newExpiration <= 0) { throw new WsFaultException(header, WsFaultType.WseInvalidExpirationTime); } } else { // Never Expires newExpiration = -1; } eventSinkId = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri); if (eventSinkId == null) { throw new XmlException(); } } catch (XmlException e) { throw new WsFaultException(header, WsFaultType.WseInvalidMessage, e.ToString()); } // Parse urn:uuid from the To address string endpointAddress = FixToAddress(header.To); // Iterate the list of hosted services at the specified endpoint and renew each subscription // with and event source that matches the eventSinkID DpwsWseEventSink eventSink; bool eventSinkFound = false; DpwsHostedService endpoint = (DpwsHostedService)serviceEndpoints[endpointAddress]; if(endpoint != null) { if ((eventSink = GetEventSink(endpoint.EventSources, eventSinkId)) != null) { eventSinkFound = true; // Update event sink expires time eventSink.Expires = newExpiration; } } // Generate Response if (eventSinkFound) return GetStatusResponse(header, newExpiration); // It's just like the GetStatus Response throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess, "Subscription was not found. ID=" + eventSinkId); }
/// <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> /// Method parses a subscription renewal response and returns. /// </summary> /// <param name="renewResponse">A byte array containing a renew response message.</param> /// <param name="messageID"> /// A string containing the original message ID passed in the request. This id is used to validate /// that this is a response to the original request. /// </param> /// <returns>A WsDuration object containing the new expiration time for the event.</returns> /// <exception cref="XmlException"> /// If header or envelope parsing fails, If a required message tag is missing or an invalid or missing /// namespace is found. /// </exception> private WsDuration ProcessRenewResponse(byte[] renewResponse, string messageID) { using(XmlReader reader = ProcessResponse(renewResponse, messageID, "RenewResponse")) { reader.ReadStartElement("RenewResponse", m_version.EventingNamespace); WsDuration expires = null; if (reader.IsStartElement("Expires", m_version.EventingNamespace)) { expires = new WsDuration(reader.ReadElementString()); } return expires; } }
/// <summary> /// Use to renew an existing subscription. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscriptionID"> /// A subscription ID returned from a previous subscribe response. The device uses this ID /// to identify a specific event source subscription. /// </param> /// <param name="expires"> /// A WsDuration object indicating the new duration time for this event subscription, null = infinite. /// </param> /// <returns> /// A WsDuration object containing the new Expires time actually asigned by the device service to this /// event subscription, null = infinite. /// </returns> public WsDuration Renew(Uri endpointAddress, String subscriptionID, WsDuration expires) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Renew request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode(WsNamespacePrefix.Wse, "Identifier", null, subscriptionID)); WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/Renew", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To null, null, nodeList); // ReplyTo, From, Any WsMessage msg = new WsMessage(header, null, WsPrefix.Wse, null, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Renew", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null); xmlWriter.WriteString(expires.DurationString); xmlWriter.WriteEndElement(); // End Expires xmlWriter.WriteEndElement(); // End Renew smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Renew Message Build Took"); // Create an Http client and send Unsubscribe request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToArray(); WsMessage renewResponse = httpClient.SendRequest(msg, endpointAddress); // If a renew response is received validate the messageID and action and get the new expiration time. // If a parsing fault is received print exception and go on. if (renewResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Renew response is null."); return null; } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(renewResponse.Body as byte[]); try { return ProcessRenewResponse((byte[])renewResponse.Body, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); } } } return null; }
/// <summary> /// Method parses a subscription renewal response and returns. /// </summary> /// <param name="renewResponse">A byte array containing a renew response message.</param> /// <param name="messageID"> /// A string containing the original message ID passed in the request. This id is used to validate /// that this is a response to the original request. /// </param> /// <returns>A WsDuration object containing the new expiration time for the event.</returns> /// <exception cref="XmlException"> /// If header or envelope parsing fails, If a required message tag is missing or an invalid or missing /// namespace is found. /// </exception> private WsDuration ProcessRenewResponse(byte[] renewResponse, string messageID) { XmlReader reader = ProcessResponse(renewResponse, messageID, "RenewResponse"); try { reader.ReadStartElement("RenewResponse", WsWellKnownUri.WseNamespaceUri); WsDuration expires = null; if (reader.IsStartElement("Expires", WsWellKnownUri.WseNamespaceUri)) { expires = new WsDuration(reader.ReadElementString()); } return expires; } finally { reader.Close(); } }
/// <summary> /// Use to renew an existing subscription. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscriptionID"> /// A subscription ID returned from a previous subscribe response. The device uses this ID /// to identify a specific event source subscription. /// </param> /// <param name="expires"> /// A WsDuration object indicating the new duration time for this event subscription, null = infinite. /// </param> /// <returns> /// A WsDuration object containing the new Expires time actually asigned by the device service to this /// event subscription, null = infinite. /// </returns> public WsDuration Renew(Uri endpointAddress, String subscriptionID, WsDuration expires) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Renew request MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode("wse", "Identifier", null, subscriptionID)); WsWsaHeader header = new WsWsaHeader( WsWellKnownUri.WseNamespaceUri + "/Renew", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To null, null, nodeList); // ReplyTo, From, Any String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wse, null, header, null); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement("wse", "Renew", null); xmlWriter.WriteStartElement("wse", "Expires", null); xmlWriter.WriteString(expires.DurationString); xmlWriter.WriteEndElement(); // End Expires xmlWriter.WriteEndElement(); // End Renew WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Renew Message Build Took"); // Flush and close writer xmlWriter.Flush(); xmlWriter.Close(); // Create an Http client and send Unsubscribe request WsHttpClient httpClient = new WsHttpClient(); byte[] renewResponse = null; try { renewResponse = httpClient.SendRequest(soapStream.ToArray(), endpointAddress.ToString(), false, false); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Renew failed. " + e.Message); return null; } // If a renew response is received validate the messageID and action and get the new expiration time. // If a parsing fault is received print exception and go on. if (renewResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Renew response is null."); return null; } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(renewResponse))); try { return ProcessRenewResponse(renewResponse, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); } } return null; }