/// <summary> /// Constructor that accepts values for all mandatory fields /// </summary> ///<param name="source">The SIF node that logged this entry.</param> ///<param name="logLevel">The level of the log entry herein described.</param> ///<param name="sifLogEntryHeader">This is a copy of the SIF_Event/SIF_Header in the message that added this SIF_LogEntry to the zone. This copy facilitates querying log entries with regard to source, time, destination, etc.</param> ///<param name="sifDesc">A textual description of the error.</param> /// public SIF_LogEntry(LogSource source, LogLevel logLevel, SIF_LogEntryHeader sifLogEntryHeader, string sifDesc) : base(Adk.SifVersion, InfraDTD.SIF_LOGENTRY) { this.SetSource(source); this.SetLogLevel(logLevel); this.SIF_LogEntryHeader = sifLogEntryHeader; this.SIF_Desc = sifDesc; }
/// <summary> /// Constructor that accepts values for all mandatory fields /// </summary> ///<param name="source">The SIF node that logged this entry.</param> ///<param name="logLevel">The level of the log entry herein described.</param> ///<param name="sifLogEntryHeader">This is a copy of the SIF_Event/SIF_Header in the message that added this SIF_LogEntry to the zone. This copy facilitates querying log entries with regard to source, time, destination, etc.</param> ///<param name="sifDesc">A textual description of the error.</param> /// public SIF_LogEntry( LogSource source, LogLevel logLevel, SIF_LogEntryHeader sifLogEntryHeader, string sifDesc ) : base(Adk.SifVersion, InfraDTD.SIF_LOGENTRY) { this.SetSource( source ); this.SetLogLevel( logLevel ); this.SIF_LogEntryHeader = sifLogEntryHeader; this.SIF_Desc = sifDesc; }
/// <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; }