Пример #1
0
        /// <summary>  Create an error SIF_Ack for this message.</summary>
        /// <param name="category">The value of the SIF_Error/SIF_Category element
        /// </param>
        /// <param name="code">The value of the SIF_Error/SIF_Code element
        /// </param>
        /// <param name="desc">The value of the SIF_Error/SIF_Desc element
        /// </param>
        /// <param name="extDesc">The value of the SIF_Error/SIF_ExtendedDesc element
        /// </param>
        /// <returns> A new SIF_Ack instance with a SIF_Error element and SIF_Ack
        /// header values derived from this message's header values
        /// </returns>
        public virtual SIF_Ack AckError(SifErrorCategoryCode category,
                                        int code,
                                        string desc,
                                        string extDesc)
        {
            SIF_Ack ack = new SIF_Ack();

            ack.SIF_OriginalMsgId    = this.MsgId;
            ack.SIF_OriginalSourceId = this.SourceId;
            SIF_Error error = new SIF_Error
                              (
                (int)category,
                code,
                desc ?? "");

            if (extDesc != null)
            {
                error.SIF_ExtendedDesc = extDesc;
            }
            ack.SIF_Error = error;


            //  Ack using the same version of SIF as this message
            ack.SifVersion = SifVersion;

            return(ack);
        }
Пример #2
0
        /// <summary>  Create a SIF_Ack for this message.</summary>
        /// <param name="code">The SIF_Status/SIF_Code value
        /// </param>
        /// <returns> A new SIF_Ack instance where the SIF_Status/SIF_Code value is
        /// set to the specified value and SIF_Ack header values are derived
        /// from this message's header values
        /// </returns>
        public virtual SIF_Ack ackStatus(int code)
        {
            SIF_Ack    ack    = new SIF_Ack();
            SIF_Status status = new SIF_Status(code);

            ack.SIF_Status           = status;
            ack.SIF_OriginalMsgId    = MsgId;
            ack.SIF_OriginalSourceId = SourceId;


            SifVersion msgVersion = this.SifVersion;

            if (code == 8 /* Receiver is sleeping */)
            {
                if (msgVersion.Major == 1)
                {
                    // SIF 1.x used SIF_Data for text
                    SIF_Data d = new SIF_Data();
                    d.TextValue     = "Receiver is sleeping";
                    status.SIF_Data = d;
                }
                else
                {
                    status.SIF_Desc = "Receiver is sleeping";
                }
            }

            ack.message = this;

            //  Ack using the same version of SIF as this message
            ack.SifVersion = msgVersion;

            return(ack);
        }
Пример #3
0
 /// <summary>  Constructs an exception to wrap one or more SIF_Errors received from an
 /// inbound SIF_Ack message. This form of constructor is only called by
 /// the Adk.
 /// </summary>
 public SifException(SIF_Ack ack,
                     IZone zone)
     : base(null, zone)
 {
     fAck   = ack;
     fError = ack != null ? ack.SIF_Error : null;
 }
Пример #4
0
        private void AckPush(SIF_Ack ack,
                             AdkHttpResponse response)
        {
            try {
                //  Set SIF_Ack / SIF_Header fields
                SIF_Header hdr = ack.Header;
                hdr.SIF_Timestamp = DateTime.Now;

                hdr.SIF_MsgId    = SifFormatter.GuidToSifRefID(Guid.NewGuid());
                hdr.SIF_SourceId = this.Zone.Agent.Id;

                ack.LogSend(this.Zone.Log);

                response.ContentType = SifIOFormatter.CONTENTTYPE;
                // TODO: This code may need to change. The ADKHttpResponse should not automatically set the content length
                // and other implementations will not do so.
                SifWriter w = new SifWriter(response.GetResponseStream());
                w.Write(ack);
                w.Flush();
            }
            catch (Exception thr) {
                Console.Out.WriteLine
                    ("HttpProtocolHandler failed to send SIF_Ack for pushed message (zone=" +
                    this.Zone.ZoneId + "): " + thr);
                throw new AdkHttpException
                          (AdkHttpStatusCode.ServerError_500_Internal_Server_Error, thr.Message, thr);
            }
        }
Пример #5
0
 /// <summary>  Constructs an exception to wrap one or more SIF_Errors received from an
 /// inbound SIF_Ack message. This form of constructor is only called by
 /// the Adk.
 /// </summary>
 public SifException(string msg,
                     SIF_Ack ack,
                     IZone zone)
     : base(msg, zone)
 {
     fAck   = ack;
     fError = ack != null ? ack.SIF_Error : null;
 }
Пример #6
0
 /// <summary>
 /// Constructs a SifException for delivery to the ZIS
 /// </summary>
 /// <param name="category">A <c>SifErrorCategoryCode.</c> error category</param>
 /// <param name="code">A <c>SifErrorCodes</c> error code</param>
 /// <param name="desc">The error description</param>
 /// <param name="extDesc">An option extended error description</param>
 /// <param name="zone">The zone on which the error occurred</param>
 /// <param name="innerException">The internal error that was thrown by the agent</param>
 /// <remarks>
 ///  The Adk will include
 /// the error information provided by the exception when it sends a SIF_Ack
 /// in response to the message being processed. This form of constructor is
 /// typically called by the Adk, but may also be called by agent code if an
 /// exception occurs in a <c>IPublisher</c>, <c>ISubscriber</c>, or <c>IQueryResults</c>
 /// message handler implementation.
 /// </remarks>
 public SifException(SifErrorCategoryCode category,
                     int code,
                     string desc,
                     string extDesc,
                     IZone zone,
                     Exception innerException)
     : base(desc, zone, innerException)
 {
     fAck   = null;
     fError = new SIF_Error((int)category, code, desc == null ? "" : desc);
     if (extDesc != null)
     {
         fError.SIF_ExtendedDesc = extDesc;
     }
 }
Пример #7
0
        public void ParseSIF_LogEntry2()
        {
            // This test attempts to parse SIF_LogEntry,
            Console.WriteLine("Parsing from file...");
            SifParser p      = SifParser.NewInstance();
            SIF_Ack   logMsg = null;

            using (Stream inStream = GetResourceStream("SIF_LogEntry2.xml"))
            {
                logMsg = (SIF_Ack)p.Parse(inStream, null, SifParserFlags.ExpectInnerEnvelope, SifVersion.SIF20r1);
                inStream.Close();
            }

            Assert.IsNotNull(logMsg);
            //AdkObjectParseHelper.runParsingTest( logMsg );
        }
Пример #8
0
 /**
  * If the SIF_OriginalMsgID or SIF_OriginalSourceId are not set,
  * process according to Infrastructure resolution #157
  * @param errorAck
  */
 public static void SetRequiredAckValues(SIF_Ack errorAck)
 {
     //  Return a SIF_Ack with a blank SIF_OriginalSourceId and
     //  SIF_OriginalMsgId per SIFInfra resolution #157
     // Also See 4.1.2.1 SIF_Message processing
     if (errorAck.GetField(InfraDTD.SIF_ACK_SIF_ORIGINALMSGID) == null)
     {
         // Set SIF_OriginalMsgId to xsi:nill
         errorAck.SetField(InfraDTD.SIF_ACK_SIF_ORIGINALMSGID, new SifString(null));
     }
     if (errorAck.GetField(InfraDTD.SIF_ACK_SIF_ORIGINALSOURCEID) == null)
     {
         // Set SIF_OriginalSource to an empty string
         errorAck.SIF_OriginalSourceId = "";
     }
 }
        private static IMessageInputStream makeAck()
        {
            SIF_Ack retval = new SIF_Ack();
            retval.SIF_Status = new SIF_Status( 0 );
            MemoryStream ms = new MemoryStream();
            try
            {
                SifWriter sifWriter = new SifWriter( ms );
                sifWriter.Write( retval );
                sifWriter.Flush();
                //sifWriter.Close();


                MessageStreamImpl imp = new MessageStreamImpl( ms );
                return (IMessageInputStream) imp;
            }
            catch ( Exception )
            {
                return null;
            }
        }
Пример #10
0
        /// <summary>
        /// Create an error SIF_Ack for this message.
        /// </summary>
        /// <param name="sifEx">The SIFException that is the cause of the error</param>
        /// <returns></returns>
        public SIF_Ack AckError(SifException sifEx)
        {
            SIF_Ack ack = new SIF_Ack();

            ack.message = this;

            ack.SIF_OriginalMsgId    = this.MsgId;
            ack.SIF_OriginalSourceId = this.SourceId;

            SIF_Error error = new SIF_Error(
                sifEx.ErrorCategory,
                sifEx.ErrorCode,
                sifEx.ErrorDesc,
                sifEx.ErrorExtDesc);

            ack.SIF_Error = error;

            //  Ack using the same version of SIF as this message
            ack.SifVersion = this.SifVersion;

            return(ack);
        }
Пример #11
0
        /// <summary>
        ///  Attempts to parse attributes out of the source message enough to make a valid
        ///  SIF_Ack with a SIF_Error. This is useful in conditions where the source message cannot
        /// be parsed by the ADK
        /// </summary>
        /// <param name="sourceMessage"> The original message as a string</param>
        /// <param name="error">The error to place in the SIF_Ack/SIF_Error</param>
        /// <param name="zone">The zone associated with this message</param>
        /// <returns></returns>
        /// <exception cref="AdkMessagingException"></exception>
        public static SIF_Ack ackError(String sourceMessage, SifException error, ZoneImpl zone)
        {
            SifMessageInfo parsed = null;

            try
            {
                StringReader reader = new StringReader(sourceMessage);
                parsed = SifMessageInfo.Parse(reader, false, zone);
                reader.Close();
            }
            catch (Exception e)
            {
                zone.Log.Error(e, e);
            }

            SIF_Ack errorAck = new SIF_Ack(zone.HighestEffectiveZISVersion);

            if (parsed != null)
            {
                // Set SIFVersion, OriginalSourceId, and OriginalMsgId;
                if (parsed.SifVersion != null)
                {
                    errorAck.SifVersion = parsed.SifVersion;
                }
                errorAck.SIF_OriginalMsgId    = parsed.GetAttribute("SIF_MsgId");
                errorAck.SIF_OriginalSourceId = parsed.GetAttribute("SIF_SourceId");
            }
            SetRequiredAckValues(errorAck);

            SIF_Error newErr = new SIF_Error();

            newErr.SIF_Category     = (int)error.ErrorCategory;
            newErr.SIF_Code         = error.ErrorCode;
            newErr.SIF_Desc         = error.ErrorDesc;
            newErr.SIF_ExtendedDesc = error.ErrorExtDesc;
            errorAck.SIF_Error      = newErr;

            return(errorAck);
        }
Пример #12
0
        public void EmbeddedSIFMessage()
        {
            SifElement element = null;

            using (Stream aStream = GetResourceStream("GetNextMessageResponse.xml"))
            {
                TextReader aReader = new StreamReader(aStream);
                SifParser  parser  = SifParser.NewInstance();
                element = parser.Parse(aReader, null, SifParserFlags.ExpectInnerEnvelope, SifVersion.SIF11);
                aReader.Close();
                aStream.Close();
            }

            Assert.IsNotNull(element, "SIFElement was not parsed");
            SIF_Ack         ack            = (SIF_Ack)element;
            SifElement      messageElement = ack.SIF_Status.SIF_Data.GetChild("SIF_Message");
            SIF_Event       aEvent         = (SIF_Event)messageElement.GetChild("SIF_Event");
            SIF_EventObject eventObject    = aEvent.SIF_ObjectData.SIF_EventObject;

            Assert.AreEqual("SchoolCourseInfo", eventObject.ObjectName, "Wrong object name");
            Assert.AreEqual("Change", eventObject.Action, "Wrong Action");
            Assert.IsTrue(eventObject.GetChildList()[0] is SchoolCourseInfo, "Wrong object type");
        }
        //public string Send(string msg)
        //{
        //   lock (this)
        //   {
        //      fMessages.AddLast(msg);
        //   }
        //   return makeAck();
        //}

        public IMessageInputStream Send( IMessageOutputStream msg )
        {
            lock ( this )
            {
                try
                {
                    MemoryStream stream = new MemoryStream();
                    msg.CopyTo( stream );
                    stream.Seek( 0, SeekOrigin.Begin );
                    SifParser parser = SifParser.NewInstance();
                    SifMessagePayload smp = (SifMessagePayload) parser.Parse( stream, fZone );

                    fMessages.Add( smp );
                    parser = null;

                    SIF_Ack ack = smp.ackStatus( 0 );
                    SIF_Header hdr = ack.Header;
                    hdr.SIF_Timestamp = DateTime.Now;
                    hdr.SIF_MsgId = Adk.MakeGuid();
                    hdr.SIF_SourceId = fZone.Agent.Id;

                    StringWriter str = new StringWriter();
                    SifWriter writer = new SifWriter( str );
                    writer.Write( ack );
                    writer.Flush();
                    writer.Close();
                    writer = null;
                    return new MessageStreamImpl( str.ToString() );
                }
                catch( Exception ex )
                {
                    // Possible error parsing. Write the message to console out
                    Console.Out.WriteLine(msg.Decode());
                    throw new AdkMessagingException(ex.Message, fZone, ex);
                }
            }
        }
Пример #14
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);
        }