| /* |
| * 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.axis2.context.MessageContext; |
| |
| import java.lang.reflect.Field; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| public class MessageContextChangeTest extends TestCase { |
| private FieldDescription[] knownList = { |
| new FieldDescription("org.apache.commons.logging.Log", "log"), |
| new FieldDescription("java.lang.String", "logCorrelationID"), |
| new FieldDescription("java.lang.String", "logCorrelationIDString"), |
| new FieldDescription("java.lang.String", "myClassName"), |
| new FieldDescription("long", "serialVersionUID"), |
| new FieldDescription("int", "REVISION_2"), |
| new FieldDescription("int", "revisionID"), |
| new FieldDescription("java.lang.ThreadLocal", "currentMessageContext"), |
| new FieldDescription("org.apache.axis2.client.Options", "options"), |
| new FieldDescription("int", "IN_FLOW"), |
| new FieldDescription("int", "IN_FAULT_FLOW"), |
| new FieldDescription("int", "OUT_FLOW"), |
| new FieldDescription("int", "OUT_FAULT_FLOW"), |
| new FieldDescription("java.lang.String", "REMOTE_ADDR"), |
| new FieldDescription("java.lang.String", "TRANSPORT_ADDR"), |
| new FieldDescription("java.lang.String", "TRANSPORT_HEADERS"), |
| new FieldDescription("java.lang.String", "IN_MESSAGE_CONTEXT"), |
| new FieldDescription("org.apache.axiom.attachments.Attachments", "attachments"), |
| new FieldDescription("java.lang.String", "TRANSPORT_OUT"), |
| new FieldDescription("java.lang.String", "TRANSPORT_IN"), |
| new FieldDescription("java.lang.String", "CHARACTER_SET_ENCODING"), |
| new FieldDescription("java.lang.String", "UTF_8"), |
| new FieldDescription("java.lang.String", "UTF_16"), |
| new FieldDescription("java.lang.String", "TRANSPORT_SUCCEED"), |
| new FieldDescription("java.lang.String", "DEFAULT_CHAR_SET_ENCODING"), |
| new FieldDescription("int", "FLOW"), |
| new FieldDescription("java.lang.String", "CLIENT_API_NON_BLOCKING"), |
| new FieldDescription("java.lang.String", "DISABLE_ASYNC_CALLBACK_ON_TRANSPORT_ERROR"), |
| new FieldDescription("boolean", "processingFault"), |
| new FieldDescription("boolean", "paused"), |
| new FieldDescription("boolean", "outputWritten"), |
| new FieldDescription("boolean", "newThreadRequired"), |
| new FieldDescription("boolean", "isSOAP11"), |
| new FieldDescription("java.util.ArrayList", "executionChain"), |
| new FieldDescription("java.util.LinkedList", "executedPhases"), |
| new FieldDescription("boolean", "doingREST"), |
| new FieldDescription("boolean", "doingMTOM"), |
| new FieldDescription("boolean", "doingSwA"), |
| new FieldDescription("org.apache.axis2.description.AxisMessage", "axisMessage"), |
| new FieldDescription("org.apache.axis2.description.AxisOperation", "axisOperation"), |
| new FieldDescription("org.apache.axis2.description.AxisService", "axisService"), |
| new FieldDescription("org.apache.axis2.description.AxisServiceGroup", |
| "axisServiceGroup"), |
| new FieldDescription("org.apache.axis2.context.ConfigurationContext", |
| "configurationContext"), |
| new FieldDescription("int", "currentHandlerIndex"), |
| new FieldDescription("int", "currentPhaseIndex"), |
| new FieldDescription("org.apache.axiom.soap.SOAPEnvelope", "envelope"), |
| new FieldDescription("org.apache.axis2.context.OperationContext", "operationContext"), |
| new FieldDescription("boolean", "responseWritten"), |
| new FieldDescription("boolean", "serverSide"), |
| new FieldDescription("org.apache.axis2.context.ServiceContext", "serviceContext"), |
| new FieldDescription("java.lang.String", "serviceContextID"), |
| new FieldDescription("org.apache.axis2.context.ServiceGroupContext", |
| "serviceGroupContext"), |
| new FieldDescription("java.lang.String", "serviceGroupContextId"), |
| new FieldDescription("org.apache.axis2.context.SessionContext", "sessionContext"), |
| new FieldDescription("org.apache.axis2.description.TransportOutDescription", |
| "transportOut"), |
| new FieldDescription("org.apache.axis2.description.TransportInDescription", |
| "transportIn"), |
| new FieldDescription("java.lang.String", "incomingTransportName"), |
| new FieldDescription("java.util.LinkedHashMap", "selfManagedDataMap"), |
| new FieldDescription("boolean", "needsToBeReconciled"), |
| new FieldDescription("int", "selfManagedDataHandlerCount"), |
| new FieldDescription("java.util.ArrayList", "selfManagedDataListHolder"), |
| new FieldDescription("java.util.ArrayList", "metaExecutionChain"), |
| new FieldDescription("java.util.LinkedList", "metaExecuted"), |
| new FieldDescription("int", "metaHandlerIndex"), |
| new FieldDescription("int", "metaPhaseIndex"), |
| new FieldDescription("org.apache.axis2.util.MetaDataEntry", "metaAxisOperation"), |
| new FieldDescription("org.apache.axis2.util.MetaDataEntry", "metaAxisService"), |
| new FieldDescription("org.apache.axis2.util.MetaDataEntry", "metaAxisServiceGroup"), |
| new FieldDescription("org.apache.axis2.util.MetaDataEntry", "metaTransportOut"), |
| new FieldDescription("org.apache.axis2.util.MetaDataEntry", "metaTransportIn"), |
| new FieldDescription("org.apache.axis2.util.MetaDataEntry", "metaAxisMessage"), |
| new FieldDescription("boolean", "reconcileAxisMessage"), |
| new FieldDescription("boolean", "executedPhasesReset"), |
| new FieldDescription("java.lang.String", "selfManagedDataDelimiter"), |
| // new FieldDescription("java.lang.Class", |
| // new String[] {"class$org$apache$axis2$context$MessageContext","class$0"}), |
| // new FieldDescription("java.lang.Class", |
| // new String[] {"class$org$apache$axis2$context$SelfManagedDataManager","class$1"}), |
| new FieldDescription("java.lang.Exception", "failureReason"), |
| new FieldDescription("boolean", "DEBUG_ENABLED"), |
| }; |
| |
| |
| public MessageContextChangeTest(String arg0) { |
| super(arg0); |
| } |
| |
| |
| public void testChange() throws Exception { |
| StringBuilder messages = new StringBuilder(); |
| |
| MessageContext mc = new MessageContext(); |
| |
| Class mcClass = mc.getClass(); |
| |
| List<Field> fieldList = new ArrayList<>(); |
| for (Field field : mcClass.getDeclaredFields()) { |
| // Ignore fields added by instrumentation (such as JaCoCo) |
| if (!field.getName().startsWith("$")) { |
| fieldList.add(field); |
| } |
| } |
| Field[] fields = fieldList.toArray(new Field[fieldList.size()]); |
| |
| int numberFields = fields.length; |
| |
| int numberKnownFields = knownList.length; |
| |
| if (numberKnownFields != numberFields) { |
| messages.append("ERROR: number of actual fields [" + numberFields + |
| "] in MessageContext does not match the expected number [" + numberKnownFields + |
| "]\n"); |
| } |
| |
| // first check the expected fields with the actual fields |
| |
| for (int i = 0; i < numberKnownFields; i++) { |
| // see if this entry is in the actual list |
| String[] names = knownList[i].getNames(); |
| Field actualField = null; |
| for (int j = 0; actualField == null && j < names.length; j++) { |
| String name = names[j]; |
| actualField = findField(fields, name); |
| } |
| |
| if (actualField == null) { |
| messages.append("ERROR: MessageContext is missing field [" + Arrays.asList(names) + "]\n"); |
| } else { |
| String knownType = knownList[i].getType(); |
| String actualType = actualField.getType().getName(); |
| |
| if (!knownType.equals(actualType)) { |
| messages.append("ERROR: MessageContext field [" + Arrays.asList(names) + |
| "] expected type [" + knownType + "] does not match actual type [" + |
| actualType + "]\n"); |
| } |
| } |
| } |
| |
| // next, check the actual fields with the predefined, known fields |
| |
| for (int j = 0; j < numberFields; j++) { |
| String description = fields[j].toString(); |
| |
| // see if this entry is in the predefined list |
| String name = fields[j].getName(); |
| |
| FieldDescription fd = findFieldDescription(name); |
| |
| if (fd == null) { |
| messages.append("ERROR: MessageContext has new field [" + description + |
| "] that needs to be assessed for message context save/restore functions\n"); |
| } else { |
| String knownType = fd.getType(); |
| String actualType = fields[j].getType().getName(); |
| |
| if (!knownType.equals(actualType)) { |
| messages.append("ERROR: MessageContext field [" + name + |
| "] expected type [" + knownType + "] does not match actual type [" + |
| actualType + "]\n"); |
| } |
| } |
| |
| } |
| |
| if (messages.length() > 0) { |
| fail(messages.toString()); |
| } |
| } |
| |
| private Field findField(Field[] fields, String name) { |
| |
| //System.out.println("findField: looking for ["+name+"]"); |
| |
| for (int k = 0; k < fields.length; k++) { |
| String fieldName = fields[k].getName(); |
| //System.out.println("fieldName["+k+"] = ["+fieldName+"]"); |
| |
| if (fieldName.equals(name)) { |
| return fields[k]; |
| } |
| } |
| return null; |
| } |
| |
| private FieldDescription findFieldDescription(String name) { |
| for (int k = 0; k < knownList.length; k++) { |
| String[] fieldName = knownList[k].getNames(); |
| for (int i = 0; i < fieldName.length; i++) { |
| if (fieldName[i].equals(name)) { |
| return knownList[k]; |
| } |
| } |
| } |
| return null; |
| } |
| |
| |
| private class FieldDescription { |
| String type = null; |
| String[] name = null; |
| |
| // constructor |
| public FieldDescription() { |
| } |
| |
| // constructor |
| public FieldDescription(String t, String n) { |
| type = t; |
| name = new String[]{n}; |
| } |
| |
| // constructor |
| public FieldDescription(String t, String[] n) { |
| type = t; |
| name = n; |
| } |
| |
| public String getType() { |
| return type; |
| } |
| |
| public String[] getNames() { |
| return name; |
| } |
| |
| public void setType(String t) { |
| type = t; |
| } |
| } |
| |
| } |