/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.axis2.engine; import junit.framework.TestCase; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.soap.SOAPFactory; import org.apache.axiom.util.UIDGenerator; import org.apache.axis2.AxisFault; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.MessageContext; import org.apache.axis2.context.OperationContext; import org.apache.axis2.context.ServiceContext; import org.apache.axis2.context.ServiceGroupContext; import org.apache.axis2.description.AxisMessage; import org.apache.axis2.description.AxisOperation; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.AxisServiceGroup; import org.apache.axis2.description.HandlerDescription; import org.apache.axis2.description.InOutAxisOperation; import org.apache.axis2.description.TransportInDescription; import org.apache.axis2.description.TransportOutDescription; import org.apache.axis2.dispatchers.AddressingBasedDispatcher; import org.apache.axis2.dispatchers.RequestURIBasedDispatcher; import org.apache.axis2.dispatchers.SOAPActionBasedDispatcher; import org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher; import org.apache.axis2.handlers.AbstractHandler; import org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver; import org.apache.axis2.receivers.RawXMLINOutMessageReceiver; import org.apache.axis2.transport.http.SimpleHTTPServer; import org.apache.axis2.transport.http.impl.httpclient4.HTTPClient4TransportSender; import org.apache.axis2.util.MetaDataEntry; import org.apache.axis2.wsdl.WSDLConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.xml.namespace.QName; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; /** * Provides tests that focus on the message context object graph */ public class MessageContextSaveCTest extends TestCase { protected static final Log log = LogFactory.getLog(MessageContextSaveCTest.class); private File persistentStore = null; //------------------------------------------------------------------------- // variables for the object graph //------------------------------------------------------------------------- // used on a save of a message context, uses the same setup // as the regular top-level objects. the difference is that // the phase contains handlers that split the action across // two handlers private ConfigurationContext saveConfigurationContext = null; private AxisConfiguration saveAxisConfiguration = null; // used on a restore of a message context, uses the same setup // as the regular top-level objects with the exception that the // context objects don't exist. also, the phase contains handlers // that split the action across two handlers private ConfigurationContext restoreConfigurationContext = null; private AxisConfiguration restoreAxisConfiguration = null; // used on a restore of a message context, uses the same setup // as the regular top-level objects with service-level context objects // with the name service name. also, the phase contains handlers // that split the action across two handlers private ConfigurationContext equivConfigurationContext = null; private AxisConfiguration equivAxisConfiguration = null; //------------------------------ // service group ABC //------------------------------ private String serviceGroupName_ABC = "ABCServiceGroup"; private String serviceName_A = "ServiceA"; private String serviceName_B = "ServiceB"; private String serviceName_C = "ServiceC"; private QName service_QName_A = new QName(serviceName_A); private QName service_QName_B = new QName(serviceName_B); private QName service_QName_C = new QName(serviceName_C); private String operationName_A1 = "TestOperationA1"; private String operationName_A2 = "TestOperationA2"; private QName operation_QName_A1 = new QName(operationName_A1); private QName operation_QName_A2 = new QName(operationName_A2); private ServiceGroupContext srvGrpCtx_ABC_save = null; private AxisServiceGroup axisSrvGrp_ABC_save = null; private AxisServiceGroup axisSrvGrp_ABC_restore = null; private ServiceGroupContext srvGrpCtx_ABC_equiv = null; private AxisServiceGroup axisSrvGrp_ABC_equiv = null; private ServiceContext srvCtx_A_save = null; private ServiceContext srvCtx_B_save = null; private ServiceContext srvCtx_C_save = null; private AxisService axisSrv_A_save = null; private AxisService axisSrv_B_save = null; private AxisService axisSrv_C_save = null; private ServiceContext srvCtx_A_restore = null; private ServiceContext srvCtx_B_restore = null; private ServiceContext srvCtx_C_restore = null; private AxisService axisSrv_A_restore = null; private AxisService axisSrv_B_restore = null; private AxisService axisSrv_C_restore = null; private ServiceContext srvCtx_A_equiv = null; private ServiceContext srvCtx_B_equiv = null; private ServiceContext srvCtx_C_equiv = null; private AxisService axisSrv_A_equiv = null; private AxisService axisSrv_B_equiv = null; private AxisService axisSrv_C_equiv = null; private OperationContext opCtx_A1_save = null; private OperationContext opCtx_A2_save = null; private AxisOperation axisOp_A1_save = null; private AxisOperation axisOp_A2_save = null; private OperationContext opCtx_A1_restore = null; private OperationContext opCtx_A2_restore = null; private AxisOperation axisOp_A1_restore = null; private AxisOperation axisOp_A2_restore = null; private OperationContext opCtx_A1_equiv = null; private OperationContext opCtx_A2_equiv = null; private AxisOperation axisOp_A1_equiv = null; private AxisOperation axisOp_A2_equiv = null; private MessageContext msgCtx_A1_1_save = null; private MessageContext msgCtx_A1_2_save = null; private MessageContext msgCtx_A2_save = null; private MessageContext msgCtx_A1_1_equiv = null; private MessageContext msgCtx_A1_2_equiv = null; private MessageContext msgCtx_A2_equiv = null; //------------------------------------- // objects needed for message context //------------------------------------ private TransportOutDescription transportOut = null; private TransportOutDescription transportOut2 = null; private TransportOutDescription transportOut3 = null; private TransportInDescription transportIn = null; private TransportInDescription transportIn2 = null; private TransportInDescription transportIn3 = null; private Phase phaseSave = null; private Phase phaseRestore = null; private Phase phaseEquiv = null; private ArrayList executedHandlers = null; private MessageContext restoredMessageContext = null; //------------------------------------------------------------------------- // methods //------------------------------------------------------------------------- public MessageContextSaveCTest(String arg0) { super(arg0); try { prepare(); } catch (Exception e) { log.debug("MessageContextSaveCTest:constructor: error in setting up object graph [" + e.getClass().getName() + " : " + e.getMessage() + "]"); } } // // prepare the object hierarchy for testing // private void prepare() throws Exception { //----------------------------------------------------------------- // setup the top-level objects //----------------------------------------------------------------- DispatchPhase dispatchPhase = new DispatchPhase(); dispatchPhase.setName("Dispatch"); AddressingBasedDispatcher abd = new AddressingBasedDispatcher(); abd.initDispatcher(); RequestURIBasedDispatcher rud = new RequestURIBasedDispatcher(); rud.initDispatcher(); SOAPActionBasedDispatcher sabd = new SOAPActionBasedDispatcher(); sabd.initDispatcher(); SOAPMessageBodyBasedDispatcher smbd = new SOAPMessageBodyBasedDispatcher(); smbd.initDispatcher(); dispatchPhase.addHandler(abd); dispatchPhase.addHandler(rud); dispatchPhase.addHandler(sabd); dispatchPhase.addHandler(smbd); saveAxisConfiguration = new AxisConfiguration(); saveConfigurationContext = new ConfigurationContext(saveAxisConfiguration); saveConfigurationContext.getAxisConfiguration().addMessageReceiver( "http://www.w3.org/ns/wsdl/in-only", new RawXMLINOnlyMessageReceiver()); saveConfigurationContext.getAxisConfiguration().addMessageReceiver( "http://www.w3.org/ns/wsdl/in-out", new RawXMLINOutMessageReceiver()); saveConfigurationContext.getAxisConfiguration().getInFlowPhases().add(dispatchPhase); restoreAxisConfiguration = new AxisConfiguration(); restoreConfigurationContext = new ConfigurationContext(restoreAxisConfiguration); restoreConfigurationContext.getAxisConfiguration().addMessageReceiver( "http://www.w3.org/ns/wsdl/in-only", new RawXMLINOnlyMessageReceiver()); restoreConfigurationContext.getAxisConfiguration().addMessageReceiver( "http://www.w3.org/ns/wsdl/in-out", new RawXMLINOutMessageReceiver()); restoreConfigurationContext.getAxisConfiguration().getInFlowPhases().add(dispatchPhase); equivAxisConfiguration = new AxisConfiguration(); equivConfigurationContext = new ConfigurationContext(equivAxisConfiguration); equivConfigurationContext.getAxisConfiguration().addMessageReceiver( "http://www.w3.org/ns/wsdl/in-only", new RawXMLINOnlyMessageReceiver()); equivConfigurationContext.getAxisConfiguration().addMessageReceiver( "http://www.w3.org/ns/wsdl/in-out", new RawXMLINOutMessageReceiver()); equivConfigurationContext.getAxisConfiguration().getInFlowPhases().add(dispatchPhase); //---------------------------- // transport-related objects //---------------------------- transportOut = new TransportOutDescription("null"); transportOut2 = new TransportOutDescription("happy"); transportOut3 = new TransportOutDescription("golucky"); transportOut.setSender(new HTTPClient4TransportSender()); transportOut2.setSender(new HTTPClient4TransportSender()); transportOut3.setSender(new HTTPClient4TransportSender()); saveAxisConfiguration.addTransportOut(transportOut3); saveAxisConfiguration.addTransportOut(transportOut2); saveAxisConfiguration.addTransportOut(transportOut); restoreAxisConfiguration.addTransportOut(transportOut3); restoreAxisConfiguration.addTransportOut(transportOut2); restoreAxisConfiguration.addTransportOut(transportOut); equivAxisConfiguration.addTransportOut(transportOut3); equivAxisConfiguration.addTransportOut(transportOut2); equivAxisConfiguration.addTransportOut(transportOut); transportIn = new TransportInDescription("null"); transportIn2 = new TransportInDescription("always"); transportIn3 = new TransportInDescription("thebest"); transportIn.setReceiver(new SimpleHTTPServer()); transportIn2.setReceiver(new SimpleHTTPServer()); transportIn3.setReceiver(new SimpleHTTPServer()); saveAxisConfiguration.addTransportIn(transportIn2); saveAxisConfiguration.addTransportIn(transportIn); saveAxisConfiguration.addTransportIn(transportIn3); restoreAxisConfiguration.addTransportIn(transportIn2); restoreAxisConfiguration.addTransportIn(transportIn); restoreAxisConfiguration.addTransportIn(transportIn3); equivAxisConfiguration.addTransportIn(transportIn2); equivAxisConfiguration.addTransportIn(transportIn); equivAxisConfiguration.addTransportIn(transportIn3); //---------------------------- // phase-related objects //---------------------------- persistentStore = File.createTempFile("mcObjTest", null); phaseSave = new Phase("PhaseTest"); phaseSave.addHandler(new TempHandler(1, 1)); phaseSave.addHandler(new SaveHandler(2, persistentStore, true)); phaseSave.addHandler(new TempHandler(3, 1)); ArrayList phases_Save = new ArrayList(); phases_Save.add(phaseSave); saveAxisConfiguration.setInPhasesUptoAndIncludingPostDispatch(phases_Save); phaseRestore = new Phase("PhaseTest"); phaseRestore.addHandler(new TempHandler(1, 1)); phaseRestore.addHandler(new SaveHandler(2, persistentStore, false)); phaseRestore.addHandler(new TempHandler(3, 1)); ArrayList phases_Restore = new ArrayList(); phases_Restore.add(phaseRestore); restoreAxisConfiguration.setInPhasesUptoAndIncludingPostDispatch(phases_Restore); phaseEquiv = new Phase("PhaseTest"); phaseEquiv.addHandler(new TempHandler(1, 1)); phaseEquiv.addHandler(new SaveHandler(2, persistentStore, true)); phaseEquiv.addHandler(new TempHandler(3, 1)); ArrayList phases_Equiv = new ArrayList(); phases_Equiv.add(phaseEquiv); equivAxisConfiguration.setInPhasesUptoAndIncludingPostDispatch(phases_Equiv); //----------------------------------------------------------------- // setup the axis side of the hierachy //----------------------------------------------------------------- // ABC group //---------------------------- axisSrvGrp_ABC_save = new AxisServiceGroup(saveAxisConfiguration); axisSrvGrp_ABC_save.setServiceGroupName(serviceGroupName_ABC); axisSrv_A_save = new AxisService(service_QName_A.getLocalPart()); axisSrv_B_save = new AxisService(service_QName_B.getLocalPart()); axisSrv_C_save = new AxisService(service_QName_C.getLocalPart()); axisSrvGrp_ABC_save.addService(axisSrv_A_save); axisSrvGrp_ABC_save.addService(axisSrv_B_save); axisSrvGrp_ABC_save.addService(axisSrv_C_save); axisOp_A1_save = new InOutAxisOperation(operation_QName_A1); axisOp_A2_save = new InOutAxisOperation(operation_QName_A2); axisOp_A1_save.setMessageReceiver(new MessageReceiver() { public void receive(MessageContext messageCtx) { } }); axisOp_A2_save.setMessageReceiver(new MessageReceiver() { public void receive(MessageContext messageCtx) { } }); axisSrv_A_save.addOperation(axisOp_A1_save); axisSrv_A_save.mapActionToOperation(operation_QName_A1.getLocalPart(), axisOp_A1_save); axisSrv_A_save.addOperation(axisOp_A2_save); axisSrv_A_save.mapActionToOperation(operation_QName_A2.getLocalPart(), axisOp_A2_save); saveAxisConfiguration.addService(axisSrv_A_save); saveAxisConfiguration.addService(axisSrv_B_save); saveAxisConfiguration.addService(axisSrv_C_save); //--------------------- axisSrvGrp_ABC_restore = new AxisServiceGroup(restoreAxisConfiguration); axisSrvGrp_ABC_restore.setServiceGroupName(serviceGroupName_ABC); axisSrv_A_restore = new AxisService(service_QName_A.getLocalPart()); axisSrv_B_restore = new AxisService(service_QName_B.getLocalPart()); axisSrv_C_restore = new AxisService(service_QName_C.getLocalPart()); axisSrvGrp_ABC_restore.addService(axisSrv_A_restore); axisSrvGrp_ABC_restore.addService(axisSrv_B_restore); axisSrvGrp_ABC_restore.addService(axisSrv_C_restore); axisOp_A1_restore = new InOutAxisOperation(operation_QName_A1); axisOp_A2_restore = new InOutAxisOperation(operation_QName_A2); axisOp_A1_restore.setMessageReceiver(new MessageReceiver() { public void receive(MessageContext messageCtx) { } }); axisOp_A2_restore.setMessageReceiver(new MessageReceiver() { public void receive(MessageContext messageCtx) { } }); axisSrv_A_restore.addOperation(axisOp_A1_restore); axisSrv_A_restore .mapActionToOperation(operation_QName_A1.getLocalPart(), axisOp_A1_restore); axisSrv_A_restore.addOperation(axisOp_A2_restore); axisSrv_A_restore .mapActionToOperation(operation_QName_A2.getLocalPart(), axisOp_A2_restore); restoreAxisConfiguration.addService(axisSrv_A_restore); restoreAxisConfiguration.addService(axisSrv_B_restore); restoreAxisConfiguration.addService(axisSrv_C_restore); axisOp_A1_save.getRemainingPhasesInFlow().add(phaseSave); axisOp_A2_save.getRemainingPhasesInFlow().add(phaseSave); axisOp_A1_restore.getRemainingPhasesInFlow().add(phaseRestore); axisOp_A2_restore.getRemainingPhasesInFlow().add(phaseRestore); //------------------------------- axisSrvGrp_ABC_equiv = new AxisServiceGroup(equivAxisConfiguration); axisSrvGrp_ABC_equiv.setServiceGroupName(serviceGroupName_ABC); axisSrv_A_equiv = new AxisService(service_QName_A.getLocalPart()); axisSrv_B_equiv = new AxisService(service_QName_B.getLocalPart()); axisSrv_C_equiv = new AxisService(service_QName_C.getLocalPart()); axisSrvGrp_ABC_equiv.addService(axisSrv_A_equiv); axisSrvGrp_ABC_equiv.addService(axisSrv_B_equiv); axisSrvGrp_ABC_equiv.addService(axisSrv_C_equiv); axisOp_A1_equiv = new InOutAxisOperation(operation_QName_A1); axisOp_A2_equiv = new InOutAxisOperation(operation_QName_A2); axisOp_A1_equiv.setMessageReceiver(new MessageReceiver() { public void receive(MessageContext messageCtx) { } }); axisOp_A2_equiv.setMessageReceiver(new MessageReceiver() { public void receive(MessageContext messageCtx) { } }); axisSrv_A_equiv.addOperation(axisOp_A1_equiv); axisSrv_A_equiv.mapActionToOperation(operation_QName_A1.getLocalPart(), axisOp_A1_equiv); axisSrv_A_equiv.addOperation(axisOp_A2_equiv); axisSrv_A_equiv.mapActionToOperation(operation_QName_A2.getLocalPart(), axisOp_A2_equiv); equivAxisConfiguration.addService(axisSrv_A_equiv); equivAxisConfiguration.addService(axisSrv_B_equiv); equivAxisConfiguration.addService(axisSrv_C_equiv); //----------------------------------------------------------------- // setup the context objects //----------------------------------------------------------------- srvGrpCtx_ABC_save = saveConfigurationContext.createServiceGroupContext(axisSrvGrp_ABC_save); srvGrpCtx_ABC_save.setId(serviceGroupName_ABC); srvCtx_A_save = srvGrpCtx_ABC_save.getServiceContext(axisSrv_A_save); srvCtx_B_save = srvGrpCtx_ABC_save.getServiceContext(axisSrv_B_save); srvCtx_C_save = srvGrpCtx_ABC_save.getServiceContext(axisSrv_C_save); opCtx_A1_save = srvCtx_A_save.createOperationContext(operation_QName_A1); opCtx_A2_save = srvCtx_A_save.createOperationContext(operation_QName_A2); //---------------------------------------- srvGrpCtx_ABC_equiv = equivConfigurationContext.createServiceGroupContext(axisSrvGrp_ABC_equiv); srvGrpCtx_ABC_equiv.setId(serviceGroupName_ABC); srvCtx_A_equiv = srvGrpCtx_ABC_equiv.getServiceContext(axisSrv_A_equiv); srvCtx_B_equiv = srvGrpCtx_ABC_equiv.getServiceContext(axisSrv_B_equiv); srvCtx_C_equiv = srvGrpCtx_ABC_equiv.getServiceContext(axisSrv_C_equiv); opCtx_A1_equiv = srvCtx_A_equiv.createOperationContext(operation_QName_A1); opCtx_A2_equiv = srvCtx_A_equiv.createOperationContext(operation_QName_A2); //---------------------------------------- // message context objects //---------------------------------------- msgCtx_A1_1_save = createMessageContext(opCtx_A1_save, saveConfigurationContext, MessageContext.IN_FLOW); msgCtx_A1_2_save = createMessageContext(opCtx_A1_save, saveConfigurationContext, MessageContext.OUT_FLOW); msgCtx_A2_save = createMessageContext(opCtx_A2_save, saveConfigurationContext, MessageContext.IN_FLOW); msgCtx_A1_1_equiv = createMessageContext(opCtx_A1_equiv, equivConfigurationContext, MessageContext.IN_FLOW); msgCtx_A1_2_equiv = createMessageContext(opCtx_A1_equiv, equivConfigurationContext, MessageContext.OUT_FLOW); msgCtx_A2_equiv = createMessageContext(opCtx_A2_equiv, equivConfigurationContext, MessageContext.IN_FLOW); //----------------------------------------------------------------- // other objects //----------------------------------------------------------------- executedHandlers = new ArrayList(); } private MessageContext createMessageContext(OperationContext oc, ConfigurationContext cc, int flowType) throws Exception { MessageContext mc = cc.createMessageContext(); mc.setFLOW(flowType); mc.setTransportIn(transportIn); mc.setTransportOut(transportOut); mc.setServerSide(true); // mc.setProperty(MessageContext.TRANSPORT_OUT, System.out); SOAPFactory omFac = OMAbstractFactory.getSOAP11Factory(); mc.setEnvelope(omFac.getDefaultEnvelope()); AxisOperation axisOperation = oc.getAxisOperation(); String action = axisOperation.getName().getLocalPart(); mc.setSoapAction(action); // System.out.flush(); mc.setMessageID(UIDGenerator.generateURNString()); axisOperation.registerOperationContext(mc, oc); mc.setOperationContext(oc); ServiceContext sc = oc.getServiceContext(); mc.setServiceContext(sc); mc.setTo(new EndpointReference("axis2/services/NullService")); mc.setWSAAction("DummyOp"); AxisMessage axisMessage = axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE); mc.setAxisMessage(axisMessage); return mc; } protected void setUp() throws Exception { //org.apache.log4j.BasicConfigurator.configure(); } public void testHierarchyNewContext() throws Exception { String title = "MessageContextSaveCTest:testHierarchyNewContext(): "; MessageContext mc = msgCtx_A1_2_save; OperationContext oc = mc.getOperationContext(); log.debug(title + "*** Original OperationContext message context table ****"); showMCTable(oc); // run the message through the message processing // this causes the message context to get saved log.debug(title + "- - - Save the message context from the engine - - - -"); AxisEngine.receive(mc); LinkedHashMap original_object_graph = getObjectGraphInfo(mc); log.debug(title + "*** Originial object graph ****"); showObjectGraphInfo(original_object_graph); log.debug(title + "- - - Restore the message context on a separate engine - - - - - - - - - - - - - - - -"); MessageContext mc2 = restoreMessageContext(persistentStore, restoreConfigurationContext); LinkedHashMap restored_object_graph = getObjectGraphInfo(mc2); log.debug(title + "*** Restored object graph ****"); showObjectGraphInfo(restored_object_graph); OperationContext oc2 = mc2.getOperationContext(); log.debug(title + "*** Restored OperationContext message context table ****"); showMCTable(oc2); boolean mcTableMatch = compareMCTable(oc, oc2); assertTrue(mcTableMatch); // resume the restored paused message context on an engine that has the // same setup as the engine where the save occurred // but doesn't have the Context objects log.debug(title + "- - - Resume the restored message context - - - - - - - - - - - - - - - -"); AxisEngine.resume(mc2); LinkedHashMap resumed_object_graph = getObjectGraphInfo(mc2); log.debug(title + "*** Post Resumed object graph ****"); showObjectGraphInfo(resumed_object_graph); // compare object hashcodes - expect differences boolean expectFalse = compareObjectGraphInfo(original_object_graph, restored_object_graph, true); assertFalse(expectFalse); boolean expectSameObjectIds = compareObjectGraphInfo(original_object_graph, restored_object_graph, false); assertTrue(expectSameObjectIds); boolean isSame = compareObjectGraphInfo(restored_object_graph, resumed_object_graph, false); assertTrue(isSame); } public void testHierarchyReuse() throws Exception { String title = "MessageContextSaveCTest:testHierarchyReuse(): "; MessageContext mc = msgCtx_A1_1_save; // run the message through the message processing // this causes the message context to get saved log.debug(title + "- - - Save the message context from the engine - - - -"); AxisEngine.receive(mc); LinkedHashMap original_object_graph = getObjectGraphInfo(mc); log.debug(title + "*** Originial object graph ****"); showObjectGraphInfo(original_object_graph); log.debug(title + "- - - Restore the message context on a separate engine - - - - - - - - - - - - - - - -"); MessageContext mc2 = restoreMessageContext(persistentStore, equivConfigurationContext); LinkedHashMap restored_object_graph = getObjectGraphInfo(mc2); log.debug(title + "*** Restored object graph ****"); showObjectGraphInfo(restored_object_graph); // we don't use strict checking here since the engine where the // restoration takes place is a "copy", ie, there are new objects // for the same names/identifications boolean hasEquivalence = compareObjectGraphInfo(original_object_graph, restored_object_graph, false); assertTrue(hasEquivalence); // get an object graph from an equivalent message context on the separate engine // we would expect a strict match of the object graphs between the // restored message context and the message context on the separate engine LinkedHashMap separate_object_graph = getObjectGraphInfo(msgCtx_A1_1_equiv); // compare the restored object graph with the existing object graph boolean expectStrict = compareObjectGraphInfo(restored_object_graph, separate_object_graph, true); assertTrue(expectStrict); // resume the restored paused message context on an engine that has the // same setup as the engine where the save occurred // and save has the Service-level Context objects log.debug(title + "- - - Resume the restored message context - - - - - - - - - - - - - - - -"); AxisEngine.resume(mc2); LinkedHashMap resumed_object_graph = getObjectGraphInfo(mc2); log.debug(title + "*** Post Resumed object graph ****"); showObjectGraphInfo(resumed_object_graph); // there should be no changes in the object graph in our case after the resume hasEquivalence = compareObjectGraphInfo(restored_object_graph, resumed_object_graph, true); assertTrue(hasEquivalence); } /** * Restores a previously saved message context */ public MessageContext restoreMessageContext(File restoreFile, ConfigurationContext cc) { String title = "restoreMessageContext(): "; MessageContext restoredMC = null; File theFile = restoreFile; String theFilename = null; // the configuration context to use for message context activation ConfigurationContext cfgCtx = cc; boolean restoredOk = false; if ((theFile != null) && (theFile.exists())) { theFilename = theFile.getName(); log.debug(title + "temp file = [" + theFilename + "]"); // --------------------------------------------------------- // restore from the temporary file // --------------------------------------------------------- try { // setup an input stream to the file FileInputStream inStream = new FileInputStream(theFile); // attach a stream capable of reading objects from the // stream connected to the file ObjectInputStream inObjStream = new ObjectInputStream(inStream); // try to restore the message context log.debug(title + "restoring a message context....."); restoredOk = false; MessageContext msgContext2 = (MessageContext) inObjStream.readObject(); inObjStream.close(); inStream.close(); msgContext2.activate(cfgCtx); restoredOk = true; log.debug(title + "....restored message context....."); // now put the restored message context in the global // variable for the test restoredMC = msgContext2; } catch (Exception ex2) { log.debug(title + "error with restoring message context = [" + ex2.getClass().getName() + " : " + ex2.getMessage() + "]"); ex2.printStackTrace(); restoredMessageContext = null; } assertTrue(restoredOk); // if the restore of the message context succeeded, // then don't keep the temporary file around boolean removeTmpFile = restoredOk; if (removeTmpFile) { try { theFile.delete(); } catch (Exception e) { // just absorb it } } } return restoredMC; } private LinkedHashMap getObjectGraphInfo(MessageContext msgCtx) { if (msgCtx == null) { return null; } MetaDataEntry metaMC = null; MetaDataEntry metaOC = null; MetaDataEntry metaSC = null; MetaDataEntry metaSGC = null; MetaDataEntry metaCC = null; MetaDataEntry metaAO = null; MetaDataEntry metaAS = null; MetaDataEntry metaASG = null; MetaDataEntry metaAC = null; String keyMC = null; String keyOC = null; String keySC = null; String keySGC = null; String keyCC = null; String keyAO = null; String keyAS = null; String keyASG = null; String keyAC = null; LinkedHashMap objInfo = new LinkedHashMap(); // get the identification info about the primary objects in the object graph // class name // name string // hashcode string // message context keyMC = msgCtx.getClass().getName(); metaMC = new MetaDataEntry(keyMC, msgCtx.getMessageID(), "[" + msgCtx.hashCode() + "]"); objInfo.put(keyMC, metaMC); // operation context OperationContext oc = msgCtx.getOperationContext(); keyOC = oc.getClass().getName(); metaOC = new MetaDataEntry(keyOC, oc.getOperationName(), "[" + oc.hashCode() + "]"); objInfo.put(keyOC, metaOC); // service context ServiceContext sc = msgCtx.getServiceContext(); keySC = sc.getClass().getName(); metaSC = new MetaDataEntry(keySC, sc.getName(), "[" + sc.hashCode() + "]"); objInfo.put(keySC, metaSC); // service group context ServiceGroupContext sgc = msgCtx.getServiceGroupContext(); keySGC = sgc.getClass().getName(); metaSGC = new MetaDataEntry(keySGC, sgc.getId(), "[" + sgc.hashCode() + "]"); objInfo.put(keySGC, metaSGC); // configuration context ConfigurationContext cc = msgCtx.getConfigurationContext(); keyCC = cc.getClass().getName(); metaCC = new MetaDataEntry(keyCC, null, "[" + cc.hashCode() + "]"); objInfo.put(keyCC, metaCC); // axis operation AxisOperation ao = msgCtx.getAxisOperation(); keyAO = ao.getClass().getName(); metaAO = new MetaDataEntry(keyAO, ao.getName().toString(), "[" + ao.hashCode() + "]"); objInfo.put(keyAO, metaAO); // axis service AxisService as = msgCtx.getAxisService(); keyAS = as.getClass().getName(); metaAS = new MetaDataEntry(keyAS, as.getName(), "[" + as.hashCode() + "]"); objInfo.put(keyAS, metaAS); // axis service group AxisServiceGroup asg = msgCtx.getAxisServiceGroup(); keyASG = asg.getClass().getName(); metaASG = new MetaDataEntry(keyASG, asg.getServiceGroupName(), "[" + asg.hashCode() + "]"); objInfo.put(keyASG, metaASG); // axis configuration AxisConfiguration ac = cc.getAxisConfiguration(); keyAC = ac.getClass().getName(); metaAC = new MetaDataEntry(keyAC, null, "[" + ac.hashCode() + "]"); objInfo.put(keyAC, metaAC); return objInfo; } /** * Compare two mappings containing object graph info. * This uses the class name and object ID. * <p/> * Strict comparison includes the object hash codes. If * you expect the same object to be represented in * both maps, you may want to use Strict checking. * <p/> * * @param map1 The first object graph info map * @param map2 The second object graph info map * @param strict TRUE if strict comparison * @return Outcome of the comparison: TRUE if equivalent, FALSE otherwise */ private boolean compareObjectGraphInfo(LinkedHashMap map1, LinkedHashMap map2, boolean strict) { String title = "MessageContextSaveCTest: compareObjectGraphInfo(): "; if ((map1 != null) && (map2 != null)) { if (map1.size() != map2.size()) { log.debug(title + "Object graph info mappings are different sizes."); return false; } Iterator it = map1.keySet().iterator(); while (it.hasNext()) { // the key is the class name associated with the object String key = (String) it.next(); // skip certain objects, those will always be unique if ((key.indexOf("MessageContext") == -1) && (key.indexOf("OperationContext") == -1) && (key.indexOf("ConfigurationContext") == -1) && (key.indexOf("AxisConfiguration") == -1) ) { // the class names listed above were not found // so we're dealing with the other objects MetaDataEntry value1 = (MetaDataEntry) map1.get(key); MetaDataEntry value2 = (MetaDataEntry) map2.get(key); if ((value1 != null) && (value2 != null)) { // check the object identification String name1 = value1.getName(); String name2 = value2.getName(); if ((name1 != null) && (name2 != null)) { if (name1.equals(name2) == false) { log.debug(title + "name1 [" + name1 + "] != name2 [" + name2 + "]"); return false; } } else if ((name1 == null) && (name2 == null)) { // ok } else { // mismatch log.debug(title + "name1 [" + name1 + "] != name2 [" + name2 + "]"); return false; } // Strict testing means checking the object hashcodes. // Use this option when you expect the same // objects in the map. if (strict) { String code1 = value1.getExtraName(); String code2 = value2.getExtraName(); if ((code1 != null) && (code2 != null)) { if (code1.equals(code2) == false) { log.debug(title + "name [" + name1 + "] code1 [" + code1 + "] != code2 [" + code2 + "]"); return false; } } else if ((code1 == null) && (code2 == null)) { // ok } else { // mismatch log.debug(title + "name [" + name1 + "]code1 [" + code1 + "] != code2 [" + code2 + "]"); return false; } } } else if ((value1 == null) && (value2 == null)) { // ok } else { // mismatch log.debug(title + "value1 [" + value1 + "] != value2 [" + value2 + "]"); return false; } } } return true; } else if ((map1 == null) && (map2 == null)) { return true; } else { log.debug(title + "mismatch: one or more of the maps are null. "); return false; } } private void showObjectGraphInfo(LinkedHashMap map) { if (map == null) { return; } Iterator it = map.keySet().iterator(); while (it.hasNext()) { String metaClassName = (String) it.next(); MetaDataEntry meta = (MetaDataEntry) map.get(metaClassName); if (meta != null) { String classname = meta.getClassName(); String name = meta.getName(); String hashcode = meta.getExtraName(); log.debug("class[" + classname + "] id[" + name + "] hashcode" + hashcode + " "); } } } private boolean compareMCTable(OperationContext oc1, OperationContext oc2) { String title = "compareMCTable: "; if ((oc1 != null) && (oc2 != null)) { HashMap mcTable1 = oc1.getMessageContexts(); HashMap mcTable2 = oc2.getMessageContexts(); if ((mcTable1 != null) && (mcTable2 != null)) { if ((!mcTable1.isEmpty()) && (!mcTable2.isEmpty())) { int size1 = mcTable1.size(); int size2 = mcTable2.size(); if (size1 != size2) { log.debug(title + " Return FALSE: table sizes don't match size1[" + size1 + "] != size2 [" + size2 + "] "); return false; } Iterator it1 = mcTable1.keySet().iterator(); while (it1.hasNext()) { String key1 = (String) it1.next(); MessageContext mc1 = (MessageContext) mcTable1.get(key1); MessageContext mc2 = (MessageContext) mcTable2.get(key1); if ((mc1 != null) && (mc2 != null)) { // check the IDs String id1 = mc1.getMessageID(); String id2 = mc2.getMessageID(); if ((id1 != null) && (id2 != null)) { if (!id1.equals(id2)) { log.debug(title + " Return FALSE: message IDs don't match id1[" + id1 + "] != id2 [" + id2 + "] "); return false; } } else if ((id1 == null) && (id2 == null)) { // can't tell, keep going } else { // mismatch log.debug(title + " Return FALSE: message IDs don't match id1[" + id1 + "] != id2 [" + id2 + "] "); return false; } } else if ((mc1 == null) && (mc2 == null)) { // entries match } else { // mismatch log.debug( title + " Return FALSE: message context objects don't match "); return false; } } log.debug(title + " Return TRUE: message context tables match"); return true; } else if (mcTable1.isEmpty() && mcTable2.isEmpty()) { log.debug(title + " Return TRUE: message context tables are both empty "); return true; } else { log.debug(title + " Return FALSE: message context tables mismatch"); return false; } } else if ((mcTable1 == null) && (mcTable2 == null)) { log.debug(title + " Return TRUE: message context tables are null"); return true; } else { log.debug(title + " Return FALSE: message context tables don't match"); return false; } } else if ((oc1 == null) && (oc2 == null)) { log.debug(title + " Return TRUE: operation context objects are null "); return true; } else { log.debug(title + " Return FALSE: operation context objects don't match "); return false; } } private void showMCTable(OperationContext oc) { if (oc == null) { return; } HashMap mcTable = oc.getMessageContexts(); if ((mcTable == null) || (mcTable.isEmpty())) { return; } Iterator it = mcTable.keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); MessageContext mc = (MessageContext) mcTable.get(key); if (mc != null) { String id = mc.getMessageID(); log.debug("message context table entry: label [" + key + "] message ID [" + id + "] "); } } } /** * Gets the ID associated with the handler object. * * @param o The handler object * @return The ID associated with the handler, * -1 otherwise */ private int getHandlerID(Object o) { int id = -1; if (o instanceof TempHandler) { id = ((TempHandler) o).getHandlerID(); } return id; } //========================================================================= // Handler classes //========================================================================= /** * Pauses and saves the message context the message context */ public class SaveHandler extends AbstractHandler { private Integer handlerID = null; private File theFile = null; private String theFilename = null; private boolean performSave = true; private boolean savedOk = false; //----------------------------------------------------------------- // constructors //----------------------------------------------------------------- public SaveHandler() { this.handlerID = new Integer(-5); } public SaveHandler(int index, File saveFile, boolean doIt) { this.handlerID = new Integer(index); init(new HandlerDescription(new String("handler" + index))); theFile = saveFile; performSave = doIt; } //----------------------------------------------------------------- // methods //----------------------------------------------------------------- public int getHandlerID() { if (handlerID != null) { return handlerID.intValue(); } return -5; } public InvocationResponse invoke(MessageContext msgContext) throws AxisFault { String title = "SaveHandler[" + getHandlerID() + "]:invoke(): "; savedOk = false; if (performSave == false) { log.debug(title + "Configured for no action to be performed."); return InvocationResponse.CONTINUE; } log.debug(title + "msgContext.pause()"); msgContext.pause(); if (theFile != null) { try { log.debug(title + "Resetting the file to use."); theFile.delete(); theFile.createNewFile(); theFilename = theFile.getName(); log.debug(title + "temp file = [" + theFilename + "]"); } catch (Exception ex) { log.debug(title + "error creating new file = [" + ex.getMessage() + "]"); } if (theFile.exists() == true) { // --------------------------------------------------------- // save to the temporary file // --------------------------------------------------------- try { // setup an output stream to a physical file FileOutputStream outStream = new FileOutputStream(theFile); // attach a stream capable of writing objects to the // stream connected to the file ObjectOutputStream outObjStream = new ObjectOutputStream(outStream); // try to save the message context log.debug(title + "saving message context....."); savedOk = false; outObjStream.writeObject(msgContext); // close out the streams outObjStream.flush(); outObjStream.close(); outStream.flush(); outStream.close(); savedOk = true; log.debug(title + "....saved message context....."); long filesize = theFile.length(); log.debug(title + "file size after save [" + filesize + "] temp file = [" + theFilename + "]"); } catch (Exception ex2) { log.debug(title + "error with saving message context = [" + ex2.getClass().getName() + " : " + ex2.getMessage() + "]"); ex2.printStackTrace(); } assertTrue(savedOk); } } log.debug(title + "executedHandlers.add(" + handlerID + ")"); executedHandlers.add(handlerID); return InvocationResponse.SUSPEND; } } public class TempHandler extends AbstractHandler { private Integer handlerID = null; private int count = 0; private int numberProperties = 3; private String propertyKey = "Property"; private String propertyValue = "ServiceLevelSetting"; //----------------------------------------------------------------- // constructors //----------------------------------------------------------------- public TempHandler() { this.handlerID = new Integer(-5); } public TempHandler(int index) { this.handlerID = new Integer(index); init(new HandlerDescription(new String("handler" + index))); } public TempHandler(int index, int number) { this.handlerID = new Integer(index); init(new HandlerDescription(new String("handler" + index))); numberProperties = number; } //----------------------------------------------------------------- // methods //----------------------------------------------------------------- public int getHandlerID() { if (handlerID != null) { return handlerID.intValue(); } return -5; } public InvocationResponse invoke(MessageContext msgContext) throws AxisFault { String title = "TempHandler[" + getHandlerID() + "]:invoke(): "; // get the service context from the message context ServiceContext serviceContext = msgContext.getServiceContext(); if (serviceContext == null) { // get the service context from the operation context OperationContext operationContext = msgContext.getOperationContext(); serviceContext = operationContext.getServiceContext(); } if (serviceContext != null) { for (int j = 0; j < numberProperties; j++) { count++; String key = new String(propertyKey + ".ID[" + getHandlerID() + "]." + count); String value = new String(propertyValue + "[" + count + "]"); serviceContext.setProperty(key, value); } } log.debug(title + "executedHandlers.add(" + handlerID + ")"); executedHandlers.add(handlerID); return InvocationResponse.CONTINUE; } } }