diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/util/DestinationsPlugin.java b/activemq-broker/src/main/java/org/apache/activemq/broker/util/DestinationsPlugin.java new file mode 100644 index 0000000000..c61172821d --- /dev/null +++ b/activemq-broker/src/main/java/org/apache/activemq/broker/util/DestinationsPlugin.java @@ -0,0 +1,119 @@ +/** + * 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.broker.util; + +import org.apache.activemq.broker.Broker; +import org.apache.activemq.broker.BrokerPluginSupport; +import org.apache.activemq.broker.ConnectionContext; +import org.apache.activemq.broker.region.Destination; +import org.apache.activemq.command.ActiveMQDestination; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.util.Arrays; +import java.util.HashSet; + +/** + * + * A simple plugin that can be used to export/import runtime destinations. It's useful in security constrained + * environments where you want to create destinations only through the management APIs and be able to + * replicate them to another broker + * + * @org.apache.xbean.XBean element="destinationsPlugin" + */ +public class DestinationsPlugin extends BrokerPluginSupport { + private static Logger LOG = LoggerFactory.getLogger(DestinationsPlugin.class); + HashSet destinations = new HashSet(); + File location; + + @Override + public Destination addDestination(ConnectionContext context, ActiveMQDestination destination, boolean createIfTemporary) throws Exception { + destinations.add(destination); + return super.addDestination(context, destination, createIfTemporary); + } + + @Override + public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception { + super.removeDestination(context, destination, timeout); + destinations.remove(destination); + } + + @Override + public void start() throws Exception { + super.start(); + if (location == null) { + location = new File(getBrokerService().getBrokerDataDirectory(), "destinations"); + } + importDestinations(); + destinations.addAll(Arrays.asList(getBrokerService().getBroker().getDestinations())); + } + + @Override + public void stop() throws Exception { + super.stop(); + exportDestinations(); + } + + protected void importDestinations() throws Exception { + BufferedReader reader = null; + try { + if (location.exists()) { + reader = new BufferedReader(new FileReader(location)); + String destination; + Broker broker = getBrokerService().getBroker(); + while ((destination = reader.readLine()) != null) { + broker.addDestination(getBrokerService().getAdminConnectionContext(), + ActiveMQDestination.createDestination(destination, ActiveMQDestination.QUEUE_TYPE), + true); + } + } + } catch (Exception e) { + LOG.warn("Exception loading destinations", e); + } finally { + if (reader != null) { + reader.close(); + } + } + } + + protected void exportDestinations() throws Exception { + PrintWriter pw = null; + try { + location.getParentFile().mkdirs(); + FileOutputStream fos = new FileOutputStream(location); + pw = new PrintWriter(fos); + for (ActiveMQDestination destination : destinations) { + pw.println(destination); + } + } catch (Exception e) { + LOG.warn("Exception saving destinations", e); + } finally { + if (pw != null) { + pw.close(); + } + } + } + + public File getLocation() { + return location; + } + + public void setLocation(File location) { + this.location = location; + } +} diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/util/DestinationsPluginTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/util/DestinationsPluginTest.java new file mode 100644 index 0000000000..42a0e619a1 --- /dev/null +++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/util/DestinationsPluginTest.java @@ -0,0 +1,80 @@ +/** + * 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.broker.util; + + +import org.apache.activemq.broker.BrokerPlugin; +import org.apache.activemq.broker.BrokerService; +import org.apache.activemq.broker.jmx.BrokerView; +import org.apache.activemq.command.ActiveMQDestination; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + + +public class DestinationsPluginTest { + + BrokerService broker; + + @Before + public void setUp() throws Exception { + broker = createBroker(); + broker.start(); + broker.waitUntilStarted(); + } + + @After + public void shutdown() throws Exception { + broker.stop(); + broker.waitUntilStopped(); + } + + protected BrokerService createBroker() { + BrokerService broker = new BrokerService(); + broker.setPersistent(false); + broker.setUseJmx(true); + broker.setPlugins(new BrokerPlugin[]{new DestinationsPlugin()}); + broker.setDataDirectory("target/test"); + return broker; + } + + @Test + public void testDestinationSave() throws Exception { + + BrokerView brokerView = broker.getAdminView(); + brokerView.addQueue("test-queue"); + + broker.stop(); + broker.waitUntilStopped(); + + broker = createBroker(); + broker.start(); + broker.waitUntilStarted(); + + + ActiveMQDestination[] destinations = broker.getRegionBroker().getDestinations(); + for (ActiveMQDestination destination : destinations) { + if (destination.isQueue()) { + assertEquals("test-queue", destination.getPhysicalName()); + } + } + + } + +}