private SIF_Ack ProcessPush(SifMessagePayload parsed) { try { // Dispatch. When the result is an Integer it is an ack code to // return; otherwise it is ack data to return and the code is assumed // to be 1 for an immediate acknowledgement. int ackStatus = this.Zone.Dispatcher.dispatch(parsed); // Ask the original message to generate a SIF_Ack for itself return(parsed.ackStatus(ackStatus)); } catch (SifException se) { return (parsed.AckError(se)); } catch (AdkException adke) { return (parsed.AckError (SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_GENERIC_ERROR_1, adke.Message)); } catch (Exception thr) { if ((Adk.Debug & AdkDebugFlags.Messaging) != 0) { this.Zone.Log.Debug("Uncaught exception dispatching push message: " + thr); } return (parsed.AckError (SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_GENERIC_ERROR_1, "An unexpected error has occurred", thr.ToString())); } }
private void assertNormalHandling(ErrorMessageHandler handler, SifMessagePayload payload, ZoneImpl zone) { MessageDispatcher testDispatcher = new MessageDispatcher(zone); int result = testDispatcher.dispatch(payload); Assert.IsTrue(handler.wasCalled(), "Handler was not called"); Assert.AreEqual(1, result, "Result code should always be 1 because this version does not support SMB"); }
public override void ApplyOutboundPolicy(SifMessagePayload msg, IZone zone ) { SifMessageType pload = Adk.Dtd.GetElementType(msg.ElementDef.Name); switch( pload ){ case SifMessageType.SIF_Request: SetRequestPolicy((SIF_Request)msg, zone ); break; } }
public static void WriteObject(SifVersion writeVersion, string fileName, SifMessagePayload smp) { using (FileStream outputStream = new FileStream(fileName, FileMode.Create)) { SifWriter writer = new SifWriter(outputStream); smp.SetChanged(true); smp.SifVersion = writeVersion; writer.Write(smp); writer.Flush(); writer.Close(); outputStream.Close(); } }
private void assertMessagesInVersion(SifVersion version, String[] expectedMessages) { Zone.Connect(ProvisioningFlags.Register); InMemoryProtocolHandler handler = (InMemoryProtocolHandler)Zone.ProtocolHandler; for (int a = 0; a < expectedMessages.Length; a++) { SifMessagePayload smp = (SifMessagePayload)handler.readMsg(); Assert.AreEqual(expectedMessages[a], smp.Tag, "Should be a " + expectedMessages[a]); Assert.AreEqual(version, smp.SifVersion, "Version should be " + version); } Assert.IsNull(handler.readMsg(), " Should have no more messages "); }
public bool Validate(SifElement se, SifVersion testedVerson) { // Before we can validate with the schema, we need to ensure that the // data object is wrapped in a SIF_Message elements, because the SIF // Schema makes that assumption SifMessagePayload smp = MakeSIFMessagePayload(se); String tmpFileName = se.ElementDef.Name + ".SchemaValidator." + testedVerson.ToString() + ".adk"; // 2) Write the message out to a file WriteObject(testedVerson, tmpFileName, smp); return(Validate(tmpFileName)); }
private void AssertRetryHandling(ErrorMessageHandler handler, SifMessagePayload payload, ZoneImpl zone) { try { assertNormalHandling(handler, payload, zone); } catch (SifException ex) { Assert.IsTrue(handler.wasCalled(), "Handler was not called"); Assert.AreEqual(SifErrorCategoryCode.Transport, ex.ErrorCategory, "SIF Error category should be 10: " + ex.Message); } Assert.IsTrue(handler.wasCalled(), "Handler was not called"); AssertThreadIsOK(); }
///<summary> Pop off the message that was written to the queue. Returns null if there /// were no messages written.</summary> public SifMessagePayload readMsg() { lock ( this ) { if ( fMessages.Count < 1 ) { return null; } else { SifMessagePayload smp = fMessages[0]; fMessages.RemoveAt( 0 ); return smp; } } }
public bool OnDispatchError(SifMessagePayload message, IZone zone, IMessageInfo info) { try { doBehavior(zone); } catch (SifException sifex) { throw sifex; } catch (AdkException adke) { throw new SifException(0, 0, "This shouldn't happen", zone, adke); } return(false); }
private void AssertExceptionHandling(ErrorMessageHandler handler, SifMessagePayload payload, ZoneImpl zone, Type expectedExceptionType) { Exception exc = null; try { assertNormalHandling(handler, payload, zone); } catch (Exception ex) { exc = ex; Assert.IsTrue(handler.wasCalled(), "Handler was not called"); AdkMessagingException adkme = ex as AdkMessagingException; Assert.IsNotNull(adkme, "Expected an ADKMessagingException, but was " + ex.GetType().Name + ":" + ex.ToString()); Exception source = adkme; Exception innerEx = null; while (source.InnerException != null) { innerEx = source.InnerException; source = innerEx; } Assert.IsNotNull(innerEx, "AdkMessaginException was thrown but inner exception was not set"); if (innerEx.GetType() != expectedExceptionType) { Assert.Fail("Exception thrown was not a " + expectedExceptionType.Name + ", but was " + innerEx.GetType().Name + ":" + innerEx.ToString()); } } Assert.IsNotNull(exc, "An exception was not thrown by the handler"); AssertThreadIsOK(); }
//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); } } }
/// <summary> /// Applies ADK policy to the outbound message /// </summary> /// <param name="payload">The message being sent from the ADK</param> /// <param name="zone">The zone that the message is being sent to</param> public abstract void ApplyOutboundPolicy(SifMessagePayload payload, IZone zone);
/// <summary> Dispatch a message. /// /// </summary> /// <param name="msg">The infrastructure message to dispatch /// </param> public virtual int dispatch(SifMessagePayload msg) { string errTyp = null; int status = 1; try { SifMessageType pload = (SifMessageType)Adk.Dtd.GetElementType(msg.ElementDef.Name); if (pload == SifMessageType.SIF_SystemControl) { IList<SifElement> ch = ((SIF_SystemControl)msg).SIF_SystemControlData.GetChildList(); if (ch != null && ch.Count > 0) { if (ch[0].ElementDef == InfraDTD.SIF_SLEEP) { fZone.ExecSleep(); } else if (ch[0].ElementDef == InfraDTD.SIF_WAKEUP) { fZone.ExecWakeup(); } else if (ch[0].ElementDef == InfraDTD.SIF_PING) { // Notify MessagingListeners... SifMessageInfo msginfo = new SifMessageInfo(msg, fZone); NotifyMessagingListeners_OnMessageProcessed (SifMessageType.SIF_SystemControl, msginfo); if (fZone.IsSleeping(AdkQueueLocation.QUEUE_LOCAL)) { return 8; } return 1; } else { fZone.Log.Warn("Received unknown SIF_SystemControlData: " + ch[0].Tag); throw new SifException (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_SystemControlData must contain SIF_Ping, SIF_Wakeup, or SIF_Sleep", fZone); } // Notify MessagingListeners... SifMessageInfo msginfo2 = new SifMessageInfo(msg, fZone); NotifyMessagingListeners_OnMessageProcessed (SifMessageType.SIF_SystemControl, msginfo2); } return status; } // If zone is asleep, return status code if (fZone.IsSleeping(AdkQueueLocation.QUEUE_LOCAL)) { return 8; } // Some agents don't want to receive messages - for example, the // SIFSend Adk Example agent. This is very rare but we offer a property // to allow for it if (fZone.Properties.DisableMessageDispatcher) { return status; } switch (pload) { case SifMessageType.SIF_Event: errTyp = "Subscriber.onEvent"; status = dispatchEvent((SIF_Event)msg); break; case SifMessageType.SIF_Request: errTyp = "Publisher.onRequest"; dispatchRequest((SIF_Request)msg); break; case SifMessageType.SIF_Response: errTyp = "QueryResults"; dispatchResponse((SIF_Response)msg); break; default: fZone.Log.Warn ("Agent does not know how to dispatch " + msg.ElementDef.Name + " messages"); throw new SifException (SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_MESSAGE_NOT_SUPPORTED_2, "Message not supported", msg.ElementDef.Name, fZone); } } catch (LifecycleException) { throw; } catch (SifException se) { // Check if AdkException.setRetry() was called; use transport // error category to force ZIS to resend message if (se.Retry) { se.ErrorCategory = SifErrorCategoryCode.Transport; se.ErrorCode = SifErrorCodes.WIRE_GENERIC_ERROR_1; } logAndRethrow("SIFException in " + errTyp + " message handler for " + msg.ElementDef.Name, se); } catch (AdkZoneNotConnectedException adkznce) { // Received a message while the zone was disconnected. Return a system transport // error so that the message is not removed from the queue SifException sifEx = new SifException( SifErrorCategoryCode.Transport, SifErrorCodes.WIRE_GENERIC_ERROR_1, adkznce.Message, fZone); logAndRethrow("Message received while zone is not connected", sifEx); } catch (AdkException adke) { // Check if ADKException.setRetry() was called; use transport // error category to force ZIS to resent message if (adke.Retry) { logAndThrowRetry(adke.Message, adke); } logAndThrowSIFException("ADKException in " + errTyp + " message handler for " + msg.ElementDef.Name, adke); } catch (Exception uncaught) { logAndThrowSIFException("Uncaught exception in " + errTyp + " message handler for " + msg.ElementDef.Name, uncaught); } return status; }
/** * Sends a SIF_Ack in response to a pulled message * @param sifGetMessageAck The original SIF_Ack from the SIF_GetMessage. This is sometimes null, when * parsing fails * @param pulledMEssage The message delivered inside of the above ack. NOTE that even if parsing fails, * the SIFParser tries to return what it can, and will return this message payload (in getParsed()), * instead of the above container message. * @param ackStatus The status to ack (NOTE: This is ignored if the err property is set) * @param err The error to set in the SIF_Ack */ private void sendPushAck(SIF_Ack sifGetMessageAck, SifMessagePayload pulledMEssage, int ackStatus, SifException err) { try { SIF_Ack ack2 = null; if( fAckAckOnPull && sifGetMessageAck != null){ ack2 = sifGetMessageAck.ackStatus( ackStatus ); } else { ack2 = pulledMEssage.ackStatus(ackStatus); } // If an error occurred processing the message, return // the details in the SIF_Ack if( err != null ) { fZone.Log.Debug( "Handling exception by creating a SIF_Error", err ); SIF_Error newErr = new SIF_Error(); newErr.SIF_Category = (int)err.ErrorCategory; newErr.SIF_Code = err.ErrorCode; newErr.SIF_Desc = err.ErrorDesc; newErr.SIF_ExtendedDesc = err.ErrorExtDesc; ack2.SIF_Error = newErr; // Get rid of the <SIF_Status> SIF_Status status = ack2.SIF_Status; if( status != null ) { ack2.RemoveChild( status ); } } // Send the ack send(ack2); } catch( Exception ackEx ) { fZone.Log.Debug( "Failed to send acknowledgement to pulled message: " + ackEx, ackEx ); } }
/// <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; }
public void testSchoolInfo010() { String schoolInfoResp = " <SIF_Message xmlns=\"http://www.sifinfo.org/infrastructure/1.x\" Version=\"1.5r1\">" + " <SIF_Response>" + " <SIF_Header>" + " <SIF_MsgId>B329CA6E5BC342339F135880CEE0578E</SIF_MsgId>" + " <SIF_Date>20070813</SIF_Date>" + " <SIF_Time Zone=\"UTC-06:00\">13:55:57</SIF_Time>" + " <SIF_Security>" + " <SIF_SecureChannel>" + " <SIF_AuthenticationLevel>0</SIF_AuthenticationLevel>" + " <SIF_EncryptionLevel>0</SIF_EncryptionLevel>" + " </SIF_SecureChannel>" + " </SIF_Security>" + " <SIF_SourceId>SASIxp</SIF_SourceId>" + " <SIF_DestinationId>Destiny</SIF_DestinationId>" + " </SIF_Header>" + " <SIF_RequestMsgId>88BE30BA0B8746809598854A1F58C8CC</SIF_RequestMsgId>" + " <SIF_PacketNumber>1</SIF_PacketNumber>" + " <SIF_MorePackets>No</SIF_MorePackets>" + " <SIF_ObjectData>" + " <SchoolInfo RefId=\"B3E73AC5E8C7392044015E25A454AC6F\">" + " <LocalId>997</LocalId>" + " <SchoolName>Junior High Demo</SchoolName>" + " <PrincipalInfo>" + " <ContactName>Mrs. Pleasant</ContactName>" + " </PrincipalInfo>\r\n" + /* " <PhoneNumber Format=\"NA\" Type=\"TE\">(949) 888-7655</PhoneNumber>" + */ " <PhoneNumber Format=\"NA\" Type=\"FE\">888-9877</PhoneNumber>\r\n" + " <Address Type=\"SS\">" + " <Street>" + " <Line1>Grand Avenue</Line1>" + " </Street>" + " <City>Plesantville</City>" + " <StatePr Code=\"CA\" />" + " <Country Code=\"US\" />" + " <PostalCode>12345</PostalCode>" + " </Address>" + " <IdentificationInfo Code=\"76\">997</IdentificationInfo>" + " </SchoolInfo>" + " </SIF_ObjectData>" + " </SIF_Response>" + " </SIF_Message>"; SifParser parser = SifParser.NewInstance(); SifMessagePayload smi = (SifMessagePayload)parser.Parse( schoolInfoResp, null); // Verify that it is parsing the correct version Assertion.AssertEquals("Version", SifVersion.SIF15r1, smi.SifVersion); Assertion.AssertEquals("Version attribute", "1.5r1", smi.VersionAttribute); SifDataObject sdo = (SifDataObject)((SIF_Response)smi) .SIF_ObjectData.GetChildList()[0]; // Now attempt an inbound mapping IDictionary fields = new ListDictionary(); StringMapAdaptor sma = new StringMapAdaptor(fields); Mappings m = fCfg.Mappings.GetMappings("Default").Select("asdf", "SASIxp", smi.SifVersion); m.MapInbound(sdo, sma, smi.SifVersion); Assertion.Assert("Elements Mapped", fields.Count > 0); Assertion.AssertEquals("Phone Number", "888-9877", fields["FAX"]); }
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); }
private bool RunSingleTest( SifVersion parseVersion, SifVersion writeVersion, string fileName, TextWriter output, SchemaValidator sv) { sv.Clear(); if (VERBOSE) { output.Write("Running test on " + fileName + "\r\n"); } // 1) Read the object into memory SifElement se = null; try { se = AdkObjectParseHelper.ParseFile(fileName, parseVersion); } catch (AdkException adke) { // Parsing failed. However, since this unit test is a complete // test of all available objects, just emit the problem and allow // the test to continue (with a notification of false) output .WriteLine("Error parsing file " + fileName + "\r\n - " + adke); output.WriteLine(); return(false); } catch (Exception re) { output.WriteLine("Error parsing file " + fileName + "\r\n - " + re); output.WriteLine(); return(false); } // if (VERBOSE) // { // SifWriter writer = new SifWriter(output); // writer.Write(se,parseVersion); // output.Flush(); // } // Before we can validate with the schema, we need to ensure that the // data object is wrapped in a SIF_Message elements, because the SIF // Schema makes that assumption SifMessagePayload smp = SchemaValidator.MakeSIFMessagePayload(se); String tmpFileName = fileName + "." + writeVersion.ToString() + ".adk"; // 2) Write the message out to a file SchemaValidator.WriteObject(writeVersion, tmpFileName, smp); // 3) Validate the file bool validated = sv.Validate(tmpFileName); // 4) If validation failed, write the object out for tracing purposes if (!validated) { if (VERBOSE) { SifWriter outWriter = new SifWriter(output); outWriter.Write(se, writeVersion); outWriter.Flush(); } output.WriteLine("Errors reading/writing " + fileName); sv.PrintProblems(output); return(false); } // 5) Read the object again into memory try { se = AdkObjectParseHelper.ParseFile(fileName, parseVersion); } catch (AdkException adke) { // Parsing failed. However, since this unit test is a complete // test of all available objects, just emit the problem and allow // the test to continue (with a notification of false) output.WriteLine("Error parsing file " + fileName + ": " + adke.Message); return(false); } catch (Exception re) { output.Write("Error parsing file " + fileName + ": " + re.Message + "\r\n"); return(false); } return(validated); }
/// <summary> Sends a message.</summary> /// <remarks> /// <para> /// If the message is a SIF_Event or SIF_Response message it is persisted to /// the Agent Local Queue (if enabled) to ensure reliable delivery. The /// message is then sent. Upon successful delivery to the ZIS, the message /// is removed from the queue. For all other message types the message is /// sent immediately without being posted to the queue.</para> /// <para> /// If an exception occurs and a message has been persisted to the queue, /// it is removed from the queue if possible (the queue is operational) and /// the send operation fails.</para> /// </remarks> public virtual SIF_Ack send(SifMessagePayload msg) { return send(msg, false); }