/* * 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.common; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.client.ActiveMQClient; import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientRequestor; import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.api.core.management.ManagementHelper; import org.apache.activemq.artemis.api.core.management.ResourceNames; import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory; import org.apache.activemq.artemis.api.core.RoutingType; import org.apache.activemq.artemis.tests.util.SpawnedVMSupport; import org.objectweb.jtests.jms.admin.Admin; /** * AbstractAdmin. */ public class AbstractAdmin implements Admin { protected ClientSession clientSession; protected ClientRequestor requestor; protected boolean serverLifeCycleActive; protected Process serverProcess; protected ServerLocator serverLocator; protected ClientSessionFactory sf; // this is a constant to control if we should use a separate VM for the server. public static final boolean spawnServer = false; /** * Determines whether to act or 'no-op' on serverStart() and * serverStop(). This is used when testing combinations of client and * servers with different versions. */ private static final String SERVER_LIVE_CYCLE_PROPERTY = "org.apache.activemq.artemis.jms.ActiveMQAMQPAdmin.serverLifeCycle"; public AbstractAdmin() { serverLifeCycleActive = Boolean.valueOf(System.getProperty(SERVER_LIVE_CYCLE_PROPERTY, "true")); } @Override public String getName() { return getClass().getName(); } @Override public void start() throws Exception { serverLocator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName())); sf = serverLocator.createSessionFactory(); clientSession = sf.createSession(ActiveMQDefaultConfiguration.getDefaultClusterUser(), ActiveMQDefaultConfiguration.getDefaultClusterPassword(), false, true, true, false, 1); requestor = new ClientRequestor(clientSession, ActiveMQDefaultConfiguration.getDefaultManagementAddress()); clientSession.start(); } @Override public void stop() throws Exception { requestor.close(); if (sf != null) { sf.close(); } if (serverLocator != null) { serverLocator.close(); } sf = null; serverLocator = null; } @Override public Context createContext() throws NamingException { return new InitialContext(); } @Override public void createConnectionFactory(final String name) { throw new RuntimeException("FIXME NYI createConnectionFactory"); } @Override public void deleteConnectionFactory(final String name) { throw new RuntimeException("FIXME NYI deleteConnectionFactory"); } @Override public void createQueue(final String name) { Boolean result; try { invokeSyncOperation(ResourceNames.BROKER, "createQueue", name, RoutingType.ANYCAST.toString(), name, null, true, ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), true); } catch (Exception e) { throw new IllegalStateException(e); } } @Override public void deleteQueue(final String name) { Boolean result; try { invokeSyncOperation(ResourceNames.BROKER, "destroyQueue", name); } catch (Exception e) { throw new IllegalStateException(e); } } @Override public void createQueueConnectionFactory(final String name) { createConnectionFactory(name); } @Override public void deleteQueueConnectionFactory(final String name) { deleteConnectionFactory(name); } @Override public void createTopic(final String name) { try { invokeSyncOperation(ResourceNames.BROKER, "createAddress", name, "MULTICAST"); } catch (Exception e) { throw new IllegalStateException(e); } } @Override public void deleteTopic(final String name) { Boolean result; try { invokeSyncOperation(ResourceNames.BROKER, "deleteAddress", name); } catch (Exception e) { throw new IllegalStateException(e); } } @Override public void createTopicConnectionFactory(final String name) { createConnectionFactory(name); } @Override public void deleteTopicConnectionFactory(final String name) { deleteConnectionFactory(name); } @Override public void startServer() throws Exception { if (!serverLifeCycleActive) { return; } if (spawnServer) { String[] vmArgs = new String[]{}; serverProcess = SpawnedVMSupport.spawnVM(SpawnedJMSServer.class.getName(), vmArgs, false); InputStreamReader isr = new InputStreamReader(serverProcess.getInputStream()); final BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { System.out.println("SERVER: " + line); if ("OK".equals(line.trim())) { new Thread() { @Override public void run() { try { String line1 = null; while ((line1 = br.readLine()) != null) { System.out.println("SERVER: " + line1); } } catch (Exception e) { e.printStackTrace(); } } }.start(); return; } else if ("KO".equals(line.trim())) { // something went wrong with the server, destroy it: serverProcess.destroy(); throw new IllegalStateException("Unable to start the spawned server :" + line); } } } else { SpawnedJMSServer.startServer(); } } @Override public void stopServer() throws Exception { if (!serverLifeCycleActive) { return; } if (spawnServer) { OutputStreamWriter osw = new OutputStreamWriter(serverProcess.getOutputStream()); osw.write("STOP\n"); osw.flush(); int exitValue = serverProcess.waitFor(); if (exitValue != 0) { serverProcess.destroy(); } } else { SpawnedJMSServer.stopServer(); } } protected Object invokeSyncOperation(final String resourceName, final String operationName, final Object... parameters) throws Exception { ClientMessage message = clientSession.createMessage(false); ManagementHelper.putOperationInvocation(message, resourceName, operationName, parameters); ClientMessage reply; try { reply = requestor.request(message, 3000); } catch (Exception e) { throw new IllegalStateException("Exception while invoking " + operationName + " on " + resourceName, e); } if (reply == null) { throw new IllegalStateException("no reply received when invoking " + operationName + " on " + resourceName); } if (!ManagementHelper.hasOperationSucceeded(reply)) { throw new IllegalStateException("operation failed when invoking " + operationName + " on " + resourceName + ": " + ManagementHelper.getResult(reply)); } return ManagementHelper.getResult(reply); } }