private void storeRequest( RequestCache rc, SIF_Request request, Query q, String msgID, String objectName) { //request.getSIF_Query().getSIF_QueryObject().setObjectName(objectName); request.SIF_Query.SIF_QueryObject.ObjectName = objectName; request.Header.SIF_MsgId = msgID; rc.StoreRequestInfo(request, q, null); }
public void testPersistenceWithBadState() { //create new cache for agent RequestCache cache = RequestCache.GetInstance(fAgent); //create new queryobject SIF_QueryObject obj = new SIF_QueryObject(""); //create query, telling it what type of query it is(passing it queryobj) SIF_Query query = new SIF_Query(obj); //create new sif request SIF_Request request = new SIF_Request(); //set query property request.SIF_Query = query; Query q = new Query(StudentDTD.STUDENTPERSONAL); String testStateItem = Adk.MakeGuid(); String requestMsgId = Adk.MakeGuid(); String testObjectType = Adk.MakeGuid(); TestState ts = new TestState(); ts.State = testStateItem; ts.setCreateErrorOnRead(true); q.UserData = ts; storeRequest(cache, request, q, requestMsgId, testObjectType); cache.Close(); // Create a new instance. This one should retrieve its settings from the persistence mechanism cache = RequestCache.GetInstance(fAgent); IRequestInfo ri = cache.GetRequestInfo(requestMsgId, null); //if state is null, should still return ri object Assertion.AssertNotNull("RequestInfo was null", ri); Assertion.AssertEquals("MessageId", requestMsgId, ri.MessageId); Assertion.AssertEquals("ObjectType", testObjectType, ri.ObjectType); ts = (TestState) ri.UserData; // In order for this to be a valid test, the TestState class should have thrown // an exception during deserialization and should be null here. Assertion.AssertNull("UserData should be null", ts); }
public void testWithLegacyFile() { //assertStoredRequests(fRC, true); // Copy the legacy requests.adk file to the agent work directory //FileInfo legacyFile = new FileInfo("requests.adk"); //Assertion.Assert("Saved legacy file does [not?] exist", legacyFile.Exists); //FileInfo copiedFile = new FileInfo(fAgent.HomeDir + Path.DirectorySeparatorChar + "work" + Path.DirectorySeparatorChar + "requests.adk"); //if (copiedFile.Exists) //{ // copiedFile.Delete(); //} //// Copy the file //legacyFile.CopyTo(copiedFile.FullName, true); // Now open up an instance of the request cache and verify that the contents are there fRC = RequestCache.GetInstance(fAgent); SIF_QueryObject obj = new SIF_QueryObject(""); SIF_Query query = new SIF_Query(obj); SIF_Request request = new SIF_Request(); request.SIF_Query = query; Query q; TestState ts; fMsgIds = new String[10]; fStateObjects = new String[10]; // Add 10 entries to the cache for (int i = 0; i < 10; i++) { ts = new TestState(); ts.State = Adk.MakeGuid(); fStateObjects[i] = (String) ts.State; q = new Query(StudentDTD.STUDENTPERSONAL); q.UserData = ts; fMsgIds[i] = Adk.MakeGuid(); storeRequest(fRC, request, q, fMsgIds[i], "Object_" + i.ToString()); } Assertion.AssertEquals("Active request count", 10, fRC.ActiveRequestCount); // Lookup each setting, for (int i = 0; i < 10; i++) { IRequestInfo reqInfo = fRC.LookupRequestInfo(fMsgIds[i], null); Assertion.AssertEquals("Initial lookup", "Object_" + i.ToString(), reqInfo.ObjectType); } // Lookup each setting, for (int i = 0; i < 10; i++) { IRequestInfo reqInfo = fRC.GetRequestInfo(fMsgIds[i], null); Assertion.AssertEquals("Initial lookup", "Object_" + i.ToString(), reqInfo.ObjectType); } // all messages should now be removed from the queue Assertion.AssertEquals("Cache should be empty", 0, fRC.ActiveRequestCount); // Now run one of our other tests testPersistence(); }
/** * Stores the items in the cache that will later be asserted * @param cache */ private void storeAssertedRequests(RequestCache cache) { SIF_QueryObject obj = new SIF_QueryObject(""); SIF_Query query = new SIF_Query(obj); SIF_Request request = new SIF_Request(); request.SIF_Query = query; Query q; TestState ts; fMsgIds = new String[10]; fStateObjects = new String[10]; // Add 10 entries to the cache, interspersed with other entries that are removed for (int i = 0; i < 10; i++) { ts = new TestState(); ts.State = Adk.MakeGuid(); fStateObjects[i] = ts.State; q = new Query(StudentDTD.STUDENTPERSONAL); q.UserData = ts; String phantom1 = Adk.MakeGuid(); String phantom2 = Adk.MakeGuid(); storeRequest(cache, request, q, phantom1, "foo"); fMsgIds[i] = Adk.MakeGuid(); storeRequest(cache, request, q, fMsgIds[i], "Object_" + i.ToString()); storeRequest(cache, request, q, phantom2, "bar"); cache.GetRequestInfo(phantom1, null); cache.GetRequestInfo(phantom2, null); } }
// TODO: Implement /* [Test] public void testReportPublishSIFExceptionAfterReportInfo() { ElementDef objType = SifDtd.SIF_REPORTOBJECT; ErrorMessageHandler handler = new ErrorMessageHandler( ErrorMessageHandler.BVR_SET_REPORT_INFO_THROW_EXCEPTION ); fZone.setReportPublisher( handler, ADKFlags.PROV_NONE); TestProtocolHandler testProto = new TestProtocolHandler(); testProto.open(fZone); MessageDispatcher testDispatcher = new MessageDispatcher( fZone ); fZone.setDispatcher(testDispatcher); fZone.setProto(testProto); testDispatcher.dispatch( createSIF_Request( objType, ADK.makeGUID(), fZone ) ); String msg = testProto.readMsg(); assertNull(testProto.readMsg()); fZone.log.info(msg); SIFParser parser = SIFParser.newInstance(); SIFElement element = parser.parse(new StringReader(msg), fZone); assertTrue(element instanceof SIF_Response); SIF_Response response = (SIF_Response) element; assertTrue(response.getSIF_Error() != null); assertTrue(response.getSIF_Error().getSIF_Desc().startsWith("Blah")); } public void testReportPublishSIFExceptionAfterReportInfo() throws ADKException, IOException { ElementDef objType = SifDtd.SIF_REPORTOBJECT; ErrorMessageHandler handler = new ErrorMessageHandler( ErrorMessageHandler.BVR_SET_REPORT_INFO_THROW_EXCEPTION ); fZone.setReportPublisher( handler, ADKFlags.PROV_NONE); TestProtocolHandler testProto = new TestProtocolHandler(); testProto.open(fZone); MessageDispatcher testDispatcher = new MessageDispatcher( fZone ); fZone.setDispatcher(testDispatcher); fZone.setProto(testProto); testDispatcher.dispatch( createSIF_Request( objType, ADK.makeGUID(), fZone ) ); String msg = testProto.readMsg(); assertNull(testProto.readMsg()); fZone.log.info(msg); SIFParser parser = SIFParser.newInstance(); SIFElement element = parser.parse(new StringReader(msg), fZone); assertTrue(element instanceof SIF_Response); SIF_Response response = (SIF_Response) element; assertTrue(response.getSIF_Error() != null); assertTrue(response.getSIF_Error().getSIF_Desc().startsWith("Blah")); } */ private SIF_Request createSIF_Request(IElementDef objType) { SIF_Request request = new SIF_Request(); request.Header.SIF_MsgId = MSG_GUID; request.Header.SIF_SourceId = "foo"; request.SIF_MaxBufferSize = 32768; request.AddSIF_Version(new SIF_Version(Adk.SifVersion.ToString())); SIF_Query q = new SIF_Query(); SIF_QueryObject sqo = new SIF_QueryObject(); sqo.ObjectName = objType.Name; q.SIF_QueryObject = sqo; request.SIF_Query = q; return request; }
public void testPersistenceWithRemoval() { fRC = RequestCache.GetInstance(fAgent); SIF_QueryObject obj = new SIF_QueryObject(""); SIF_Query query = new SIF_Query(obj); SIF_Request request = new SIF_Request(); request.SIF_Query = query; Query q = new Query(StudentDTD.STUDENTPERSONAL); String testStateItem = Adk.MakeGuid(); TestState ts = new TestState(); ts.State = testStateItem; q.UserData = ts; fMsgIds = new String[10]; // Add 10 entries to the cache, interspersed with other entries that are removed for (int i = 0; i < 10; i++) { String phantom1 = Adk.MakeGuid(); String phantom2 = Adk.MakeGuid(); storeRequest(fRC, request, q, phantom1, "foo"); fMsgIds[i] = Adk.MakeGuid(); storeRequest(fRC, request, q, fMsgIds[i], "Object_" + i); storeRequest(fRC, request, q, phantom2, "bar"); fRC.GetRequestInfo(phantom1, null); fRC.GetRequestInfo(phantom2, null); } // remove every other entry, close, re-open and assert that the correct entries are there for (int i = 0; i < 10; i += 2) { fRC.GetRequestInfo(fMsgIds[i], null); } Assertion.AssertEquals("Before closing Should have five objects", 5, fRC.ActiveRequestCount); fRC.Close(); // Create a new instance. This one should retrieve its settings from the persistence mechanism fRC = RequestCache.GetInstance(fAgent); Assertion.AssertEquals("After Re-Openeing Should have five objects", 5, fRC.ActiveRequestCount); for (int i = 1; i < 10; i += 2) { IRequestInfo cachedInfo = fRC.GetRequestInfo(fMsgIds[i], null); Assertion.AssertNotNull("No cachedID returned for " + i, cachedInfo); } Assertion.AssertEquals("Should have zero objects", 0, fRC.ActiveRequestCount); }
/// <summary> Find the QueryResults object for a zone by searching up the message /// dispatching chain until a Zone, Topic, or Agent is found with a registered /// QueryResults implementation. /// /// </summary> /// <param name="rsp">The SIF_Response message (if a SIF_Response was received). /// Either rsp or req must be specified, but not both. /// </param> /// <param name="req">The SIF_Request message (if a SIF_Request is being sent). /// Either rsp or req must be specified, but not both. /// </param> /// <param name="query">Only applicable when <i>req</i> is non-null: The Query /// associated with the SIF_Request /// </param> /// <param name="zone">The Zone to begin the search at /// </param> internal IQueryResults getQueryResultsTarget(SIF_Response rsp, SIF_Request req, IElementDef objType, Query query, IZone zone) { // // - First check TrackQueryResults for a matching pending request // - Next check the Topic, the Zone, and finally the Agent. The // message is dispatched to the first one that results a // QueryResults object // IQueryResults target = null; SifContext context = null; if (req != null) { // First check TrackQueryResults string reqId = req.MsgId; // TODO: Implement SMB later // TrackQueryResults tracker = (TrackQueryResults) TrackQueryResultsImpl.sRequestQueries[query]; // if (tracker != null) // { // TrackQueryResultsImpl.sRequestQueries.Remove( query ); // target = tracker; // } // else // { SIF_Query q = req.SIF_Query; if (q == null) { throw new SifException (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Request message missing mandatory element", "SIF_Query is required", fZone); } SIF_QueryObject qo = q.SIF_QueryObject; if (qo == null) { throw new SifException (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Request message missing mandatory element", "SIF_QueryObject is required", fZone); } objType = Adk.Dtd.LookupElementDef(qo.ObjectName); if (objType == null) { throw new SifException (SifErrorCategoryCode.RequestResponse, SifErrorCodes.REQRSP_INVALID_OBJ_3, "Agent does not support this object type", qo.ObjectName, fZone); } // Check to see if the Context is supported // TODO: Determine if a SIFException should be thrown at this point? try { context = req.SifContexts[0]; } catch (AdkNotSupportedException contextNotSupported) { throw new SifException( SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_CONTEXT_NOT_SUPPORTED_4, contextNotSupported.Message, fZone); } } else if (rsp != null) { // TODO Implement SMB // // First check TrackQueryResults object to see if it is expecting // // to be called for this SIF_Response // string reqId = rsp.SIF_RequestMsgId; // // TrackQueryResults tracker = (TrackQueryResults) TrackQueryResultsImpl.sRequestMsgIds[reqId]; // if (tracker != null) // { // // Dispatch to the TrackQueryResults object // target = tracker; // } // Check to see if the Context is supported // TODO: Determine if a SIFException should be thrown at this point? try { context = rsp.SifContexts[0]; } catch (AdkNotSupportedException contextNotSupported) { throw new SifException( SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_CONTEXT_NOT_SUPPORTED_4, contextNotSupported.Message, fZone); } } else { throw new ArgumentException ( "A SIF_Request or SIF_Response object must be passed to getQueryResultsTarget"); } if (target == null) { TopicImpl topic = (TopicImpl)fZone.Agent.TopicFactory.LookupInstance(objType, context); if (topic != null) { target = topic.fQueryResults; } if (target == null) { // Next try the Zone... target = fZone.GetQueryResults(context, objType); } if (target == null) { // Finally, try the Agent... target = fZone.Agent.GetQueryResults(context, objType); } } return target; }
/// <summary> Store the request MsgId and associated SIF Data Object type in the cache</summary> public abstract IRequestInfo StoreRequestInfo( SIF_Request request, Query query, IZone zone );
private void sendErrorResponse(SIF_Request req, SifException se, SifVersion renderAsVer, int maxBufSize) { DataObjectOutputStreamImpl outStream = DataObjectOutputStreamImpl.NewInstance(); outStream.Initialize(fZone, (IElementDef[])null, req.SourceId, req.MsgId, renderAsVer, maxBufSize); SIF_Error err = new SIF_Error( (int)se.ErrorCategory, se.ErrorCode, se.ErrorDesc); err.SIF_ExtendedDesc = se.ErrorExtDesc; outStream.SetError(err); try { outStream.Close(); } catch (Exception ignored) { fZone.Log.Warn("Ignoring exception in out.close()", ignored); } try { outStream.Commit(); } catch (Exception ignored) { fZone.Log.Warn("Ignoring exception in out.commit()", ignored); } }
/// <summary> Dispatch a SIF_Request. /// /// <b>When ALQ Disabled:</b> The SIF_Request is immediately dispatched to /// the Publisher of the associated topic. Only after the Publisher has /// returned a result does this method return, causing the SIF_Request to /// be acknowledged. The result data returned by the Publisher is handed to /// the zone's ResponseDelivery thread, which sends SIF_Response messages to /// the ZIS until all of the result data has been sent, potentially with /// multiple SIF_Response packets. Note without the ALQ, there is the /// potential for the agent to terminate before all data has been sent, /// causing some results to be lost. In this case the SIF_Request will have /// never been ack'd and will be processed again the next time the agent /// is started. /// /// /// <b>When ALQ Enabled:</b> The SIF_Request is placed in the ALQ where it /// will be consumed by the zone's ResponseDelivery thread at a later time. /// This method returns immediately, causing the SIF_Request to be /// acknowledged. The ResponseDelivery handles dispatching the request to /// the Publisher of the associated topic, and also handles returning /// SIF_Response packets to the ZIS. With the ALQ, the processing of the /// SIF_Request and the returning of all SIF_Response data is guaranteed /// because the original SIF_Request will not be removed from the ALQ until /// both of these activities have completed successfully (even over multiple /// agent sessions). /// /// /// Note that any error that occurs during a SIF_Request should result in a /// successful SIF_Ack (because the SIF_Request was received successfully), /// and a single SIF_Response with a SIF_Error payload. The SIF Compliance /// harness checks for this. /// /// /// </summary> /// <param name="req">The SIF_Request to process /// </param> private void dispatchRequest(SIF_Request req) { SifVersion renderAsVer = null; SIF_Query q = null; SIF_QueryObject qo = null; IElementDef typ = null; int maxBufSize = 0; bool rethrow = false; try { // block thread until Zone.query() has completed in case it is in the // midst of a SIF_Request and the destination of that request is this // agent (i.e. a request of self). This is done to ensure that we don't // receive the SIF_Request from the zone before the ADK and agent have // finished issuing it in Zone.query() fZone.WaitForRequestsToComplete(); // // Check SIF_Version. If the version is not supported by the Adk, // fail the SIF_Request with an error SIF_Ack. If the version is // supported, continue on; the agent may not support this version, // but that will be determined later and will result in a SIF_Response // with a SIF_Error payload. // SIF_Version[] versions = req.GetSIF_Versions(); if (versions == null || versions.Length == 0) { rethrow = true; throw new SifException ( SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Request/SIF_Version is a mandatory element", fZone); } // SIF_Version specifies the version of SIF that will be used to render // the SIF_Responses // TODO: Add support for multiple SIF_Request versions renderAsVer = SifVersion.Parse(versions[0].Value); if (!Adk.IsSIFVersionSupported(renderAsVer)) { rethrow = true; throw new SifException ( SifErrorCategoryCode.RequestResponse, SifErrorCodes.REQRSP_UNSUPPORTED_SIFVERSION_7, "SIF_Version " + renderAsVer + " is not supported by this agent", fZone); } // Check max buffer size int? maximumBufferSize = req.SIF_MaxBufferSize; if (!maximumBufferSize.HasValue ) { rethrow = true; throw new SifException ( SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Request/SIF_MaxBufferSize is a mandatory element", fZone); } maxBufSize = maximumBufferSize.Value; if (maxBufSize < 4096 || maxBufSize > Int32.MaxValue) { throw new SifException ( SifErrorCategoryCode.RequestResponse, SifErrorCodes.REQRSP_UNSUPPORTED_MAXBUFFERSIZE_8, "Invalid SIF_MaxBufferSize value (" + maxBufSize + ")", "Acceptable range is 4096 to " + Int32.MaxValue, fZone); } // Check to see if the Context is supported try { IList<SifContext> contexts = req.SifContexts; } catch (AdkNotSupportedException contextNotSupported) { throw new SifException( SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_CONTEXT_NOT_SUPPORTED_4, contextNotSupported.Message, fZone); } // Lookup the SIF_QueryObject q = req.SIF_Query; if (q == null) { // If it's a SIF_ExtendedQuery or SIF_Example, throw the appropriate error if (req.SIF_ExtendedQuery != null) { throw new SifException( SifErrorCategoryCode.RequestResponse, SifErrorCodes.REQRSP_NO_SUPPORT_FOR_SIF_EXT_QUERY, "SIF_ExtendedQuery is not supported", fZone); } else { throw new SifException ( SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Request/SIF_Query is a mandatory element", fZone); } } qo = q.SIF_QueryObject; if (qo == null) { rethrow = true; throw new SifException ( SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Query/SIF_QueryObject is a mandatory element", fZone); } // Lookup the ElementDef for the requested object type typ = Adk.Dtd.LookupElementDef(qo.ObjectName); if (typ == null) { throw new SifException ( SifErrorCategoryCode.RequestResponse, SifErrorCodes.REQRSP_INVALID_OBJ_3, "Agent does not support this object type: " + qo.ObjectName, fZone); } } catch (SifException se) { if (!rethrow) { sendErrorResponse(req, se, renderAsVer, maxBufSize); } // rethrow all errors at this point throw se; // // Capture the SifException so it can be written to the output stream // // and thus returned as the payload of the SIF_Response message later // // in this function. // error = se; // fZone.Log.Error("Error in dispatchRequest that will be put into the SIF_Response", se); } // For now, SIFContext is not repeatable in SIF Requests SifContext requestContext = req.SifContexts[0]; Object target = null; // // Lookup the Publisher for this object type using Topics, // but only if the context is the Default context // if (typ != null && SifContext.DEFAULT.Equals(requestContext)) { ITopic topic = null; topic = fZone.Agent.TopicFactory.LookupInstance(typ, requestContext); if (topic != null) { target = topic.GetPublisher(); } } if (target == null) { target = fZone.GetPublisher(requestContext, typ); if (target == null) { // // No Publisher message handler found. Try calling the Undeliverable- // MessageHandler for the zone or agent. If none is registered, // return an error SIF_Ack indicating the object type is not // supported. // Boolean handled = false; IUndeliverableMessageHandler errHandler = fZone.ErrorHandler; if (errHandler != null) { SifMessageInfo msginfo = new SifMessageInfo(req, fZone); handled = errHandler.OnDispatchError(req, fZone, msginfo); // Notify MessagingListeners... foreach (IMessagingListener ml in GetMessagingListeners(fZone)) { ml.OnMessageProcessed(SifMessageType.SIF_Request, msginfo); } } if (!handled) { fZone.Log.Warn("Received a SIF_Request for " + qo.ObjectName + " (MsgId=" + req.MsgId + "), but no Publisher object is registered to handle it"); SifException sifEx = new SifException( SifErrorCategoryCode.RequestResponse, SifErrorCodes.REQRSP_INVALID_OBJ_3, "Agent does not support this object type", qo.ObjectName, fZone); sendErrorResponse(req, sifEx, renderAsVer, maxBufSize); throw sifEx; } else { #if PROFILED ( BuildOptions.PROFILED ) ProfilerUtils.profileStop(); #endif return; } } } //bool success; DataObjectOutputStreamImpl outStream = null; SifMessageInfo msgInfo = new SifMessageInfo(req, fZone); Query query = null; try { // Convert SIF_Request/SIF_Query into a Query object if (q != null) { query = new Query(q); } msgInfo.SIFRequestObjectType = typ; } catch (Exception thr) { fZone.Log.Debug(thr.ToString()); SifException sifEx = new SifException (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MALFORMED_2, "Could not parse SIF_Query element", thr.Message, fZone, thr); sendErrorResponse(req, sifEx, renderAsVer, maxBufSize); throw sifEx; } try { outStream = DataObjectOutputStreamImpl.NewInstance(); outStream.Initialize ( fZone, query, req.SourceId, req.MsgId, renderAsVer, maxBufSize ); // Call the agent-supplied Publisher, or if we have an error, write // that error to the output stream instead ((IPublisher)target).OnRequest(outStream, query, fZone, msgInfo); // Notify MessagingListeners... NotifyMessagingListeners_OnMessageProcessed (SifMessageType.SIF_Request, msgInfo); } catch (SifException se) { // For a SIF_Request, a SifException (other than a Transport Error) // does not mean to return an error ack but instead to return a // valid SIF_Response with a SIF_Error payload (see the SIF // Specification). Transport Errors must be returned to the ZIS so // that the message will be retried later. // if (se.Retry || se.ErrorCategory == SifErrorCategoryCode.Transport) { //success = false; //retry was requested, so we have to tell the output stream to not send an empty response outStream.DeferResponse(); throw; } outStream.SetError(se.Error); } catch (AdkException adke) { // If retry requested, throw a Transport Error back to the ZIS // instead of returning a SIF_Error in the SIF_Response payload if (adke.Retry) { //success = false; //retry was requested, so we have to tell the output stream to not send an empty response outStream.DeferResponse(); throw; } // Return SIF_Error payload in SIF_Response SIF_Error err = new SIF_Error(); err.SIF_Category = (int)SifErrorCategoryCode.Generic; err.SIF_Code = SifErrorCodes.GENERIC_GENERIC_ERROR_1; err.SIF_Desc = adke.Message; outStream.SetError(err); } catch (Exception thr) { SIF_Error err = new SIF_Error(); err.SIF_Category = (int)SifErrorCategoryCode.Generic; err.SIF_Code = SifErrorCodes.GENERIC_GENERIC_ERROR_1; err.SIF_Desc = "Agent could not process the SIF_Request at this time"; err.SIF_ExtendedDesc = "Exception in " + "Publisher.onRequest" + " message handler: " + thr.ToString(); outStream.SetError(err); } finally { try { outStream.Close(); } catch { // Do Nothing } try { outStream.Commit(); } catch { /* Do Nothing */ } #if PROFILED ProfilerUtils.profileStop(); #endif outStream.Dispose(); } }
/** * SIF_Request */ public SIF_Ack SifRequest(IZone zone, Query query, String destinationId, String sifMsgId) { // Send SIF_Request... SIF_Request msg = new SIF_Request(); // Find the maxmimum requested version and set the version of the message to lower // if the version is currently higher than the highest requested version. // In other words, if the Adk is initialized to 2.0, but the highest requested version // is 1.5r1, set the message version to 1.5r1 SifVersion highestRequestVersion = SifVersion.SIF11; if (query.ObjectType == InfraDTD.SIF_ZONESTATUS) { // This query will be satisfied by the ZIS. Use the ZIS compatibility // version, which returns the highest version supported by the ZIS // (Default to Adk.SIFVersion() if not specified in the config) highestRequestVersion = ((ZoneImpl)zone).HighestEffectiveZISVersion; msg.AddSIF_Version(new SIF_Version(highestRequestVersion)); } else { SifVersion[] requestVersions = query.SifVersions; if( requestVersions.Length > 0 ){ // If the Query has one or more SIFVersions set, use them, // and also add [major].* foreach( SifVersion version in requestVersions ){ msg.AddSIF_Version( new SIF_Version( version ) ); if( version.CompareTo( highestRequestVersion ) > 0 ){ highestRequestVersion = version; } } } else { highestRequestVersion = Adk.SifVersion; if( highestRequestVersion.Major == 1 ){ msg.AddSIF_Version( new SIF_Version( highestRequestVersion ) ); } else { // 2.0 and greater, request all data using // [major].*, with 2.0r1 as the message version // This allows for maximum compatibility will all 2.x providers msg.AddSIF_Version( new SIF_Version( highestRequestVersion.Major + ".*" )); msg.SifVersion = SifVersion.GetEarliest( highestRequestVersion.Major ); } } } AgentProperties zoneProperties = zone.Properties; if (zoneProperties.OverrideSifMessageVersionForSifRequests != null) { //There is a property in Agent.cfg that can be used to override the message version from the //default of 2.0r1 This is needed to pass the test harness for 2.3 msg.SifVersion = SifVersion.Parse(zoneProperties.OverrideSifMessageVersionForSifRequests); } else if(msg.SifVersion.CompareTo(highestRequestVersion) > 0) { // The current version of the SIF_Message is higher than the highest // requested version. Back the version number of message down to match msg.SifVersion = highestRequestVersion; } msg.SIF_MaxBufferSize = zone.Properties.MaxBufferSize; SIF_Query sifQ = CreateSIF_Query(query, highestRequestVersion, zone); msg.SIF_Query = sifQ; SIF_Header msgHeader = msg.Header; if (destinationId != null) { msgHeader.SIF_DestinationId = destinationId; } if (sifMsgId != null) { msgHeader.SIF_MsgId = sifMsgId; } // Set the SIF_Context msgHeader.SIF_Contexts = new SIF_Contexts( new SIF_Context(query.SifContext.Name)); return ((ZoneImpl)zone).Dispatcher.send(msg); }
public override IRequestInfo StoreRequestInfo(SIF_Request request, Query q, IZone zone) { // validate that the userdata supplied with the query is serializable if (q.UserData != null) { Type userDataType = q.UserData.GetType(); if (!userDataType.IsSerializable) { throw new ArgumentException ("Query.UserData contains " + userDataType.AssemblyQualifiedName + " which is not serializable"); } } try { RequestCacheFileEntry entry = new RequestCacheFileEntry(true); entry.SetObjectType(request.SIF_Query.SIF_QueryObject.ObjectName); entry.SetMessageId(request.MsgId); entry.SetUserData(q.UserData); Store(fFile, entry); return entry; } catch (Exception thr) { throw new AdkException ("Error writing to SIF_Request ID cache (MsgId: " + request.MsgId + ") " + thr, zone, thr); } }
private void SetRequestPolicy( SIF_Request request, IZone zone ) { SIF_Query query = request.SIF_Query; if( query == null ) { // SIF_ExtendedQuery and SIF_Example are not supported by ADK Policy yet return; } // // Object Request Policy // // Determine if there is policy in effect for this Query // String objectName = query.SIF_QueryObject.ObjectName; ObjectRequestPolicy requestPolicy = fPolicyFactory.GetRequestPolicy( zone, objectName ); if( requestPolicy != null ){ // // SIF_Request/SIF_Version policy // String requestVersions = requestPolicy.RequestVersion; if( requestVersions != null ){ if( (Adk.Debug & AdkDebugFlags.Policy ) > 0 ){ zone.Log.Info( "POLICY: Setting SIF_Request/SIF_Version to " + requestVersions ); } // Clear the list of SIF Versions foreach( SIF_Version existingVersion in request.GetSIF_Versions() ){ request.RemoveChild( existingVersion ); } // The version will be a comma-delimited list. Set each of these // as SIF_Version elements, but also try to derive the most logical // version element to set the SIF Message/@Version attribute to // NOTE: Someone could theoretically set versions incorrectly, such // as "1.1,1.5r1". Multiple SIF_Version elements are not supported in // SIF 1.x, but we won't bother with validating incorrect settings. Policy // is power in the configurator's hands to use or abuse. String[] versions = requestVersions.Split( ',' ); String lowestVersion = versions[0]; foreach( String version in versions ){ String ver = version.Trim(); request.AddSIF_Version(new SIF_Version(ver)); if (lowestVersion.CompareTo(ver) > 0) { lowestVersion = ver; } } // Determine how the SIF_Message/@Version should be set to // * If the policy is set to a single version, use it // * If a list, use the lowest // * If *, ignore // * if [major].*, use the lowest version supported if( lowestVersion.Length > 0 ){ SifVersion newMsgVersion = null; if( lowestVersion.EndsWith( "*" ) ){ try { // 2.*, requests go out with a message version of 2.0r1 int major = int.Parse( lowestVersion.Substring( 0, 1 ) ); newMsgVersion = SifVersion.GetEarliest( major ); } catch( FormatException iae ){ zone.Log.Warn( "POLICY: Error parsing ObjectRequestPolicy version '" + requestVersions + "' : " + iae.Message, iae ); } } else { try { newMsgVersion = SifVersion.Parse( lowestVersion ); } catch( FormatException iae ){ zone.Log.Warn( "POLICY: Error parsing ObjectRequestPolicy version '" + requestVersions + "' : " + iae.Message, iae ); } } if( newMsgVersion != null ){ if( (Adk.Debug & AdkDebugFlags.Policy ) > 0 ){ zone.Log.Info( "POLICY: Setting SIF_Messaage/@Version to " + newMsgVersion ); } request.SifVersion = newMsgVersion; } } } // // SIF_DestinationID policy // String requestSourceId = requestPolicy.RequestSourceId ; if( requestSourceId != null ){ if( (Adk.Debug & AdkDebugFlags.Policy) > 0 ){ zone.Log.Info( "POLICY: Setting SIF_Request SIF_DestinationID to " + requestPolicy.RequestSourceId ); } request.SIF_Header.SIF_DestinationId = requestSourceId; } } }