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     */
017    
018    package org.apache.geronimo.activemq;
019    
020    import java.net.URI;
021    
022    import javax.sql.DataSource;
023    import javax.jms.JMSException;
024    
025    import org.apache.commons.logging.Log;
026    import org.apache.commons.logging.LogFactory;
027    
028    import org.apache.activemq.broker.BrokerFactory;
029    import org.apache.activemq.broker.BrokerService;
030    import org.apache.activemq.broker.jmx.ManagementContext;
031    import org.apache.activemq.store.DefaultPersistenceAdapterFactory;
032    import org.apache.activemq.transport.TransportDisposedIOException;
033    import org.apache.geronimo.connector.outbound.ConnectionFactorySource;
034    import org.apache.geronimo.gbean.GBeanInfo;
035    import org.apache.geronimo.gbean.GBeanInfoBuilder;
036    import org.apache.geronimo.gbean.GBeanLifecycle;
037    import org.apache.geronimo.management.geronimo.JMSManager;
038    import org.apache.geronimo.management.geronimo.NetworkConnector;
039    import org.apache.geronimo.system.jmx.MBeanServerReference;
040    import org.apache.geronimo.system.serverinfo.ServerInfo;
041    
042    /**
043     * Default implementation of the ActiveMQ Message Server
044     *
045     * @version $Rev: 556056 $ $Date: 2007-07-13 12:29:43 -0400 (Fri, 13 Jul 2007) $
046     */
047    public class BrokerServiceGBeanImpl implements GBeanLifecycle, BrokerServiceGBean {
048    
049        private Log log = LogFactory.getLog(getClass());
050    
051        private String brokerName;
052        private String brokerUri;
053        private BrokerService brokerService;
054        private ServerInfo serverInfo;
055        private String dataDirectory;
056        private ConnectionFactorySource dataSource;
057        private ClassLoader classLoader;
058        private String objectName;
059        private JMSManager manager;
060        private boolean useShutdownHook;
061        private MBeanServerReference mbeanServerReference;
062    
063        public BrokerServiceGBeanImpl() {
064        }
065    
066        public synchronized BrokerService getBrokerContainer() {
067            return brokerService;
068        }
069        
070        public void setMbeanServerReference(MBeanServerReference mbeanServerReference) {
071            this.mbeanServerReference = mbeanServerReference;
072        }
073    
074        public synchronized void doStart() throws Exception {
075            ClassLoader old = Thread.currentThread().getContextClassLoader();
076            Thread.currentThread().setContextClassLoader(getClassLoader());
077            try {
078                if (brokerService == null) {
079                    if (brokerUri != null) {
080                        brokerService = BrokerFactory.createBroker(new URI(brokerUri));
081                        brokerName = brokerService.getBrokerName();
082                    }
083                    else {
084                        brokerService = new BrokerService();
085                        if (brokerName != null) {
086                            brokerService.setBrokerName(brokerName);
087                        }
088                        else {
089                            brokerName = brokerService.getBrokerName();
090                        }
091                    }
092                }
093                
094                // Do not allow creation of another ConnectorServer
095                ManagementContext mgmtctx = new ManagementContext(mbeanServerReference != null ? mbeanServerReference.getMBeanServer() : null);
096                mgmtctx.setCreateConnector(false);
097                brokerService.setManagementContext(mgmtctx);
098    
099                // Do not allow the broker to use a shutown hook, the kernel will stop it
100                brokerService.setUseShutdownHook(isUseShutdownHook());
101    
102                // Setup the persistence adapter to use the right datasource and directory
103                DefaultPersistenceAdapterFactory persistenceFactory = (DefaultPersistenceAdapterFactory) brokerService.getPersistenceFactory();
104                persistenceFactory.setDataDirectoryFile(serverInfo.resolveServer(dataDirectory));
105                persistenceFactory.setDataSource((DataSource) dataSource.$getResource());
106    
107                brokerService.start();
108            }
109            finally {
110                Thread.currentThread().setContextClassLoader(old);
111            }
112        }
113    
114        public synchronized void doStop() throws Exception {
115            if (brokerService != null) {
116                BrokerService temp = brokerService;
117                brokerService = null;
118                try {
119                    temp.stop();
120                } catch (JMSException ignored) {
121                    // just a lame exception ActiveMQ likes to throw on shutdown
122                    if (!(ignored.getCause() instanceof TransportDisposedIOException)) {
123                        throw ignored;
124                    }
125                }
126            }
127        }
128    
129        public synchronized void doFail() {
130            if (brokerService != null) {
131                BrokerService temp = brokerService;
132                brokerService = null;
133                try {
134                    temp.stop();
135                } catch (JMSException ignored) {
136                    // just a lame exception ActiveMQ likes to throw on shutdown
137                    if (!(ignored.getCause() instanceof TransportDisposedIOException)) {
138                        log.warn("Caught while closing due to failure: " + ignored, ignored);
139                    }
140                } catch (Exception e) {
141                    log.warn("Caught while closing due to failure: " + e, e);
142                }
143            }
144        }
145    
146        public static final GBeanInfo GBEAN_INFO;
147    
148        static {
149            GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder("ActiveMQ Message Broker", BrokerServiceGBeanImpl.class, "JMSServer");
150            infoBuilder.addReference("serverInfo", ServerInfo.class);
151            infoBuilder.addReference("mbeanServerReference", MBeanServerReference.class);
152            infoBuilder.addAttribute("classLoader", ClassLoader.class, false);
153            infoBuilder.addAttribute("brokerName", String.class, true);
154            infoBuilder.addAttribute("brokerUri", String.class, true);
155            infoBuilder.addAttribute("useShutdownHook", Boolean.TYPE, true);
156            infoBuilder.addAttribute("dataDirectory", String.class, true);
157            infoBuilder.addReference("dataSource", ConnectionFactorySource.class);
158            infoBuilder.addAttribute("objectName", String.class, false);
159            infoBuilder.addReference("manager", JMSManager.class);
160            infoBuilder.addInterface(BrokerServiceGBean.class);
161            // infoFactory.setConstructor(new String[]{"brokerName, brokerUri"});
162            GBEAN_INFO = infoBuilder.getBeanInfo();
163        }
164    
165        public static GBeanInfo getGBeanInfo() {
166            return GBEAN_INFO;
167        }
168    
169            /**
170             * @return Returns the brokerName.
171             */
172            public String getBrokerName() {
173                    return brokerName;
174            }
175    
176        public String getBrokerUri() {
177            return brokerUri;
178        }
179    
180        public void setBrokerName(String brokerName) {
181            this.brokerName = brokerName;
182        }
183    
184        public void setBrokerUri(String brokerUri) {
185            this.brokerUri = brokerUri;
186        }
187    
188        public ServerInfo getServerInfo() {
189            return serverInfo;
190        }
191    
192        public void setServerInfo(ServerInfo serverInfo) {
193            this.serverInfo = serverInfo;
194        }
195    
196        public String getDataDirectory() {
197            return dataDirectory;
198        }
199    
200        public void setDataDirectory(String dataDir) {
201            this.dataDirectory = dataDir;
202        }
203    
204        public ConnectionFactorySource getDataSource() {
205            return dataSource;
206        }
207    
208        public void setDataSource(ConnectionFactorySource dataSource) {
209            this.dataSource = dataSource;
210        }
211    
212        public String getObjectName() {
213            return objectName;
214        }
215    
216        public boolean isStateManageable() {
217            return true;
218        }
219    
220        public boolean isStatisticsProvider() {
221            return false; // todo: return true once stats are integrated
222        }
223    
224        public boolean isEventProvider() {
225            return true;
226        }
227    
228        public NetworkConnector[] getConnectors() {
229            return manager.getConnectorsForContainer(this);
230        }
231    
232        public NetworkConnector[] getConnectors(String protocol) {
233            return manager.getConnectorsForContainer(this, protocol);
234        }
235    
236        public JMSManager getManager() {
237            return manager;
238        }
239    
240        public void setManager(JMSManager manager) {
241            this.manager = manager;
242        }
243    
244        public void setObjectName(String objectName) {
245            this.objectName = objectName;
246        }
247    
248        public ClassLoader getClassLoader() {
249            if( classLoader == null ) {
250                classLoader = this.getClass().getClassLoader();
251            }
252            return classLoader;
253        }
254    
255        public void setClassLoader(ClassLoader classLoader) {
256            this.classLoader = classLoader;
257        }
258    
259        public boolean isUseShutdownHook() {
260            return useShutdownHook;
261        }
262    
263        public void setUseShutdownHook(final boolean useShutdownHook) {
264            this.useShutdownHook = useShutdownHook;
265        }
266    }