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    package org.apache.activemq.gbean.management;
018    
019    import java.util.ArrayList;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.Set;
023    
024    import org.apache.activemq.gbean.ActiveMQBroker;
025    import org.apache.activemq.gbean.ActiveMQConnector;
026    import org.apache.activemq.gbean.ActiveMQManager;
027    import org.apache.activemq.gbean.TransportConnectorGBeanImpl;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.geronimo.gbean.AbstractName;
031    import org.apache.geronimo.gbean.AbstractNameQuery;
032    import org.apache.geronimo.gbean.GBeanData;
033    import org.apache.geronimo.gbean.GBeanInfo;
034    import org.apache.geronimo.gbean.GBeanInfoBuilder;
035    import org.apache.geronimo.gbean.ReferencePatterns;
036    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
037    import org.apache.geronimo.kernel.GBeanNotFoundException;
038    import org.apache.geronimo.kernel.Kernel;
039    import org.apache.geronimo.kernel.config.ConfigurationUtil;
040    import org.apache.geronimo.kernel.config.EditableConfigurationManager;
041    import org.apache.geronimo.kernel.config.InvalidConfigException;
042    import org.apache.geronimo.kernel.proxy.ProxyManager;
043    import org.apache.geronimo.management.geronimo.JMSBroker;
044    import org.apache.geronimo.management.geronimo.JMSConnector;
045    import org.apache.geronimo.management.geronimo.NetworkConnector;
046    
047    /**
048     * Implementation of the ActiveMQ management interface.  These are the ActiveMQ
049     * management features available at runtime.
050     *
051     * @version $Revision: 487175 $ $Date: 2006-12-14 03:10:31 -0800 (Thu, 14 Dec 2006) $
052     */
053    public class ActiveMQManagerGBean implements ActiveMQManager {
054        private static final Log log = LogFactory.getLog(ActiveMQManagerGBean.class.getName());
055        private Kernel kernel;
056        private String objectName;
057    
058        public ActiveMQManagerGBean(Kernel kernel, String objectName) {
059            this.kernel = kernel;
060            this.objectName = objectName;
061        }
062    
063        public String getProductName() {
064            return "ActiveMQ";
065        }
066    
067        public String getObjectName() {
068            return objectName;
069        }
070    
071        public boolean isEventProvider() {
072            return false;
073        }
074    
075        public boolean isStateManageable() {
076            return true;
077        }
078    
079        public boolean isStatisticsProvider() {
080            return false;
081        }
082    
083        public Object[] getContainers() {
084            ProxyManager proxyManager = kernel.getProxyManager();
085            AbstractNameQuery query = new AbstractNameQuery(ActiveMQBroker.class.getName());
086            Set names = kernel.listGBeans(query);
087            ActiveMQBroker[] results = new ActiveMQBroker[names.size()];
088            int i=0;
089            for (Iterator it = names.iterator(); it.hasNext(); i++) {
090                AbstractName name = (AbstractName) it.next();
091                results[i] = (ActiveMQBroker) proxyManager.createProxy(name, ActiveMQBroker.class.getClassLoader());
092            }
093            return results;
094        }
095    
096        public String[] getSupportedProtocols() {
097            // see files in modules/core/src/conf/META-INF/services/org/activemq/transport/server/
098            return new String[]{ "tcp", "stomp", "vm", "peer", "udp", "multicast", "failover"};
099        }
100    
101        public NetworkConnector[] getConnectors() {
102            ProxyManager proxyManager = kernel.getProxyManager();
103            AbstractNameQuery query = new AbstractNameQuery(ActiveMQConnector.class.getName());
104            Set names = kernel.listGBeans(query);
105            ActiveMQConnector[] results = new ActiveMQConnector[names.size()];
106            int i=0;
107            for (Iterator it = names.iterator(); it.hasNext(); i++) {
108                AbstractName name = (AbstractName) it.next();
109                results[i] = (ActiveMQConnector) proxyManager.createProxy(name, ActiveMQConnector.class.getClassLoader());
110            }
111            return results;
112        }
113    
114        public NetworkConnector[] getConnectors(String protocol) {
115            if(protocol == null) {
116                return getConnectors();
117            }
118            List result = new ArrayList();
119            ProxyManager proxyManager = kernel.getProxyManager();
120            AbstractNameQuery query = new AbstractNameQuery(ActiveMQConnector.class.getName());
121            Set names = kernel.listGBeans(query);
122            for (Iterator it = names.iterator(); it.hasNext();) {
123                AbstractName name = (AbstractName) it.next();
124                try {
125                    if (kernel.getAttribute(name, "protocol").equals(protocol)) {
126                        result.add(proxyManager.createProxy(name, ActiveMQConnector.class.getClassLoader()));
127                    }
128                } catch (Exception e) {
129                    log.error("Unable to check the protocol for a connector", e);
130                }
131            }
132            return (ActiveMQConnector[]) result.toArray(new ActiveMQConnector[names.size()]);
133        }
134    
135        public NetworkConnector[] getConnectorsForContainer(Object broker) {
136            AbstractName containerName = kernel.getAbstractNameFor(broker);
137            ProxyManager mgr = kernel.getProxyManager();
138            try {
139                List results = new ArrayList();
140                AbstractNameQuery query = new AbstractNameQuery(ActiveMQConnector.class.getName());
141                Set set = kernel.listGBeans(query); // all Jetty connectors
142                for (Iterator it = set.iterator(); it.hasNext();) {
143                    AbstractName name = (AbstractName) it.next(); // a single Jetty connector
144                    GBeanData data = kernel.getGBeanData(name);
145                    ReferencePatterns refs = data.getReferencePatterns("brokerService");
146                    if (containerName.equals(refs.getAbstractName())) {
147                        results.add(mgr.createProxy(name, ActiveMQConnector.class.getClassLoader()));
148                    }
149                }
150                return (ActiveMQConnector[]) results.toArray(new ActiveMQConnector[results.size()]);
151            } catch (Exception e) {
152                throw (IllegalArgumentException) new IllegalArgumentException("Unable to look up connectors for ActiveMQ broker '"+containerName).initCause(e);
153            }
154        }
155    
156        public NetworkConnector[] getConnectorsForContainer(Object broker, String protocol) {
157            if(protocol == null) {
158                return getConnectorsForContainer(broker);
159            }
160            AbstractName containerName = kernel.getAbstractNameFor(broker);
161            ProxyManager mgr = kernel.getProxyManager();
162            try {
163                List results = new ArrayList();
164                AbstractNameQuery query = new AbstractNameQuery(ActiveMQConnector.class.getName());
165                Set set = kernel.listGBeans(query); // all Jetty connectors
166                for (Iterator it = set.iterator(); it.hasNext();) {
167                    AbstractName name = (AbstractName) it.next(); // a single Jetty connector
168                    GBeanData data = kernel.getGBeanData(name);
169                    ReferencePatterns refs = data.getReferencePatterns("brokerService");
170                    if(containerName.equals(refs.getAbstractName())) {
171                        try {
172                            String testProtocol = (String) kernel.getAttribute(name, "protocol");
173                            if(testProtocol != null && testProtocol.equals(protocol)) {
174                                results.add(mgr.createProxy(name, ActiveMQConnector.class.getClassLoader()));
175                            }
176                        } catch (Exception e) {
177                            log.error("Unable to look up protocol for connector '"+name+"'",e);
178                        }
179                        break;
180                    }
181                }
182                return (ActiveMQConnector[]) results.toArray(new ActiveMQConnector[results.size()]);
183            } catch (Exception e) {
184                throw (IllegalArgumentException)new IllegalArgumentException("Unable to look up connectors for ActiveMQ broker '"+containerName +"': ").initCause(e);
185            }
186        }
187    
188        /**
189         * Returns a new JMSConnector.  Note that
190         * the connector may well require further customization before being fully
191         * functional (e.g. SSL settings for a secure connector).
192         */
193        public JMSConnector addConnector(JMSBroker broker, String uniqueName, String protocol, String host, int port) {
194            AbstractName brokerAbstractName = kernel.getAbstractNameFor(broker);
195            AbstractName name = kernel.getNaming().createChildName(brokerAbstractName, uniqueName, NameFactory.GERONIMO_SERVICE);
196            GBeanData connector = new GBeanData(name, TransportConnectorGBeanImpl.GBEAN_INFO);
197            //todo: if SSL is supported, need to add more properties or use a different GBean?
198            connector.setAttribute("protocol", protocol);
199            connector.setAttribute("host", host);
200            connector.setAttribute("port", new Integer(port));
201            connector.setReferencePattern("brokerService", brokerAbstractName);
202            EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
203            if(mgr != null) {
204                try {
205                    mgr.addGBeanToConfiguration(brokerAbstractName.getArtifact(), connector, false);
206                    return (JMSConnector) kernel.getProxyManager().createProxy(name, ActiveMQConnector.class.getClassLoader());
207                } catch (InvalidConfigException e) {
208                    log.error("Unable to add GBean", e);
209                    return null;
210                } finally {
211                    ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
212                }
213            } else {
214                log.warn("The ConfigurationManager in the kernel does not allow editing");
215                return null;
216            }
217        }
218    
219        public void removeConnector(AbstractName connectorName) {
220            try {
221                GBeanInfo info = kernel.getGBeanInfo(connectorName);
222                boolean found = false;
223                Set intfs = info.getInterfaces();
224                for (Iterator it = intfs.iterator(); it.hasNext();) {
225                    String intf = (String) it.next();
226                    if (intf.equals(ActiveMQConnector.class.getName())) {
227                        found = true;
228                    }
229                }
230                if (!found) {
231                    throw new GBeanNotFoundException(connectorName);
232                }
233                EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
234                if (mgr != null) {
235                    try {
236                        mgr.removeGBeanFromConfiguration(connectorName.getArtifact(), connectorName);
237                    } catch (InvalidConfigException e) {
238                        log.error("Unable to add GBean", e);
239                    } finally {
240                        ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
241                    }
242                } else {
243                    log.warn("The ConfigurationManager in the kernel does not allow editing");
244                }
245            } catch (GBeanNotFoundException e) {
246                log.warn("No such GBean '" + connectorName + "'"); //todo: what if we want to remove a failed GBean?
247            } catch (Exception e) {
248                log.error(e);
249            }
250        }
251    
252        public static final GBeanInfo GBEAN_INFO;
253    
254        static {
255            GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ Manager", ActiveMQManagerGBean.class);
256            infoFactory.addAttribute("kernel", Kernel.class, false);
257            infoFactory.addAttribute("objectName", String.class, false);
258            infoFactory.addInterface(ActiveMQManager.class);
259            infoFactory.setConstructor(new String[]{"kernel", "objectName"});
260            GBEAN_INFO = infoFactory.getBeanInfo();
261        }
262    
263        public static GBeanInfo getGBeanInfo() {
264            return GBEAN_INFO;
265        }
266    }