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    }