Source code: org/activemq/gbean/management/ActiveMQManagerGBean.java
1 /**
2 *
3 * Copyright 2004 Protique Ltd
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.activemq.gbean.management;
19
20 import java.util.Set;
21 import java.util.Iterator;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Hashtable;
25 import javax.management.ObjectName;
26 import javax.management.MalformedObjectNameException;
27 import org.activemq.gbean.ActiveMQManager;
28 import org.activemq.gbean.ActiveMQBroker;
29 import org.activemq.gbean.ActiveMQConnector;
30 import org.activemq.gbean.ActiveMQConnectorGBean;
31 import org.apache.geronimo.gbean.GBeanInfo;
32 import org.apache.geronimo.gbean.GBeanInfoBuilder;
33 import org.apache.geronimo.gbean.GBeanQuery;
34 import org.apache.geronimo.gbean.GBeanData;
35 import org.apache.geronimo.kernel.Kernel;
36 import org.apache.geronimo.kernel.GBeanNotFoundException;
37 import org.apache.geronimo.j2ee.management.impl.Util;
38 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 /**
43 * Implementation of the ActiveMQ management interface. These are the ActiveMQ
44 * mangement features available at runtime.
45 *
46 * @version $Revision: 1.0$
47 */
48 public class ActiveMQManagerGBean implements ActiveMQManager {
49 private static final Log log = LogFactory.getLog(ActiveMQManagerGBean.class.getName());
50 private Kernel kernel;
51
52 public ActiveMQManagerGBean(Kernel kernel) {
53 this.kernel = kernel;
54 }
55
56 public String getProductName() {
57 return "ActiveMQ";
58 }
59
60 public String[] getContainers() {
61 GBeanQuery query = new GBeanQuery(null, ActiveMQBroker.class.getName());
62 Set set = kernel.listGBeans(query);
63 String[] results = new String[set.size()];
64 int i=0;
65 for (Iterator it = set.iterator(); it.hasNext();) {
66 ObjectName name = (ObjectName) it.next();
67 results[i++] = name.getCanonicalName();
68 }
69 return results;
70 }
71
72 public String[] getSupportedProtocols() {
73 // see files in modules/core/src/conf/META-INF/services/org/activemq/transport/server/
74 return new String[]{"activeio","jabber","multicast","openwire","peer","stomp","tcp","udp","vm",};
75 }
76
77 public String[] getConnectors() {
78 GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName());
79 Set set = kernel.listGBeans(query);
80 String[] results = new String[set.size()];
81 int i=0;
82 for (Iterator it = set.iterator(); it.hasNext();) {
83 ObjectName name = (ObjectName) it.next();
84 results[i++] = name.getCanonicalName();
85 }
86 return results;
87 }
88
89 public String[] getConnectors(String protocol) {
90 if(protocol == null) {
91 return getConnectors();
92 }
93 GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName());
94 Set set = kernel.listGBeans(query);
95 List results = new ArrayList();
96 for (Iterator it = set.iterator(); it.hasNext();) {
97 ObjectName name = (ObjectName) it.next();
98 try {
99 String target = (String) kernel.getAttribute(name, "protocol");
100 if(target != null && target.equals(protocol)) {
101 results.add(name.getCanonicalName());
102 }
103 } catch (Exception e) {
104 log.error("Unable to look up protocol for connector '"+name+"'",e);
105 }
106 }
107 return (String[]) results.toArray(new String[results.size()]);
108 }
109
110 public String[] getConnectorsForContainer(String broker) {
111 try {
112 ObjectName brokerName = ObjectName.getInstance(broker);
113 List results = new ArrayList();
114 GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName());
115 Set set = kernel.listGBeans(query); // all ActiveMQ connectors
116 for (Iterator it = set.iterator(); it.hasNext();) {
117 ObjectName name = (ObjectName) it.next(); // a single ActiveMQ connector
118 GBeanData data = kernel.getGBeanData(name);
119 Set refs = data.getReferencePatterns("activeMQContainer");
120 for (Iterator refit = refs.iterator(); refit.hasNext();) {
121 ObjectName ref = (ObjectName) refit.next();
122 if(ref.isPattern()) {
123 Set matches = kernel.listGBeans(ref);
124 if(matches.size() != 1) {
125 log.error("Unable to compare a connector->container reference that's a pattern to a fixed container name: "+ref.getCanonicalName());
126 } else {
127 ref = (ObjectName)matches.iterator().next();
128 if(ref.equals(brokerName)) {
129 results.add(name.getCanonicalName());
130 break;
131 }
132 }
133 } else {
134 if(ref.equals(brokerName)) {
135 results.add(name.getCanonicalName());
136 break;
137 }
138 }
139 }
140 }
141 return (String[]) results.toArray(new String[results.size()]);
142 } catch (Exception e) {
143 throw new IllegalArgumentException("Unable to look up connectors for broker '"+broker+"': "+e);
144 }
145 }
146
147 public String[] getConnectorsForContainer(String broker, String protocol) {
148 if(protocol == null) {
149 return getConnectorsForContainer(broker);
150 }
151 try {
152 ObjectName brokerName = ObjectName.getInstance(broker);
153 List results = new ArrayList();
154 GBeanQuery query = new GBeanQuery(null, ActiveMQConnector.class.getName());
155 Set set = kernel.listGBeans(query); // all ActiveMQ connectors
156 for (Iterator it = set.iterator(); it.hasNext();) {
157 ObjectName name = (ObjectName) it.next(); // a single ActiveMQ connector
158 GBeanData data = kernel.getGBeanData(name);
159 Set refs = data.getReferencePatterns("activeMQContainer");
160 for (Iterator refit = refs.iterator(); refit.hasNext();) {
161 ObjectName ref = (ObjectName) refit.next();
162 boolean match = false;
163 if(ref.isPattern()) {
164 Set matches = kernel.listGBeans(ref);
165 if(matches.size() != 1) {
166 log.error("Unable to compare a connector->container reference that's a pattern to a fixed container name: "+ref.getCanonicalName());
167 } else {
168 ref = (ObjectName)matches.iterator().next();
169 if(ref.equals(brokerName)) {
170 match = true;
171 }
172 }
173 } else {
174 if(ref.equals(brokerName)) {
175 match = true;
176 }
177 }
178 if(match) {
179 try {
180 String testProtocol = (String) kernel.getAttribute(name, "protocol");
181 if(testProtocol != null && testProtocol.equals(protocol)) {
182 results.add(name.getCanonicalName());
183 }
184 } catch (Exception e) {
185 log.error("Unable to look up protocol for connector '"+name+"'",e);
186 }
187 break;
188 }
189 }
190 }
191 return (String[]) results.toArray(new String[results.size()]);
192 } catch (Exception e) {
193 throw new IllegalArgumentException("Unable to look up connectors for broker '"+broker+"': "+e);
194 }
195 }
196
197 /**
198 * Creates a new connector, and returns the ObjectName for it. Note that
199 * the connector may well require further customization before being fully
200 * functional (e.g. SSL settings for a secure connector).
201 */
202 public String addConnector(String broker, String uniqueName, String protocol, String host, int port) {
203 ObjectName brokerName = null;
204 try {
205 brokerName = ObjectName.getInstance(broker);
206 } catch (MalformedObjectNameException e) {
207 throw new IllegalArgumentException("Unable to parse ObjectName '"+broker+"'");
208 }
209 ObjectName name = getConnectorName(brokerName, protocol, host, port, uniqueName);
210 GBeanData connector = new GBeanData(name, ActiveMQConnectorGBean.GBEAN_INFO);
211 //todo: if SSL is supported, need to add more properties or use a different GBean?
212 connector.setAttribute("protocol", protocol);
213 connector.setAttribute("host", host);
214 connector.setAttribute("port", new Integer(port));
215 connector.setReferencePattern("activeMQContainer", brokerName);
216 ObjectName config = Util.getConfiguration(kernel, brokerName);
217 try {
218 kernel.invoke(config, "addGBean", new Object[]{connector, Boolean.FALSE}, new String[]{GBeanData.class.getName(), boolean.class.getName()});
219 } catch (Exception e) {
220 log.error("Unable to add GBean ", e);
221 return null;
222 }
223 return name.getCanonicalName();
224 }
225
226 public void removeConnector(String objectName) {
227 ObjectName name = null;
228 try {
229 name = ObjectName.getInstance(objectName);
230 } catch (MalformedObjectNameException e) {
231 throw new IllegalArgumentException("Invalid object name '" + objectName + "': " + e.getMessage());
232 }
233 try {
234 GBeanInfo info = kernel.getGBeanInfo(name);
235 boolean found = false;
236 Set intfs = info.getInterfaces();
237 for (Iterator it = intfs.iterator(); it.hasNext();) {
238 String intf = (String) it.next();
239 if (intf.equals(ActiveMQConnector.class.getName())) {
240 found = true;
241 }
242 }
243 if (!found) {
244 throw new GBeanNotFoundException(name);
245 }
246 ObjectName config = Util.getConfiguration(kernel, name);
247 kernel.invoke(config, "removeGBean", new Object[]{name}, new String[]{ObjectName.class.getName()});
248 } catch (GBeanNotFoundException e) {
249 log.warn("No such GBean '" + objectName + "'"); //todo: what if we want to remove a failed GBean?
250 } catch (Exception e) {
251 log.error("Unable to remove GBean", e);
252 }
253 }
254
255 /**
256 * Generate an ObjectName for a new connector GBean
257 */
258 private ObjectName getConnectorName(ObjectName broker, String protocol, String host, int port, String uniqueName) {
259 Hashtable table = new Hashtable();
260 table.put(NameFactory.J2EE_APPLICATION, broker.getKeyProperty(NameFactory.J2EE_APPLICATION));
261 table.put(NameFactory.J2EE_SERVER, broker.getKeyProperty(NameFactory.J2EE_SERVER));
262 table.put(NameFactory.J2EE_MODULE, broker.getKeyProperty(NameFactory.J2EE_MODULE));
263 table.put(NameFactory.J2EE_TYPE, ActiveMQConnector.CONNECTOR_J2EE_TYPE);
264 String brokerName = broker.getKeyProperty(NameFactory.J2EE_NAME);
265 table.put("broker", brokerName);
266 table.put(NameFactory.J2EE_NAME, brokerName+"."+protocol+"."+host+(port > -1 ? "."+port : "")+"-"+uniqueName);
267 try {
268 return ObjectName.getInstance(broker.getDomain(), table);
269 } catch (MalformedObjectNameException e) {
270 throw new IllegalStateException("Never should have failed: " + e.getMessage());
271 }
272 }
273
274 public static final GBeanInfo GBEAN_INFO;
275
276 static {
277 GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ActiveMQ Manager", ActiveMQManagerGBean.class);
278 infoFactory.addAttribute("kernel", Kernel.class, false);
279 infoFactory.addInterface(ActiveMQManager.class);
280 infoFactory.setConstructor(new String[]{"kernel"});
281 GBEAN_INFO = infoFactory.getBeanInfo();
282 }
283
284 public static GBeanInfo getGBeanInfo() {
285 return GBEAN_INFO;
286 }
287 }