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;
            }
        }
        /// <summary>
        /// Sends the message to the SIF Zone and returns the SIFAck that was received
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="isPullMessage"></param>
        /// <returns></returns>
        public virtual SIF_Ack send(SifMessagePayload msg,
                                     bool isPullMessage)
        {
            if (fZone.ProtocolHandler == null)
            {
                throw new AdkTransportException("Zone is not connected", fZone);
            }

            try
            {
                PolicyManager policyMan = PolicyManager.GetInstance(fZone);
                if (policyMan != null)
                {
                    policyMan.ApplyOutboundPolicy(msg, fZone);
                }
            }
            catch (AdkException adkex)
            {
                throw new AdkMessagingException("Unable to apply outbound message policy: " + adkex, fZone, adkex);
            }

            SIF_Ack ack = null;
            SifWriter w = null;
            byte stage = 1;
            bool queued = false;
            SifMessageType pload = 0;
            bool cancelled = false;
            ICollection<IMessagingListener> msgList = null;

            try
            {
                //  Assign values to message header
                SIF_Header hdr = msg.Header;
                hdr.SIF_Timestamp = DateTime.Now;
                hdr.SIF_MsgId = SifFormatter.GuidToSifRefID(Guid.NewGuid());
                hdr.SIF_SourceId = fSourceId;
                hdr.SIF_Security = secureChannel();

                //	Adk 1.5+: SIF_LogEntry requires that we *duplicate* the
                //	header within the object payload. This is really the only
                //	place we can do that and ensure that the SIF_Header and
                //	the SIF_LogEntry/SIF_LogEntryHeader are identical.

                if (msg is SIF_Event)
                {
                    // TODO: Should this be done at a higher level, such as zone.ReportEvent()?
                    SIF_Event ev = ((SIF_Event)msg);
                    SIF_ObjectData od =
                        (SIF_ObjectData)ev.GetChild(InfraDTD.SIF_EVENT_SIF_OBJECTDATA);
                    SIF_EventObject eo = od == null ? null : od.SIF_EventObject;
                    if (eo != null)
                    {
                        SIF_LogEntry logentry = (SIF_LogEntry)eo.GetChild(InfraDTD.SIF_LOGENTRY);
                        if (logentry != null)
                        {
                            SIF_LogEntryHeader sleh = new SIF_LogEntryHeader();
                            sleh.SIF_Header = (SIF_Header)hdr.Clone();
                            logentry.SIF_LogEntryHeader = sleh;
                        }
                    }
                }

                if (!isPullMessage || (Adk.Debug & AdkDebugFlags.Messaging_Pull) != 0)
                {
                    msg.LogSend(fZone.Log);
                }
            }
            catch (Exception thr)
            {
                throw new AdkMessagingException
                    ("MessageDispatcher could not assign outgoing message header: " + thr,
                      fZone, thr);
            }

            try
            {
                //  Convert message to a stream
                using (MessageStreamImpl memBuf = new MessageStreamImpl())
                {
                    w = new SifWriter(memBuf.GetInputStream());
                    w.Write(msg);
                    w.Flush();

                    stage = 2;

                    //  SIF_Event and SIF_Response are posted to the agent local queue
                    //  if enabled, otherwise sent immediately. All other message types
                    //  are sent immediately even when the queue is enabled.
                    //
                    if (fQueue != null &&
                         (msg is SIF_Event ||
                          msg is SIF_Response))
                    {
                        fQueue.PostMessage(msg);
                        queued = true;
                    }

                    //	Notify MessagingListeners...
                    pload = (SifMessageType)Adk.Dtd.GetElementType(msg.ElementDef.Name);
                    if (pload != SifMessageType.SIF_Ack)
                    {
                        msgList = GetMessagingListeners(fZone);
                        if (msgList.Count > 0)
                        {
                            StringBuilder stringBuffer = new StringBuilder(memBuf.Decode());
                            SifMessageInfo msgInfo = new SifMessageInfo(msg, fZone);
                            foreach (IMessagingListener listener in msgList)
                            {
                                try
                                {
                                    if (!listener.OnSendingMessage(pload, msgInfo, stringBuffer)
                                        )
                                    {
                                        cancelled = true;
                                    }
                                }
                                catch { } // Do Nothing
                            }
                        }
                    }

                    if (!cancelled)
                    {
                        //  Send the message
                        IMessageInputStream ackStream = fZone.fProtocolHandler.Send(memBuf);
                        {
                            try
                            {
                                //  Parse the results into a SIF_Ack
                                ack =
                                    (SIF_Ack)
                                    fParser.Parse
                                        ( ackStream.GetInputStream(), fZone,
                                          isPullMessage
                                              ? SifParserFlags.ExpectInnerEnvelope
                                              : SifParserFlags.None );
                            }
                            catch (Exception parseEx)
                            {
                                if (isPullMessage && (parseEx is AdkParsingException || parseEx is SifException || parseEx is System.Xml.XmlException))
                                {
                                    String ackStr = ackStream.ToString();
                                    if ((Adk.Debug & AdkDebugFlags.Message_Content ) != 0)
                                    {
                                        fZone.Log.Info( ackStr );
                                    }
                                    // The SIFParse was unable to parse this message. Try to create an appropriate
                                    // SIF_Ack, if SIFMessageInfo is able to parse enough of the message
                                    throw new PullMessageParseException(parseEx, ackStr, fZone);

                                }

                                throw new AdkMessagingException(parseEx.Message, fZone);
                            }
                        }

                        if (ack != null)
                        {
                            ack.message = msg;
                            if (!isPullMessage || (Adk.Debug & AdkDebugFlags.Messaging_Pull) != 0)
                            {
                                ack.LogRecv(fZone.Log);
                            }
                        }

                        //	Notify MessagingListeners...
                        if (msgList != null && msgList.Count > 0)
                        {
                            SifMessageInfo msgInfo = new SifMessageInfo(msg, fZone);

                            foreach (IMessagingListener listener in msgList)
                            {
                                try
                                {
                                    listener.OnMessageSent(pload, msgInfo, ack);
                                }
                                catch { } // Do Nothing
                            }
                        }
                    }
                    else
                    {
                        //	Prepare a success SIF_Ack to return
                        ack = msg.AckImmediate();
                    }
                }
            }
            catch (AdkMessagingException)
            {
                throw;
            }
            catch (AdkTransportException)
            {
                throw;
            }
            catch (Exception thr)
            {
                if (stage == 1)
                {
                    throw new AdkMessagingException
                        (
                        "MessageDispatcher could not convert outgoing infrastructure message to a string: " +
                        thr, fZone);
                }
                if (stage == 2)
                {
                    throw new AdkMessagingException
                        (
                        "MessageDispatcher could not convert SIF_Ack response to an object: " + thr,
                        fZone);
                }
            }
            finally
            {
                //  Removed queued message from queue
                if (queued)
                {
                    try
                    {
                        fQueue.RemoveMessage(msg.MsgId);
                    }
                    catch
                    {
                        // Do nothing
                    }
                }
            }

            return ack;
        }
Esempio n. 3
0
        private IMessageInputStream TrySend(IMessageOutputStream msg)
        {
            MessageStreamImpl returnStream;
            Stream            reqStream;

            HttpWebRequest conn = GetConnection(fZoneUrl);

            conn.ContentLength = msg.Length;

            try {
                reqStream = conn.GetRequestStream();
            }
            catch (WebException webEx) {
                if (webEx.Status == WebExceptionStatus.ConnectionClosed)
                {
                    // This could be a keep-alive connection that was closed unexpectedly
                    // rethrow so that retry handling can take affect
                    throw;
                }
                else
                {
                    throw new AdkTransportException
                              ("Could not establish a connection to the ZIS (" + fZoneUrl.AbsoluteUri +
                              "): " + webEx, fZone, webEx);
                }
            }
            catch (Exception thr) {
                throw new AdkTransportException
                          ("Could not establish a connection to the ZIS (" + fZoneUrl.AbsoluteUri + "): " +
                          thr, fZone, thr);
            }

            try {
                if ((Adk.Debug & AdkDebugFlags.Transport) != 0)
                {
                    fZone.Log.Debug("Sending message (" + msg.Length + " bytes)");
                }
                if ((Adk.Debug & AdkDebugFlags.Message_Content) != 0)
                {
                    fZone.Log.Debug(msg.Decode());
                }
                try {
                    msg.CopyTo(reqStream);
                    reqStream.Flush();
                    reqStream.Close();
                }
                catch (Exception thr) {
                    throw new AdkMessagingException
                              ("HttpProtocolHandler: Unexpected error sending message: " + thr, fZone);
                }

                try {
                    using (WebResponse response = conn.GetResponse()) {
                        if ((Adk.Debug & AdkDebugFlags.Transport) != 0)
                        {
                            fZone.Log.Debug
                                ("Expecting reply (" + response.ContentLength + " bytes)");
                        }

                        returnStream = new MessageStreamImpl(response.GetResponseStream());

                        response.Close();

                        if ((Adk.Debug & AdkDebugFlags.Transport) != 0)
                        {
                            fZone.Log.Debug("Received reply (" + returnStream.Length + " bytes)");
                        }
                        if ((Adk.Debug & AdkDebugFlags.Message_Content) != 0)
                        {
                            fZone.Log.Debug(returnStream.Decode());
                        }
                    }
                }
                catch (Exception thr) {
                    throw new AdkTransportException
                              ("An unexpected error occurred while receiving data from the ZIS: " + thr,
                              fZone);
                }
            }
            catch (AdkException) {
                // rethrow anything that's already wrapped in an AdkException
                throw;
            }
            catch (Exception thr) {
                throw new AdkMessagingException
                          ("HttpProtocolHandler: Error receiving response to sent message: " + thr, fZone);
            }

            return(returnStream);
        }
        private IMessageInputStream TrySend( IMessageOutputStream msg )
        {
            MessageStreamImpl returnStream;
            Stream reqStream;

            HttpWebRequest conn = GetConnection( fZoneUrl );
            conn.ContentLength = msg.Length;

            try {
                reqStream = conn.GetRequestStream();
            }
            catch ( WebException webEx ) {
                if ( webEx.Status == WebExceptionStatus.ConnectionClosed ) {
                    // This could be a keep-alive connection that was closed unexpectedly
                    // rethrow so that retry handling can take affect
                    throw;
                }
                else {
                    throw new AdkTransportException
                        ( "Could not establish a connection to the ZIS (" + fZoneUrl.AbsoluteUri +
                          "): " + webEx, fZone, webEx );
                }
            }
            catch ( Exception thr ) {
                throw new AdkTransportException
                    ( "Could not establish a connection to the ZIS (" + fZoneUrl.AbsoluteUri + "): " +
                      thr, fZone, thr );
            }

            try {
                if ( (Adk.Debug & AdkDebugFlags.Transport) != 0 ) {
                    fZone.Log.Debug( "Sending message (" + msg.Length + " bytes)" );
                }
                if ( (Adk.Debug & AdkDebugFlags.Message_Content) != 0 ) {
                    fZone.Log.Debug( msg.Decode() );
                }
                try {
                    msg.CopyTo( reqStream );
                    reqStream.Flush();
                    reqStream.Close();
                }
                catch ( Exception thr ) {
                    throw new AdkMessagingException
                        ( "HttpProtocolHandler: Unexpected error sending message: " + thr, fZone );
                }

                try {
                    using ( WebResponse response = conn.GetResponse() ) {
                        if ( (Adk.Debug & AdkDebugFlags.Transport) != 0 ) {
                            fZone.Log.Debug
                                ( "Expecting reply (" + response.ContentLength + " bytes)" );
                        }

                        returnStream = new MessageStreamImpl( response.GetResponseStream() );

                        response.Close();

                        if ( (Adk.Debug & AdkDebugFlags.Transport) != 0 ) {
                            fZone.Log.Debug( "Received reply (" + returnStream.Length + " bytes)" );
                        }
                        if ( (Adk.Debug & AdkDebugFlags.Message_Content) != 0 ) {
                            fZone.Log.Debug( returnStream.Decode() );
                        }
                    }
                }
                catch ( Exception thr ) {
                    throw new AdkTransportException
                        ( "An unexpected error occurred while receiving data from the ZIS: " + thr,
                          fZone );
                }
            }
            catch ( AdkException ) {
                // rethrow anything that's already wrapped in an AdkException
                throw;
            }
            catch ( Exception thr ) {
                throw new AdkMessagingException
                    ( "HttpProtocolHandler: Error receiving response to sent message: " + thr, fZone );
            }

            return returnStream;
        }