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.servicemix.jbi.management.task;
018
019 import java.io.IOException;
020 import java.net.MalformedURLException;
021 import java.util.HashMap;
022 import java.util.Map;
023
024 import javax.management.MBeanServerInvocationHandler;
025 import javax.management.ObjectName;
026 import javax.management.remote.JMXConnector;
027 import javax.management.remote.JMXConnectorFactory;
028 import javax.management.remote.JMXServiceURL;
029
030 import org.apache.servicemix.jbi.container.JBIContainer;
031 import org.apache.servicemix.jbi.framework.AdminCommandsServiceMBean;
032 import org.apache.servicemix.jbi.management.ManagementContext;
033 import org.apache.tools.ant.BuildException;
034 import org.apache.tools.ant.Project;
035 import org.apache.tools.ant.Task;
036
037 /**
038 * A bean for connecting to a remote JMX MBeanServer
039 *
040 * @version $Revision: 564607 $
041 */
042 public abstract class JbiTask extends Task {
043
044 private String serverProtocol = "rmi";
045
046 private String host = "localhost";
047
048 private String containerName = JBIContainer.DEFAULT_NAME;
049
050 private String jmxDomainName = ManagementContext.DEFAULT_DOMAIN;
051
052 private int port = ManagementContext.DEFAULT_CONNECTOR_PORT;
053
054 private String jndiPath = ManagementContext.DEFAULT_CONNECTOR_PATH;
055
056 private String username;
057
058 private String password;
059
060 private boolean failOnError = true;
061
062 private JMXConnector jmxConnector;
063
064 /**
065 * Get the JMXServiceURL - built from the protocol used and host names
066 *
067 * @return the url
068 */
069 public JMXServiceURL getServiceURL() throws MalformedURLException {
070 JMXServiceURL url = null;
071 url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + jndiPath);
072 return url;
073 }
074
075 /**
076 * Get a JMXConnector from a url
077 *
078 * @param url
079 * @return the JMXConnector
080 * @throws IOException
081 */
082 public JMXConnector getJMXConnector(JMXServiceURL url) throws IOException {
083 String[] credentials = new String[] {getUsername(), getPassword() };
084 Map<String, Object> environment = new HashMap<String, Object>();
085 environment.put(JMXConnector.CREDENTIALS, credentials);
086 return JMXConnectorFactory.connect(url, environment);
087 }
088
089 /**
090 * initialize the connection
091 *
092 * @throws BuildException
093 */
094 public void connect() throws IOException {
095 this.jmxConnector = getJMXConnector(getServiceURL());
096 }
097
098 /**
099 * close any internal remote connections
100 *
101 */
102 public void close() {
103 if (this.jmxConnector != null) {
104 try {
105 jmxConnector.close();
106 } catch (IOException e) {
107 log("Caught an error closing the jmxConnector" + e.getMessage(), Project.MSG_WARN);
108 }
109 }
110 }
111
112 /**
113 * Get a servicemix internal system management instance, from it's class
114 * name
115 *
116 * @param systemClass
117 * @return the object name
118 */
119 protected ObjectName getObjectName(Class systemClass) {
120 return ManagementContext.getSystemObjectName(jmxDomainName, containerName, systemClass);
121 }
122
123 /**
124 * Get the AdminCommandsService
125 *
126 * @return the main administration service MBean
127 * @throws IOException
128 */
129 public AdminCommandsServiceMBean getAdminCommandsService() throws IOException {
130 ObjectName objectName = getObjectName(AdminCommandsServiceMBean.class);
131
132 return (AdminCommandsServiceMBean) MBeanServerInvocationHandler.newProxyInstance(jmxConnector.getMBeanServerConnection(),
133 objectName, AdminCommandsServiceMBean.class, true);
134 }
135
136 /**
137 * @return Returns the containerName.
138 */
139 public String getContainerName() {
140 return containerName;
141 }
142
143 /**
144 * @param containerName
145 * The containerName to set.
146 */
147 public void setContainerName(String containerName) {
148 this.containerName = containerName;
149 }
150
151 /**
152 * @return Returns the jmxDomainName.
153 */
154 public String getJmxDomainName() {
155 return jmxDomainName;
156 }
157
158 /**
159 * @param jmxDomainName
160 * The jmxDomainName to set.
161 */
162 public void setJmxDomainName(String jmxDomainName) {
163 this.jmxDomainName = jmxDomainName;
164 }
165
166 /**
167 * @return Returns the jndiPath.
168 */
169 public String getJndiPath() {
170 return jndiPath;
171 }
172
173 /**
174 * @param jndiPath
175 * The jndiPath to set.
176 */
177 public void setJndiPath(String jndiPath) {
178 this.jndiPath = jndiPath;
179 }
180
181 /**
182 * @return Returns the namingHost.
183 */
184 public String getHost() {
185 return host;
186 }
187
188 /**
189 * @param host
190 * The namingHost to set.
191 */
192 public void setHost(String host) {
193 this.host = host;
194 }
195
196 /**
197 * @return Returns the namingPort.
198 */
199 public int getPort() {
200 return port;
201 }
202
203 /**
204 * @param port
205 * The namingPort to set.
206 */
207 public void setPort(int port) {
208 this.port = port;
209 }
210
211 /**
212 * @return Returns the serverProtocol.
213 */
214 public String getServerProtocol() {
215 return serverProtocol;
216 }
217
218 /**
219 * @param serverProtocol
220 * The serverProtocol to set.
221 */
222 public void setServerProtocol(String serverProtocol) {
223 this.serverProtocol = serverProtocol;
224 }
225
226 /**
227 * @return Returns the passwd.
228 */
229 public String getPassword() {
230 return password;
231 }
232
233 /**
234 * @param password
235 * The passwd to set.
236 */
237 public void setPassword(String password) {
238 this.password = password;
239 }
240
241 /**
242 * @return Returns the username.
243 */
244 public String getUsername() {
245 return username;
246 }
247
248 /**
249 * @param username
250 * The username to set.
251 */
252 public void setUsername(String username) {
253 this.username = username;
254 }
255
256 /**
257 * @return Returns the failOnError.
258 */
259 public boolean isFailOnError() {
260 return failOnError;
261 }
262
263 /**
264 * @param failOnError
265 * The failOnError to set.
266 */
267 public void setFailOnError(boolean failOnError) {
268 this.failOnError = failOnError;
269 }
270
271 /**
272 * execute the task
273 *
274 * @throws BuildException
275 */
276 public void execute() throws BuildException {
277 AdminCommandsServiceMBean acs;
278 try {
279 log("Retrieving remote admin interface", Project.MSG_DEBUG);
280 connect();
281 acs = getAdminCommandsService();
282 } catch (Throwable e) {
283 log("Error accessing ServiceMix administration: " + e.getMessage(), Project.MSG_WARN);
284 if (isFailOnError()) {
285 throw new BuildException("Error accessing ServiceMix administration", e);
286 } else {
287 return;
288 }
289 }
290 try {
291 log("Executing command", Project.MSG_DEBUG);
292 doExecute(acs);
293 } catch (Throwable e) {
294 log("Error executing command: " + e.getMessage(), Project.MSG_WARN);
295 if (isFailOnError()) {
296 throw new BuildException("Error accessing ServiceMix administration", e);
297 } else {
298 return;
299 }
300 }
301 }
302
303 protected abstract void doExecute(AdminCommandsServiceMBean acs) throws Exception;
304
305 }