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