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