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.common;
018
019 import org.apache.commons.logging.Log;
020
021 import javax.jbi.component.ServiceUnitManager;
022 import javax.jbi.management.DeploymentException;
023 import javax.jbi.management.LifeCycleMBean;
024
025 /**
026 * A simple service unit manager.
027 * This service unit manager uses {@link Deployer} objects
028 * to handle different type of service units.
029 *
030 * @author Guillaume Nodet
031 * @version $Revision: 695836 $
032 * @since 3.0
033 */
034 public class BaseServiceUnitManager implements ServiceUnitManager {
035
036 protected final transient Log logger;
037
038 protected ServiceMixComponent component;
039
040 protected Deployer[] deployers;
041
042 protected boolean persistent;
043
044 public BaseServiceUnitManager(ServiceMixComponent component, Deployer[] deployers) {
045 this(component, deployers, false);
046 }
047
048 public BaseServiceUnitManager(ServiceMixComponent component, Deployer[] deployers, boolean persistent) {
049 this.component = component;
050 this.logger = component.getLogger();
051 this.deployers = deployers;
052 this.persistent = persistent;
053 }
054
055 /* (non-Javadoc)
056 * @see javax.jbi.component.ServiceUnitManager#deploy(java.lang.String, java.lang.String)
057 */
058 public synchronized String deploy(String serviceUnitName, String serviceUnitRootPath) throws DeploymentException {
059 try {
060 if (logger.isDebugEnabled()) {
061 logger.debug("Deploying service unit");
062 }
063 if (serviceUnitName == null || serviceUnitName.length() == 0) {
064 throw new IllegalArgumentException("serviceUnitName should be non null and non empty");
065 }
066 if (getServiceUnit(serviceUnitName) != null) {
067 throw failure("deploy", "Service Unit '" + serviceUnitName + "' is already deployed", null);
068 }
069 ServiceUnit su = doDeploy(serviceUnitName, serviceUnitRootPath);
070 if (su == null) {
071 throw failure("deploy", "Unable to find suitable deployer for Service Unit '" + serviceUnitName + "'", null);
072 }
073 component.getRegistry().registerServiceUnit(su);
074 if (logger.isDebugEnabled()) {
075 logger.debug("Service unit deployed");
076 }
077 return createSuccessMessage("deploy");
078 } catch (DeploymentException e) {
079 throw e;
080 } catch (Exception e) {
081 throw failure("deploy", "Unable to deploy service unit", e);
082 }
083 }
084
085 protected ServiceUnit doDeploy(String serviceUnitName, String serviceUnitRootPath) throws Exception {
086 for (int i = 0; i < deployers.length; i++) {
087 if (deployers[i].canDeploy(serviceUnitName, serviceUnitRootPath)) {
088 return deployers[i].deploy(serviceUnitName, serviceUnitRootPath);
089 }
090 }
091 return null;
092 }
093
094 /* (non-Javadoc)
095 * @see javax.jbi.component.ServiceUnitManager#init(java.lang.String, java.lang.String)
096 */
097 public synchronized void init(String serviceUnitName, String serviceUnitRootPath) throws DeploymentException {
098 ClassLoader cl = Thread.currentThread().getContextClassLoader();
099 try {
100 if (logger.isDebugEnabled()) {
101 logger.debug("Initializing service unit");
102 }
103 if (serviceUnitName == null || serviceUnitName.length() == 0) {
104 throw new IllegalArgumentException("serviceUnitName should be non null and non empty");
105 }
106 ServiceUnit su = getServiceUnit(serviceUnitName);
107 if (su == null) {
108 if (!persistent) {
109 su = doDeploy(serviceUnitName, serviceUnitRootPath);
110 if (su == null) {
111 throw failure("deploy", "Unable to find suitable deployer for Service Unit '" + serviceUnitName + "'", null);
112 }
113 component.getRegistry().registerServiceUnit(su);
114 } else {
115 throw failure("init", "Service Unit '" + serviceUnitName + "' is not deployed", null);
116 }
117 }
118 if (!LifeCycleMBean.SHUTDOWN.equals(su.getCurrentState())) {
119 throw failure("init", "ServiceUnit should be in a SHUTDOWN state", null);
120 }
121 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
122 su.init();
123 if (logger.isDebugEnabled()) {
124 logger.debug("Service unit initialized");
125 }
126 } catch (DeploymentException e) {
127 throw e;
128 } catch (Exception e) {
129 throw failure("init", "Unable to init service unit", e);
130 } finally {
131 Thread.currentThread().setContextClassLoader(cl);
132 }
133 }
134
135 /* (non-Javadoc)
136 * @see javax.jbi.component.ServiceUnitManager#start(java.lang.String)
137 */
138 public synchronized void start(String serviceUnitName) throws DeploymentException {
139 ClassLoader cl = Thread.currentThread().getContextClassLoader();
140 try {
141 if (logger.isDebugEnabled()) {
142 logger.debug("Starting service unit");
143 }
144 if (serviceUnitName == null || serviceUnitName.length() == 0) {
145 throw new IllegalArgumentException("serviceUnitName should be non null and non empty");
146 }
147 ServiceUnit su = (ServiceUnit) getServiceUnit(serviceUnitName);
148 if (su == null) {
149 throw failure("start", "Service Unit '" + serviceUnitName + "' is not deployed", null);
150 }
151 if (!LifeCycleMBean.STOPPED.equals(su.getCurrentState())) {
152 throw failure("start", "ServiceUnit should be in a STOPPED state", null);
153 }
154 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
155 su.start();
156 if (logger.isDebugEnabled()) {
157 logger.debug("Service unit started");
158 }
159 } catch (DeploymentException e) {
160 throw e;
161 } catch (Exception e) {
162 throw failure("start", "Unable to start service unit", e);
163 } finally {
164 Thread.currentThread().setContextClassLoader(cl);
165 }
166 }
167
168 /* (non-Javadoc)
169 * @see javax.jbi.component.ServiceUnitManager#stop(java.lang.String)
170 */
171 public synchronized void stop(String serviceUnitName) throws DeploymentException {
172 ClassLoader cl = Thread.currentThread().getContextClassLoader();
173 try {
174 if (logger.isDebugEnabled()) {
175 logger.debug("Stopping service unit");
176 }
177 if (serviceUnitName == null || serviceUnitName.length() == 0) {
178 throw new IllegalArgumentException("serviceUnitName should be non null and non empty");
179 }
180 ServiceUnit su = getServiceUnit(serviceUnitName);
181 if (su == null) {
182 throw failure("stop", "Service Unit '" + serviceUnitName + "' is not deployed", null);
183 }
184 if (!LifeCycleMBean.STARTED.equals(su.getCurrentState())) {
185 throw failure("stop", "ServiceUnit should be in a STARTED state", null);
186 }
187 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
188 su.stop();
189 if (logger.isDebugEnabled()) {
190 logger.debug("Service unit stopped");
191 }
192 } catch (DeploymentException e) {
193 throw e;
194 } catch (Exception e) {
195 throw failure("stop", "Unable to stop service unit", e);
196 } finally {
197 Thread.currentThread().setContextClassLoader(cl);
198 }
199 }
200
201 /* (non-Javadoc)
202 * @see javax.jbi.component.ServiceUnitManager#shutDown(java.lang.String)
203 */
204 public synchronized void shutDown(String serviceUnitName) throws DeploymentException {
205 ClassLoader cl = Thread.currentThread().getContextClassLoader();
206 try {
207 if (logger.isDebugEnabled()) {
208 logger.debug("Shutting down service unit");
209 }
210 if (serviceUnitName == null || serviceUnitName.length() == 0) {
211 throw new IllegalArgumentException("serviceUnitName should be non null and non empty");
212 }
213 ServiceUnit su = getServiceUnit(serviceUnitName);
214 if (su == null) {
215 throw failure("shutDown", "Service Unit '" + serviceUnitName + "' is not deployed", null);
216 }
217 if (!LifeCycleMBean.STOPPED.equals(su.getCurrentState())) {
218 throw failure("start", "ServiceUnit should be in a STOPPED state", null);
219 }
220 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
221 su.shutDown();
222 if (logger.isDebugEnabled()) {
223 logger.debug("Service unit shut down");
224 }
225 } catch (DeploymentException e) {
226 throw e;
227 } catch (Exception e) {
228 throw failure("shutDown", "Unable to shutdown service unit", e);
229 } finally {
230 Thread.currentThread().setContextClassLoader(cl);
231 }
232 }
233
234 /* (non-Javadoc)
235 * @see javax.jbi.component.ServiceUnitManager#undeploy(java.lang.String, java.lang.String)
236 */
237 public synchronized String undeploy(String serviceUnitName, String serviceUnitRootPath) throws DeploymentException {
238 ClassLoader cl = Thread.currentThread().getContextClassLoader();
239 try {
240 if (logger.isDebugEnabled()) {
241 logger.debug("Undeploying service unit");
242 }
243 if (logger.isDebugEnabled()) {
244 logger.debug("Shutting down service unit");
245 }
246 if (serviceUnitName == null || serviceUnitName.length() == 0) {
247 throw new IllegalArgumentException("serviceUnitName should be non null and non empty");
248 }
249 ServiceUnit su = getServiceUnit(serviceUnitName);
250 if (su == null) {
251 throw failure("undeploy", "Service Unit '" + serviceUnitName + "' is not deployed", null);
252 }
253 if (!LifeCycleMBean.SHUTDOWN.equals(su.getCurrentState())) {
254 throw failure("undeploy", "ServiceUnit should be in a SHUTDOWN state", null);
255 }
256 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
257 doUndeploy(su);
258 component.getRegistry().unregisterServiceUnit(su);
259 if (logger.isDebugEnabled()) {
260 logger.debug("Service unit undeployed");
261 }
262 return createSuccessMessage("undeploy");
263 } catch (DeploymentException e) {
264 throw e;
265 } catch (Exception e) {
266 throw failure("undeploy", "Unable to undeploy service unit", e);
267 } finally {
268 Thread.currentThread().setContextClassLoader(cl);
269 }
270 }
271
272 protected void doUndeploy(ServiceUnit su) throws Exception {
273 for (int i = 0; i < deployers.length; i++) {
274 if (deployers[i].canDeploy(su.getName(), su.getRootPath())) {
275 deployers[i].undeploy(su);
276 return;
277 }
278 }
279 throw failure("undeploy", "Unable to find suitable deployer for Service Unit '" + su.getName() + "'", null);
280 }
281
282 protected DeploymentException failure(String task, String info, Exception e) throws DeploymentException {
283 ManagementSupport.Message msg = new ManagementSupport.Message();
284 msg.setComponent(component.getComponentName());
285 msg.setTask(task);
286 msg.setResult("FAILED");
287 msg.setType("ERROR");
288 msg.setException(e);
289 msg.setMessage(info);
290 return new DeploymentException(ManagementSupport.createComponentMessage(msg));
291 }
292
293 protected String createSuccessMessage(String task) {
294 ManagementSupport.Message msg = new ManagementSupport.Message();
295 msg.setComponent(component.getComponentName());
296 msg.setTask(task);
297 msg.setResult("SUCCESS");
298 return ManagementSupport.createComponentMessage(msg);
299 }
300
301 protected ServiceUnit getServiceUnit(String name) {
302 return component.getRegistry().getServiceUnit(name);
303 }
304
305 }