/// <summary> /// Returns the XML representation of this Query in the format required by SIF /// for the specified version /// </summary> /// <param name="version">The SIF Version to render the Query in. The ADK will attempt to render /// the query path using the proper element or attribute names for the version of SIF /// </param> /// <returns>a string containing the XML representation as a SIF_Query element. If an error /// occurs during the conversion, an empty string ("") is returned. /// </returns> public String ToXml(SifVersion version) { // Create a SIF_Query object SIF_Query sifQ = SIFPrimitives.CreateSIF_Query(this, version, true); try { using (StringWriter outStream = new StringWriter()) { SifWriter w = new SifWriter(outStream); w.Write(sifQ); w.Flush(); return(outStream.ToString()); } } catch (Exception e) { Adk.Log.Warn("Error creating XML equivalent of Query: " + e, e); return(""); } }
/// <summary>the SIF_Query representation of this Query in the format required by SIF /// for the specified version /// </summary> /// <param name="version">The SIF Version to render the Query in. The ADK will attempt to render /// the query path using the proper element or attribute names for the version of SIF</param> /// <returns>A SIF_Query element</returns> public SIF_Query ToSIF_Query(SifVersion version) { return(SIFPrimitives.CreateSIF_Query(this, version, true)); }
public void ProcessRequest(AdkHttpRequestContext context) { if ((Adk.Debug & AdkDebugFlags.Messaging) != 0) { Zone.Log.Debug ("Received push message from " + context.Request.RemoteAddress + " (" + context.Request.Url.Scheme + ")"); } SIF_Ack ack = null; SifMessagePayload parsed = null; //Check request length and type if (!SifIOFormatter.IsValidContentLength(context.Request.ContentLength)) { throw new AdkHttpException (AdkHttpStatusCode.ClientError_400_Bad_Request, "Content length Must be greater than zero"); } if (!SifIOFormatter.IsValidContentMediaType(context.Request.ContentType)) { throw new AdkHttpException(AdkHttpStatusCode.ClientError_415_Unsupported_Media_Type, "Content header does not support the specified media type: " + context.Request.ContentType); } // Read raw content Stream requestStream = context.Request.GetRequestStream(); StringBuilder requestXml = null; // If we need to convert the request stream to a string for either logging or messaging, do so if ((Adk.Debug & AdkDebugFlags.Message_Content) != 0) { requestXml = ConvertRequestToString(requestStream); Zone.Log.Debug ("Received " + context.Request.ContentLength + " bytes:\r\n" + requestXml.ToString()); } TextReader requestReader = new StreamReader(requestStream, SifIOFormatter.ENCODING); Exception parseEx = null; bool reparse = false; bool cancelled = false; int reparsed = 0; do { try { parseEx = null; // Parse content parsed = (SifMessagePayload)CreateParser().Parse(requestReader, Zone); reparse = false; parsed.LogRecv(Zone.Log); } catch (AdkParsingException adke) { parseEx = adke; } catch (Exception ex) { parseEx = ex; } // // Notify listeners... // // If we're asked to reparse the message, do so but do not notify // listeners the second time around. // if (reparsed == 0) { ICollection <IMessagingListener> msgList = MessageDispatcher.GetMessagingListeners(Zone); if (msgList.Count > 0) { // Convert the stream to a string builder if (requestXml == null) { requestXml = ConvertRequestToString(requestStream); } // Determine message type before parsing foreach (IMessagingListener listener in msgList) { try { SifMessageType pload = Adk.Dtd.GetElementType(parsed.ElementDef.Name); MessagingReturnCode code = listener.OnMessageReceived(pload, requestXml); switch (code) { case MessagingReturnCode.Discard: cancelled = true; break; case MessagingReturnCode.Reparse: requestReader = new StringReader(requestXml.ToString()); reparse = true; break; } } catch (AdkException adke) { parseEx = adke; } } } } if (cancelled) { return; } reparsed++; }while (reparse); if (parseEx != null) { // TODO: Handle the case where SIF_OriginalSourceId and SIF_OriginalMsgId // are not available because parsing failed. See SIFInfra // Resolution #157. if (parseEx is SifException && parsed != null) { // Specific SIF error already provided to us by SIFParser ack = parsed.AckError((SifException)parseEx); } else { String errorMessage = null; if (parseEx is AdkException) { errorMessage = parseEx.Message; } else { // Unchecked Throwable errorMessage = "Could not parse message"; } if (parsed == null) { SifException sifError = null; if (parseEx is SifException) { sifError = (SifException)parseEx; } else { sifError = new SifException( SifErrorCategoryCode.Xml, SifErrorCodes.XML_GENERIC_ERROR_1, "Could not parse message", parseEx.ToString(), this.Zone, parseEx); } if (requestXml == null) { requestXml = ConvertRequestToString(requestStream); } ack = SIFPrimitives.ackError( requestXml.ToString( ), sifError, this.Zone); } else { ack = parsed.AckError( SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_GENERIC_ERROR_1, errorMessage, parseEx.ToString()); } } if ((Adk.Debug & AdkDebugFlags.Messaging) != 0) { Zone.Log.Warn ("Failed to parse push message from zone \"" + Zone + "\": " + parseEx); } if (ack != null) { // Ack messages in the same version of SIF as the original message if (parsed != null) { ack.SifVersion = parsed.SifVersion; } AckPush(ack, context.Response); } else { // If we couldn't build a SIF_Ack, returning an HTTP 500 is // probably the best we can do to let the server know that // we didn't get the message. Note this should cause the ZIS // to resend the message, which could result in a deadlock // condition. The administrator would need to manually remove // the offending message from the agent's queue. if ((Adk.Debug & AdkDebugFlags.Messaging) != 0) { Zone.Log.Debug ("Could not generate SIF_Ack for failed push message (returning HTTP/1.1 500)"); } throw new AdkHttpException (AdkHttpStatusCode.ServerError_500_Internal_Server_Error, "Could not generate SIF_Ack for failed push message (returning HTTP/1.1 500)"); } return; } // Check SourceId to see if it matches this agent's SourceId String destId = parsed.DestinationId; if (destId != null && !destId.Equals(Zone.Agent.Id)) { Zone.Log.Warn ("Received push message for DestinationId \"" + destId + "\", but agent is registered as \"" + Zone.Agent.Id + "\""); ack = parsed.AckError ( SifErrorCategoryCode.Transport, SifErrorCodes.WIRE_GENERIC_ERROR_1, "Message not intended for this agent (SourceId of agent does not match DestinationId of message)", "Message intended for \"" + destId + "\" but this agent is registered as \"" + Zone.Agent.Id + "\""); AckPush(ack, context.Response); return; } // Convert content to SIF message object and dispatch it ack = ProcessPush(parsed); // Send SIF_Ack reply AckPush(ack, context.Response); }