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