/* * 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.util; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSConsumer; import javax.jms.JMSContext; import javax.jms.JMSException; import javax.jms.JMSProducer; import javax.jms.JMSRuntimeException; import javax.jms.Message; import javax.jms.Queue; import javax.jms.Topic; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.management.QueueControl; import org.apache.activemq.artemis.core.config.Configuration; import org.apache.activemq.artemis.core.registry.JndiBindingRegistry; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.ActiveMQServers; import org.apache.activemq.artemis.jms.server.config.ConnectionFactoryConfiguration; import org.apache.activemq.artemis.jms.server.config.impl.ConnectionFactoryConfigurationImpl; import org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl; import org.apache.activemq.artemis.service.extensions.ServiceUtils; import org.apache.activemq.artemis.tests.integration.ra.DummyTransactionManager; import org.apache.activemq.artemis.tests.unit.util.InVMNamingContext; import org.junit.After; import org.junit.Assert; import org.junit.Before; public class JMSTestBase extends ActiveMQTestBase { protected ActiveMQServer server; protected JMSServerManagerImpl jmsServer; protected MBeanServer mbeanServer; protected ConnectionFactory cf; protected ConnectionFactory nettyCf; protected Connection conn; private final Set<JMSContext> contextSet = new HashSet<>(); private final Random random = new Random(); protected InVMNamingContext namingContext; protected boolean useSecurity() { return false; } protected boolean useJMX() { return true; } protected boolean usePersistence() { return false; } protected final JMSContext addContext(JMSContext context0) { contextSet.add(context0); return context0; } protected final JMSContext createContext() { return addContext(cf.createContext()); } protected final JMSContext createContext(int sessionMode) { return addContext(cf.createContext(null, null, sessionMode)); } /** * @throws Exception */ protected Queue createQueue(final String queueName) throws Exception { return createQueue(false, queueName); } protected Topic createTopic(final String topicName) throws Exception { return createTopic(false, topicName); } protected long getMessageCount(QueueControl control) throws Exception { control.flushExecutor(); return control.getMessageCount(); } /** * @throws Exception */ protected Queue createQueue(final boolean storeConfig, final String queueName) throws Exception { jmsServer.createQueue(storeConfig, queueName, null, true, "/jms/" + queueName); return (Queue) namingContext.lookup("/jms/" + queueName); } protected Topic createTopic(final boolean storeConfig, final String topicName) throws Exception { jmsServer.createTopic(storeConfig, topicName, "/jms/" + topicName); return (Topic) namingContext.lookup("/jms/" + topicName); } @Override @Before public void setUp() throws Exception { super.setUp(); mbeanServer = MBeanServerFactory.createMBeanServer(); Configuration config = createDefaultConfig(true).setSecurityEnabled(useSecurity()). addConnectorConfiguration("invm", new TransportConfiguration(INVM_CONNECTOR_FACTORY)). setTransactionTimeoutScanPeriod(100); config.getConnectorConfigurations().put("netty", new TransportConfiguration(NETTY_CONNECTOR_FACTORY)); server = addServer(ActiveMQServers.newActiveMQServer(config, mbeanServer, usePersistence())); jmsServer = new JMSServerManagerImpl(server); namingContext = new InVMNamingContext(); jmsServer.setRegistry(new JndiBindingRegistry(namingContext)); jmsServer.start(); registerConnectionFactory(); } @Override protected Configuration createDefaultConfig(boolean netty) throws Exception { return super.createDefaultConfig(netty).setJMXManagementEnabled(true); } protected void restartServer() throws Exception { namingContext = new InVMNamingContext(); jmsServer.setRegistry(new JndiBindingRegistry(namingContext)); jmsServer.start(); jmsServer.activated(); registerConnectionFactory(); } protected void killServer() throws Exception { jmsServer.stop(); } @Override @After public void tearDown() throws Exception { try { for (JMSContext jmsContext : contextSet) { jmsContext.close(); } } catch (RuntimeException ignored) { // no-op } finally { contextSet.clear(); } try { if (conn != null) conn.close(); } catch (Exception e) { // no-op } namingContext.close(); jmsServer.stop(); server = null; cf = null; jmsServer = null; namingContext = null; MBeanServerFactory.releaseMBeanServer(mbeanServer); mbeanServer = null; ServiceUtils.setTransactionManager(null); super.tearDown(); } protected void registerConnectionFactory() throws Exception { List<TransportConfiguration> connectorConfigs = new ArrayList<>(); connectorConfigs.add(new TransportConfiguration(INVM_CONNECTOR_FACTORY)); List<TransportConfiguration> connectorConfigs1 = new ArrayList<>(); connectorConfigs1.add(new TransportConfiguration(NETTY_CONNECTOR_FACTORY)); createCF(connectorConfigs, "/cf"); createCF("NettyCF", connectorConfigs1, "/nettyCf"); cf = (ConnectionFactory) namingContext.lookup("/cf"); nettyCf = (ConnectionFactory)namingContext.lookup("/nettyCf"); } protected void createCF(final List<TransportConfiguration> connectorConfigs, final String... jndiBindings) throws Exception { createCF(name.getMethodName(), connectorConfigs, jndiBindings); } /** * @param cfName the unique ConnectionFactory's name * @param connectorConfigs initial static connectors' config * @param jndiBindings JNDI binding names for the CF * @throws Exception */ protected void createCF(final String cfName, final List<TransportConfiguration> connectorConfigs, final String... jndiBindings) throws Exception { List<String> connectorNames = registerConnectors(server, connectorConfigs); ConnectionFactoryConfiguration configuration = new ConnectionFactoryConfigurationImpl().setName(cfName).setConnectorNames(connectorNames).setRetryInterval(1000).setReconnectAttempts(-1); testCaseCfExtraConfig(configuration); jmsServer.createConnectionFactory(false, configuration, jndiBindings); } /** * Allows test-cases to set their own options to the {@link ConnectionFactoryConfiguration} * * @param configuration */ protected void testCaseCfExtraConfig(ConnectionFactoryConfiguration configuration) { // no-op } protected final void sendMessages(JMSContext context, JMSProducer producer, Queue queue, final int total) { try { for (int j = 0; j < total; j++) { StringBuilder sb = new StringBuilder(); for (int m = 0; m < 200; m++) { sb.append(random.nextLong()); } Message msg = context.createTextMessage(sb.toString()); msg.setIntProperty("counter", j); producer.send(queue, msg); } } catch (JMSException cause) { throw new JMSRuntimeException(cause.getMessage(), cause.getErrorCode(), cause); } } protected void useDummyTransactionManager() { ServiceUtils.setTransactionManager(new DummyTransactionManager()); } protected final void receiveMessages(JMSConsumer consumer, final int start, final int msgCount, final boolean ack) { try { for (int i = start; i < msgCount; i++) { Message message = consumer.receive(100); Assert.assertNotNull("Expecting a message " + i, message); final int actual = message.getIntProperty("counter"); Assert.assertEquals("expected=" + i + ". Got: property['counter']=" + actual, i, actual); if (ack) message.acknowledge(); } } catch (JMSException cause) { throw new JMSRuntimeException(cause.getMessage(), cause.getErrorCode(), cause); } } }