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