/* * 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.activemq.artemis.tests.unit.ra; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.activemq.artemis.ra.ActiveMQResourceAdapter; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * This test is used to generate the commented out configs in the src/config/ra.xml. If you add a setter to the ActiveMQResourceAdapter * this test should fail, if it does paste the new commented out configs into the ra.xml file and in here. don't forget to * add a description for each new property added and try and put it in the config some where appropriate. */ public class ActiveMQResourceAdapterConfigTest extends ActiveMQTestBase { private static String config = "" + "<config-property>\n" + " <description>\n" + " The transport type. Multiple connectors can be configured by using a comma separated list,\n" + " i.e. org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory,org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory.\n" + " </description>\n" + " <config-property-name>ConnectorClassName</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value>org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The transport configuration. These values must be in the form of key=val;key=val;,\n" + " if multiple connectors are used then each set must be separated by a comma i.e. host=host1;port=61616,host=host2;port=61617.\n" + " Each set of params maps to the connector classname specified.\n" + " </description>\n" + " <config-property-name>ConnectionParameters</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value>server-id=0</config-property-value>\n" + " </config-property>"; private static String commentedOutConfigs = "" + " <config-property>\n" + " <description>Does we support HA</description>\n" + " <config-property-name>HA</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value>false</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>Use A local Transaction instead of XA?</description>\n" + " <config-property-name>UseLocalTx</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value>false</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The user name used to login to the JMS server</description>\n" + " <config-property-name>UserName</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The password used to login to the JMS server</description>\n" + " <config-property-name>Password</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The jndi params to use to look up the jms resources if local jndi is not to be used</description>\n" + " <config-property-name>JndiParams</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value>java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory;java.naming.provider.url=jnp://localhost:1199;java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The jndi entries to use to look up the connection factory</description>\n" + " <config-property-name>Entries</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value>[\"java://jmsXA\"]</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The discovery group address</description>\n" + " <config-property-name>DiscoveryLocalBindAddress</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The discovery group local bind address</description>\n" + " <config-property-name>DiscoveryAddress</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The discovery group port</description>\n" + " <config-property-name>DiscoveryPort</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The discovery refresh timeout</description>\n" + " <config-property-name>DiscoveryRefreshTimeout</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The discovery initial wait timeout</description>\n" + " <config-property-name>DiscoveryInitialWaitTimeout</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property> \n" + " <config-property>\n" + " <description>The class to use for load balancing connections</description>\n" + " <config-property-name>ConnectionLoadBalancingPolicyClassName</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>number of reconnect attempts for connections after failover occurs</description>\n" + " <config-property-name>ReconnectAttempts</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The client failure check period</description>\n" + " <config-property-name>ClientFailureCheckPeriod</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The connection TTL</description>\n" + " <config-property-name>ConnectionTTL</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The call timeout</description>\n" + " <config-property-name>CallTimeout</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The dups ok batch size</description>\n" + " <config-property-name>DupsOKBatchSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The transaction batch size</description>\n" + " <config-property-name>TransactionBatchSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The consumer window size</description>\n" + " <config-property-name>ConsumerWindowSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The consumer max rate</description>\n" + " <config-property-name>ConsumerMaxRate</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The confirmation window size</description>\n" + " <config-property-name>ConfirmationWindowSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The producer max rate</description>\n" + " <config-property-name>ProducerMaxRate</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The min large message size</description>\n" + " <config-property-name>MinLargeMessageSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The block on acknowledge</description>\n" + " <config-property-name>BlockOnAcknowledge</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The block on non durable send</description>\n" + " <config-property-name>BlockOnNonDurableSend</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The block on durable send</description>\n" + " <config-property-name>BlockOnDurableSend</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The auto group</description>\n" + " <config-property-name>AutoGroup</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The pre acknowledge</description>\n" + " <config-property-name>PreAcknowledge</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The retry interval</description>\n" + " <config-property-name>RetryInterval</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The retry interval multiplier</description>\n" + " <config-property-name>RetryIntervalMultiplier</config-property-name>\n" + " <config-property-type>java.lang.Double</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The client id</description>\n" + " <config-property-name>ClientID</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>use global pools for client</description>\n" + " <config-property-name>UseGlobalPools</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>max number of threads for scheduled thread pool</description>\n" + " <config-property-name>ScheduledThreadPoolMaxSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>max number of threads in pool</description>\n" + " <config-property-name>ThreadPoolMaxSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>whether to use jndi for looking up destinations etc</description>\n" + " <config-property-name>UseJNDI</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>how long in milliseconds to wait before retry on failed MDB setup</description>\n" + " <config-property-name>SetupInterval</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>How many attempts should be made when connecting the MDB</description>\n" + " <config-property-name>SetupAttempts</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>" + " <config-property>\n" + " <description>Add a new managed connection factory</description>\n" + " <config-property-name>ManagedConnectionFactory</config-property-name>\n" + " <config-property-type>org.apache.activemq.artemis.ra.ActiveMQRAManagedConnectionFactory</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>" + " <config-property>\n" + " <description>Whether to use password mask, default false</description>\n" + " <config-property-name>UseMaskedPassword</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value>false</config-property-value>\n" + " </config-property>" + " <config-property>\n" + " <description>The class definition (full qualified name and its properties) used to encrypt the password</description>\n" + " <config-property-name>PasswordCodec</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value>org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec;key=clusterpassword;algorithm=ssss</config-property-value>\n" + " </config-property>" + " <config-property>" + " <description>Whether the resource adapter must use auto recovery</description>\n" + " <config-property-name>UseAutoRecovery</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value>true</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The initial size for message packet</description>\n" + " <config-property-name>InitialMessagePacketSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value>1500</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>the Group ID</description>\n" + " <config-property-name>GroupID</config-property-name>\n" + " <config-property-type>java.lang.String</config-property-type>\n" + " <config-property-value></config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>Whether the resource adapter must failover on the initial connection</description>\n" + " <config-property-name>FailoverOnInitialConnection</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value>false</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>Whether the resource adapter compress large messages and send them as regular when possible</description>" + " <config-property-name>CompressLargeMessage</config-property-name>" + " <config-property-type>boolean</config-property-type>" + " <config-property-value>false</config-property-value>" + " </config-property>\n" + " <config-property>\n" + " <description>The timeout in milliseconds for failover call (or -1 for infinite)</description>\n" + " <config-property-name>CallFailoverTimeout</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value>-1</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The maximum interval (in milliseconds) between reconnection attempts</description>\n" + " <config-property-name>MaxRetryInterval</config-property-name>\n" + " <config-property-type>long</config-property-type>\n" + " <config-property-value>2000</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>Whether the resource adapter must cache large messages</description>\n" + " <config-property-name>CacheLargeMessagesClient</config-property-name>\n" + " <config-property-type>boolean</config-property-type>\n" + " <config-property-value>false</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The producer window size (in bytes)</description>\n" + " <config-property-name>ProducerWindowSize</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value>65536</config-property-value>\n" + " </config-property>\n" + " <config-property>\n" + " <description>The number of attempts for the initial connection</description>\n" + " <config-property-name>InitialConnectAttempts</config-property-name>\n" + " <config-property-type>int</config-property-type>\n" + " <config-property-value>1</config-property-value>\n" + " </config-property>\n" + " <config-property>" + " <description>my-channel</description>" + " <config-property-name>JgroupsChannelName</config-property-name>" + " <config-property-type>java.lang.String</config-property-type>" + " <config-property-value></config-property-value>" + " </config-property>" + " <config-property>" + " <description>my-file</description>" + " <config-property-name>JgroupsFile</config-property-name>" + " <config-property-type>java.lang.String</config-property-type>" + " <config-property-value></config-property-value>" + " </config-property>" + " <config-property>" + " <description>Jgroups Channel Locator Class</description>" + " <config-property-name>JgroupsChannelLocatorClass</config-property-name>" + " <config-property-type>java.lang.String</config-property-type>" + " <config-property-value></config-property-value>" + " </config-property>" + " <config-property>" + " <description>Name to locate a JChannel by JGroups Channel locator class</description>" + " <config-property-name>JgroupsChannelRefName</config-property-name>" + " <config-property-type>java.lang.String</config-property-type>" + " <config-property-value></config-property-value>" + " </config-property>" + " <config-property>" + " <description>ProtocolManagerConfig</description>" + " <config-property-name>ProtocolManagerFactoryStr</config-property-name>" + " <config-property-type>java.lang.String</config-property-type>" + " <config-property-value></config-property-value>" + " </config-property>" + " <config-property>" + " <description>List of package/class names against which matching objects are permitted to be deserialized</description>" + " <config-property-name>DeserializationWhiteList</config-property-name>" + " <config-property-type>java.lang.String</config-property-type>" + " <config-property-value></config-property-value>" + " </config-property>" + " <config-property>" + " <description>List of package/class names against which matching objects are forbidden to be deserialized</description>" + " <config-property-name>DeserializationBlackList</config-property-name>" + " <config-property-type>java.lang.String</config-property-type>" + " <config-property-value></config-property-value>" + " </config-property>"; private static String rootConfig = "<root>" + config + commentedOutConfigs + "</root>"; @Test public void testConfiguration() throws Exception { Method[] methods = ActiveMQResourceAdapter.class.getMethods(); Map<String, Method> methodList = new HashMap<>(); for (Method method : methods) { if (method.getName().startsWith("set")) { methodList.put(method.getName(), method); } } DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputStream io = new ByteArrayInputStream(rootConfig.getBytes()); Document dom = db.parse(new InputSource(io)); Element docEle = dom.getDocumentElement(); NodeList nl = docEle.getElementsByTagName("config-property"); for (int i = 0; i < nl.getLength(); i++) { Element el = (Element) nl.item(i); NodeList elementsByTagName = el.getElementsByTagName("config-property-name"); assertEquals(el.toString(), elementsByTagName.getLength(), 1); Node configPropertyNameNode = elementsByTagName.item(0); String configPropertyName = configPropertyNameNode.getTextContent(); System.out.println("configPropertyName = " + configPropertyName); Method setter = methodList.remove("set" + configPropertyName); assertNotNull("setter " + configPropertyName + " does not exist", setter); Class c = lookupType(setter); elementsByTagName = el.getElementsByTagName("config-property-type"); assertEquals("setter " + configPropertyName + " has no type set", elementsByTagName.getLength(), 1); Node configPropertyTypeNode = elementsByTagName.item(0); String configPropertyTypeName = configPropertyTypeNode.getTextContent(); assertEquals(configPropertyTypeName, c.getName()); } if (!methodList.isEmpty()) { StringBuffer newConfig = new StringBuffer(commentedOutConfigs); newConfig.append("\n"); for (Method method : methodList.values()) { newConfig.append(" \" <config-property>\" + \n"); newConfig.append(" \" <description>***add***</description>\" + \n"); newConfig.append(" \" <config-property-name>").append(method.getName().substring(3)).append("</config-property-name>\" + \n"); newConfig.append(" \" <config-property-type>").append(lookupType(method).getName()).append("</config-property-type>\" + \n"); newConfig.append(" \" <config-property-value></config-property-value>\" + \n"); newConfig.append(" \" </config-property>\" + \n"); } System.out.println(newConfig); fail("methods not shown please see previous and add"); } else { System.out.println(commentedOutConfigs); } } /** * @param setter * @return */ private Class<?> lookupType(Method setter) { Class<?> clzz = setter.getParameterTypes()[0]; if (clzz == Boolean.class) { return Boolean.TYPE; } else if (clzz == Long.class) { return Long.TYPE; } else if (clzz == Integer.class) { return Integer.TYPE; } else { return clzz; } } }