/* * 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.integration.jms.connection; import java.beans.PropertyDescriptor; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration; import org.apache.activemq.artemis.api.core.JGroupsFileBroadcastEndpointFactory; import org.apache.activemq.artemis.api.core.JGroupsPropertiesBroadcastEndpointFactory; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.UDPBroadcastEndpointFactory; import org.apache.activemq.artemis.api.jms.JMSFactoryType; import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.activemq.artemis.jms.server.config.ConnectionFactoryConfiguration; import org.apache.activemq.artemis.jms.server.config.impl.ConnectionFactoryConfigurationImpl; import org.apache.activemq.artemis.tests.util.JMSTestBase; import org.apache.activemq.artemis.utils.RandomUtil; import org.apache.commons.beanutils.BeanUtilsBean; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ConnectionFactorySerializationTest extends JMSTestBase { // Constants ----------------------------------------------------- // Static -------------------------------------------------------- // Attributes ---------------------------------------------------- protected static ActiveMQConnectionFactory cf; // Constructors -------------------------------------------------- @Override @Before public void setUp() throws Exception { super.setUp(); } // Public -------------------------------------------------------- @Test public void testConnectionFactoryUDP() throws Exception { createDiscoveryFactoryUDP(); cf = (ActiveMQConnectionFactory) namingContext.lookup("/MyConnectionFactory"); // apparently looking up the connection factory with the org.apache.activemq.artemis.jms.tests.tools.container.InVMInitialContextFactory // is not enough to actually serialize it so we serialize it manually byte[] x = serialize(cf); ActiveMQConnectionFactory y = deserialize(x, ActiveMQConnectionFactory.class); checkEquals(cf, y); DiscoveryGroupConfiguration dgc = y.getDiscoveryGroupConfiguration(); Assert.assertEquals(dgc.getName(), "dg1"); Assert.assertEquals(dgc.getDiscoveryInitialWaitTimeout(), 5000); Assert.assertEquals(dgc.getRefreshTimeout(), 5000); Assert.assertTrue(dgc.getBroadcastEndpointFactory() instanceof UDPBroadcastEndpointFactory); UDPBroadcastEndpointFactory befc = (UDPBroadcastEndpointFactory) dgc.getBroadcastEndpointFactory(); Assert.assertEquals(Integer.parseInt(System.getProperty("org.apache.activemq.artemis.api.core.UDPBroadcastEndpointFactory.localBindPort", "-1")), befc.getLocalBindPort()); Assert.assertEquals(System.getProperty("org.apache.activemq.artemis.api.core.UDPBroadcastEndpointFactory.localBindAddress"), befc.getLocalBindAddress()); Assert.assertEquals(getUDPDiscoveryPort(), befc.getGroupPort()); Assert.assertEquals(getUDPDiscoveryAddress(), befc.getGroupAddress()); } @Test public void testConnectionFactoryJgroupsFile() throws Exception { createDiscoveryFactoryJGroupsFile(); cf = (ActiveMQConnectionFactory) namingContext.lookup("/MyConnectionFactory"); // apparently looking up the connection factory with the org.apache.activemq.artemis.jms.tests.tools.container.InVMInitialContextFactory // is not enough to actually serialize it so we serialize it manually byte[] x = serialize(cf); ActiveMQConnectionFactory y = deserialize(x, ActiveMQConnectionFactory.class); checkEquals(cf, y); DiscoveryGroupConfiguration dgc = y.getDiscoveryGroupConfiguration(); Assert.assertEquals(dgc.getName(), "dg1"); Assert.assertEquals(dgc.getDiscoveryInitialWaitTimeout(), 5000); Assert.assertEquals(dgc.getRefreshTimeout(), 5000); Assert.assertTrue(dgc.getBroadcastEndpointFactory() instanceof JGroupsFileBroadcastEndpointFactory); JGroupsFileBroadcastEndpointFactory befc = (JGroupsFileBroadcastEndpointFactory) dgc.getBroadcastEndpointFactory(); Assert.assertEquals("myChannel", befc.getChannelName()); Assert.assertEquals("/META-INF/myfile.xml", befc.getFile()); } @Test public void testConnectionFactoryJgroupsProperties() throws Exception { createDiscoveryFactoryJGroupsProperties(); cf = (ActiveMQConnectionFactory) namingContext.lookup("/MyConnectionFactory"); // apparently looking up the connection factory with the org.apache.activemq.artemis.jms.tests.tools.container.InVMInitialContextFactory // is not enough to actually serialize it so we serialize it manually byte[] x = serialize(cf); ActiveMQConnectionFactory y = deserialize(x, ActiveMQConnectionFactory.class); checkEquals(cf, y); DiscoveryGroupConfiguration dgc = y.getDiscoveryGroupConfiguration(); Assert.assertEquals(dgc.getName(), "dg1"); Assert.assertEquals(dgc.getDiscoveryInitialWaitTimeout(), 5000); Assert.assertEquals(dgc.getRefreshTimeout(), 5000); Assert.assertTrue(dgc.getBroadcastEndpointFactory() instanceof JGroupsPropertiesBroadcastEndpointFactory); JGroupsPropertiesBroadcastEndpointFactory befc = (JGroupsPropertiesBroadcastEndpointFactory) dgc.getBroadcastEndpointFactory(); Assert.assertEquals("myChannel", befc.getChannelName()); Assert.assertEquals("param=1,param2=2", befc.getProperties()); } @Test public void testConnectionFactoryStatic1() throws Exception { createStaticFactory(true); cf = (ActiveMQConnectionFactory) namingContext.lookup("/MyConnectionFactory"); // apparently looking up the connection factory with the org.apache.activemq.artemis.jms.tests.tools.container.InVMInitialContextFactory // is not enough to actually serialize it so we serialize it manually byte[] x = serialize(cf); ActiveMQConnectionFactory y = deserialize(x, ActiveMQConnectionFactory.class); checkEquals(cf, y); Assert.assertEquals(cf.isHA(), y.isHA()); TransportConfiguration[] staticConnectors = y.getStaticConnectors(); Assert.assertEquals(staticConnectors.length, 2); TransportConfiguration tc0 = cf.getStaticConnectors()[0]; TransportConfiguration y0 = y.getStaticConnectors()[0]; Map<String, Object> ctParams = tc0.getParams(); Map<String, Object> y0Params = y0.getParams(); Assert.assertEquals(ctParams.size(), y0Params.size()); for (String key : y0Params.keySet()) { Assert.assertEquals(ctParams.get(key), y0Params.get(key)); } } private void createDiscoveryFactoryUDP() throws Exception { // Deploy a connection factory with discovery List<String> bindings = new ArrayList<>(); bindings.add("MyConnectionFactory"); final String groupAddress = getUDPDiscoveryAddress(); final int port = getUDPDiscoveryPort(); String localBindAddress = getLocalHost().getHostAddress(); UDPBroadcastEndpointFactory config = new UDPBroadcastEndpointFactory().setGroupAddress(groupAddress).setGroupPort(port).setLocalBindAddress(localBindAddress).setLocalBindPort(8580); DiscoveryGroupConfiguration dcConfig = new DiscoveryGroupConfiguration().setName("dg1").setRefreshTimeout(5000).setDiscoveryInitialWaitTimeout(5000).setBroadcastEndpointFactory(config); jmsServer.getActiveMQServer().getConfiguration().getDiscoveryGroupConfigurations().put(dcConfig.getName(), dcConfig); jmsServer.createConnectionFactory("MyConnectionFactory", false, JMSFactoryType.CF, dcConfig.getName(), "/MyConnectionFactory"); } private void createDiscoveryFactoryJGroupsFile() throws Exception { // Deploy a connection factory with discovery List<String> bindings = new ArrayList<>(); bindings.add("MyConnectionFactory"); JGroupsFileBroadcastEndpointFactory config = new JGroupsFileBroadcastEndpointFactory().setChannelName("myChannel").setFile("/META-INF/myfile.xml"); DiscoveryGroupConfiguration dcConfig = new DiscoveryGroupConfiguration().setName("dg1").setRefreshTimeout(5000).setDiscoveryInitialWaitTimeout(5000).setBroadcastEndpointFactory(config); jmsServer.getActiveMQServer().getConfiguration().getDiscoveryGroupConfigurations().put(dcConfig.getName(), dcConfig); jmsServer.createConnectionFactory("MyConnectionFactory", false, JMSFactoryType.CF, dcConfig.getName(), "/MyConnectionFactory"); } private void createDiscoveryFactoryJGroupsProperties() throws Exception { // Deploy a connection factory with discovery List<String> bindings = new ArrayList<>(); bindings.add("MyConnectionFactory"); JGroupsPropertiesBroadcastEndpointFactory config = new JGroupsPropertiesBroadcastEndpointFactory().setChannelName("myChannel").setProperties("param=1,param2=2"); DiscoveryGroupConfiguration dcConfig = new DiscoveryGroupConfiguration().setName("dg1").setRefreshTimeout(5000).setDiscoveryInitialWaitTimeout(5000).setBroadcastEndpointFactory(config); jmsServer.getActiveMQServer().getConfiguration().getDiscoveryGroupConfigurations().put(dcConfig.getName(), dcConfig); jmsServer.createConnectionFactory("MyConnectionFactory", false, JMSFactoryType.CF, dcConfig.getName(), "/MyConnectionFactory"); } private void createStaticFactory(boolean b) throws Exception { HashMap<String, Object> params = new HashMap<>(); Set<String> allowableConnectorKeys = TransportConstants.ALLOWABLE_CONNECTOR_KEYS; for (String allowableConnectorKey : allowableConnectorKeys) { String value = RandomUtil.randomString(); params.put(allowableConnectorKey, value); } params.put("host", "localhost0"); params.put("port", "1234"); TransportConfiguration main = new TransportConfiguration(NETTY_CONNECTOR_FACTORY, params); jmsServer.getActiveMQServer().getConfiguration().getConnectorConfigurations().put(main.getName(), main); HashMap<String, Object> params2 = new HashMap<>(); for (String allowableConnectorKey : allowableConnectorKeys) { String value = RandomUtil.randomString(); params2.put(allowableConnectorKey, value); } params2.put("host", "localhost1"); params2.put("port", "5678"); TransportConfiguration main2 = new TransportConfiguration(NETTY_CONNECTOR_FACTORY, params2); jmsServer.getActiveMQServer().getConfiguration().getConnectorConfigurations().put(main2.getName(), main2); ArrayList<String> connectorNames = new ArrayList<>(); connectorNames.add(main.getName()); connectorNames.add(main2.getName()); ConnectionFactoryConfiguration configuration = new ConnectionFactoryConfigurationImpl().setName("MyConnectionFactory").setHA(b).setConnectorNames(connectorNames).setClientID("clientID").setClientFailureCheckPeriod(-1).setConnectionTTL(-2).setFactoryType(JMSFactoryType.CF).setCallTimeout(-3).setCallFailoverTimeout(-4).setCacheLargeMessagesClient(b).setMinLargeMessageSize(-5).setConsumerWindowSize(-6).setConsumerMaxRate(-7).setConfirmationWindowSize(-8).setProducerWindowSize(-9).setProducerMaxRate(-10).setBlockOnAcknowledge(b).setBlockOnDurableSend(b).setBlockOnNonDurableSend(b).setAutoGroup(b).setPreAcknowledge(b).setLoadBalancingPolicyClassName("foobar").setTransactionBatchSize(-11).setDupsOKBatchSize(-12).setUseGlobalPools(b).setScheduledThreadPoolMaxSize(-13).setThreadPoolMaxSize(-14).setRetryInterval(-15).setRetryIntervalMultiplier(-16).setMaxRetryInterval(-17).setReconnectAttempts(-18).setFailoverOnInitialConnection(b).setGroupID("groupID"); jmsServer.createConnectionFactory(false, configuration, "/MyConnectionFactory"); } private void populate(StringBuilder sb, BeanUtilsBean bean, ActiveMQConnectionFactory factory) throws IllegalAccessException, InvocationTargetException { PropertyDescriptor[] descriptors = bean.getPropertyUtils().getPropertyDescriptors(factory); for (PropertyDescriptor descriptor : descriptors) { if (descriptor.getWriteMethod() != null && descriptor.getReadMethod() != null) { if (descriptor.getPropertyType() == String.class) { String value = RandomUtil.randomString(); bean.setProperty(factory, descriptor.getName(), value); sb.append("&").append(descriptor.getName()).append("=").append(value); } else if (descriptor.getPropertyType() == int.class) { int value = RandomUtil.randomPositiveInt(); bean.setProperty(factory, descriptor.getName(), value); sb.append("&").append(descriptor.getName()).append("=").append(value); } else if (descriptor.getPropertyType() == long.class) { long value = RandomUtil.randomPositiveLong(); bean.setProperty(factory, descriptor.getName(), value); sb.append("&").append(descriptor.getName()).append("=").append(value); } else if (descriptor.getPropertyType() == double.class) { double value = RandomUtil.randomDouble(); bean.setProperty(factory, descriptor.getName(), value); sb.append("&").append(descriptor.getName()).append("=").append(value); } } } } private static void checkEquals(Object factory, Object factory2) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { BeanUtilsBean bean = new BeanUtilsBean(); PropertyDescriptor[] descriptors = bean.getPropertyUtils().getPropertyDescriptors(factory); for (PropertyDescriptor descriptor : descriptors) { if (descriptor.getWriteMethod() != null && descriptor.getReadMethod() != null) { Assert.assertEquals(descriptor.getName() + " incorrect", bean.getProperty(factory, descriptor.getName()), bean.getProperty(factory2, descriptor.getName())); } } } private static <T extends Serializable> byte[] serialize(T obj) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); oos.close(); return baos.toByteArray(); } private static <T extends Serializable> T deserialize(byte[] b, Class<T> cl) throws IOException, ClassNotFoundException { ByteArrayInputStream bais = new ByteArrayInputStream(b); ObjectInputStream ois = new ObjectInputStream(bais); Object o = ois.readObject(); return cl.cast(o); } // Package protected --------------------------------------------- // Protected ----------------------------------------------------- protected static InetAddress getLocalHost() throws UnknownHostException { InetAddress addr; try { addr = InetAddress.getLocalHost(); } catch (ArrayIndexOutOfBoundsException e) { //this is workaround for mac osx bug see AS7-3223 and JGRP-1404 addr = InetAddress.getByName(null); } return addr; } // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- }