001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.broker.util;
018
019import org.apache.activemq.broker.Broker;
020import org.apache.activemq.broker.BrokerPluginSupport;
021import org.apache.activemq.broker.ConnectionContext;
022import org.apache.activemq.broker.region.Destination;
023import org.apache.activemq.command.ActiveMQDestination;
024import org.slf4j.Logger;
025import org.slf4j.LoggerFactory;
026
027import java.io.*;
028import java.util.Arrays;
029import java.util.HashSet;
030
031/**
032 *
033 * A simple plugin that can be used to export/import runtime destinations. It's useful in security constrained
034 * environments where you want to create destinations only through the management APIs and be able to
035 * replicate them to another broker
036 *
037 * @org.apache.xbean.XBean element="destinationsPlugin"
038 */
039public class DestinationsPlugin extends BrokerPluginSupport {
040    private static Logger LOG = LoggerFactory.getLogger(DestinationsPlugin.class);
041    HashSet<ActiveMQDestination> destinations = new HashSet<ActiveMQDestination>();
042    File location;
043
044    @Override
045    public Destination addDestination(ConnectionContext context, ActiveMQDestination destination, boolean createIfTemporary) throws Exception {
046        destinations.add(destination);
047        return super.addDestination(context, destination, createIfTemporary);
048    }
049
050    @Override
051    public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
052        super.removeDestination(context, destination, timeout);
053        destinations.remove(destination);
054    }
055
056    @Override
057    public void start() throws Exception {
058        super.start();
059        if (location == null) {
060            location = new File(getBrokerService().getBrokerDataDirectory(), "destinations");
061        }
062        importDestinations();
063        destinations.addAll(Arrays.asList(getBrokerService().getBroker().getDestinations()));
064    }
065
066    @Override
067    public void stop() throws Exception {
068        super.stop();
069        exportDestinations();
070    }
071
072    protected void importDestinations() throws Exception {
073        BufferedReader reader = null;
074        try {
075            if (location.exists()) {
076                reader = new BufferedReader(new FileReader(location));
077                String destination;
078                Broker broker = getBrokerService().getBroker();
079                while ((destination = reader.readLine()) != null) {
080                    broker.addDestination(getBrokerService().getAdminConnectionContext(),
081                            ActiveMQDestination.createDestination(destination, ActiveMQDestination.QUEUE_TYPE),
082                            true);
083                }
084            }
085        } catch (Exception e) {
086            LOG.warn("Exception loading destinations", e);
087        }  finally {
088            if (reader != null) {
089                reader.close();
090            }
091        }
092    }
093
094    protected void exportDestinations() throws Exception {
095        PrintWriter pw = null;
096        try {
097            location.getParentFile().mkdirs();
098            FileOutputStream fos = new FileOutputStream(location);
099            pw = new PrintWriter(fos);
100            for (ActiveMQDestination destination : destinations) {
101                pw.println(destination);
102            }
103        } catch (Exception e) {
104            LOG.warn("Exception saving destinations", e);
105        } finally {
106            if (pw != null) {
107                pw.close();
108            }
109        }
110    }
111
112    public File getLocation() {
113        return location;
114    }
115
116    public void setLocation(File location) {
117        this.location = location;
118    }
119}