Esempio n. 1
0
        /// <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("");
            }
        }
Esempio n. 2
0
 /// <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));
 }
Esempio n. 3
0
        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);
        }