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.framework;
018
019 import java.beans.PropertyChangeEvent;
020 import java.beans.PropertyChangeListener;
021 import java.io.File;
022
023 import javax.jbi.component.ServiceUnitManager;
024 import javax.jbi.management.DeploymentException;
025 import javax.management.JMException;
026 import javax.management.MBeanAttributeInfo;
027 import javax.management.MBeanOperationInfo;
028
029 import org.apache.commons.logging.Log;
030 import org.apache.commons.logging.LogFactory;
031 import org.apache.servicemix.jbi.deployment.Descriptor;
032 import org.apache.servicemix.jbi.deployment.DescriptorFactory;
033 import org.apache.servicemix.jbi.deployment.ServiceUnit;
034 import org.apache.servicemix.jbi.deployment.Services;
035 import org.apache.servicemix.jbi.event.ServiceUnitEvent;
036 import org.apache.servicemix.jbi.event.ServiceUnitListener;
037 import org.apache.servicemix.jbi.management.AttributeInfoHelper;
038 import org.apache.servicemix.jbi.management.MBeanInfoProvider;
039 import org.apache.servicemix.jbi.management.OperationInfoHelper;
040
041 public class ServiceUnitLifeCycle implements ServiceUnitMBean, MBeanInfoProvider {
042
043 private static final Log LOG = LogFactory.getLog(ServiceUnitLifeCycle.class);
044
045 private ServiceUnit serviceUnit;
046
047 private String currentState = SHUTDOWN;
048
049 private String serviceAssembly;
050
051 private Registry registry;
052
053 private PropertyChangeListener listener;
054
055 private Services services;
056
057 private File rootDir;
058
059 public ServiceUnitLifeCycle(ServiceUnit serviceUnit,
060 String serviceAssembly,
061 Registry registry,
062 File rootDir) {
063 this.serviceUnit = serviceUnit;
064 this.serviceAssembly = serviceAssembly;
065 this.registry = registry;
066 this.rootDir = rootDir;
067 Descriptor d = DescriptorFactory.buildDescriptor(rootDir);
068 if (d != null) {
069 services = d.getServices();
070 }
071 }
072
073 /**
074 * Initialize the service unit.
075 * @throws DeploymentException
076 */
077 public void init() throws DeploymentException {
078 LOG.info("Initializing service unit: " + getName());
079 checkComponentStarted("init");
080 ServiceUnitManager sum = getServiceUnitManager();
081 File path = getServiceUnitRootPath();
082 ClassLoader cl = Thread.currentThread().getContextClassLoader();
083 try {
084 Thread.currentThread().setContextClassLoader(getComponentClassLoader());
085 sum.init(getName(), path.getAbsolutePath());
086 } finally {
087 Thread.currentThread().setContextClassLoader(cl);
088 }
089 currentState = STOPPED;
090 }
091
092 /**
093 * Start the service unit.
094 * @throws DeploymentException
095 */
096 public void start() throws DeploymentException {
097 LOG.info("Starting service unit: " + getName());
098 checkComponentStarted("start");
099 ServiceUnitManager sum = getServiceUnitManager();
100 ClassLoader cl = Thread.currentThread().getContextClassLoader();
101 try {
102 Thread.currentThread().setContextClassLoader(getComponentClassLoader());
103 sum.start(getName());
104 } finally {
105 Thread.currentThread().setContextClassLoader(cl);
106 }
107 currentState = STARTED;
108 }
109
110 /**
111 * Stop the service unit. This suspends current messaging activities.
112 * @throws DeploymentException
113 */
114 public void stop() throws DeploymentException {
115 LOG.info("Stopping service unit: " + getName());
116 checkComponentStarted("stop");
117 ServiceUnitManager sum = getServiceUnitManager();
118 ClassLoader cl = Thread.currentThread().getContextClassLoader();
119 try {
120 Thread.currentThread().setContextClassLoader(getComponentClassLoader());
121 sum.stop(getName());
122 } finally {
123 Thread.currentThread().setContextClassLoader(cl);
124 }
125 currentState = STOPPED;
126 }
127
128 /**
129 * Shut down the service unit.
130 * This releases resources, preparatory to uninstallation.
131 * @throws DeploymentException
132 */
133 public void shutDown() throws DeploymentException {
134 LOG.info("Shutting down service unit: " + getName());
135 checkComponentStartedOrStopped("shutDown");
136 ServiceUnitManager sum = getServiceUnitManager();
137 ClassLoader cl = Thread.currentThread().getContextClassLoader();
138 try {
139 Thread.currentThread().setContextClassLoader(getComponentClassLoader());
140 sum.shutDown(getName());
141 } finally {
142 Thread.currentThread().setContextClassLoader(cl);
143 }
144 currentState = SHUTDOWN;
145 }
146
147 /**
148 * @return the currentState as a String
149 */
150 public String getCurrentState() {
151 return currentState;
152 }
153
154 public boolean isShutDown() {
155 return currentState.equals(SHUTDOWN);
156 }
157
158 public boolean isStopped() {
159 return currentState.equals(STOPPED);
160 }
161
162 public boolean isStarted() {
163 return currentState.equals(STARTED);
164 }
165
166 /**
167 * @return the name of the ServiceAssembly
168 */
169 public String getName() {
170 return serviceUnit.getIdentification().getName();
171 }
172
173 /**
174 * @return the description of the ServiceAssembly
175 */
176 public String getDescription() {
177 return serviceUnit.getIdentification().getDescription();
178 }
179
180 public String getComponentName() {
181 return serviceUnit.getTarget().getComponentName();
182 }
183
184 public String getServiceAssembly() {
185 return serviceAssembly;
186 }
187
188 public String getDescriptor() {
189 File suDir = getServiceUnitRootPath();
190 return DescriptorFactory.getDescriptorAsText(suDir);
191 }
192
193 public Services getServices() {
194 return services;
195 }
196
197 protected void checkComponentStarted(String task) throws DeploymentException {
198 String componentName = getComponentName();
199 String suName = getName();
200 ComponentMBeanImpl lcc = registry.getComponent(componentName);
201 if (lcc == null) {
202 throw ManagementSupport.componentFailure("deploy", componentName, "Target component "
203 + componentName + " for service unit " + suName + " is not installed");
204 }
205 if (!lcc.isStarted()) {
206 throw ManagementSupport.componentFailure("deploy", componentName, "Target component "
207 + componentName + " for service unit " + suName + " is not started");
208 }
209 if (lcc.getServiceUnitManager() == null) {
210 throw ManagementSupport.componentFailure("deploy", componentName, "Target component "
211 + componentName + " for service unit " + suName + " does not accept deployments");
212 }
213 }
214
215 protected void checkComponentStartedOrStopped(String task) throws DeploymentException {
216 String componentName = getComponentName();
217 String suName = getName();
218 ComponentMBeanImpl lcc = registry.getComponent(componentName);
219 if (lcc == null) {
220 throw ManagementSupport.componentFailure("deploy", componentName, "Target component "
221 + componentName + " for service unit " + suName + " is not installed");
222 }
223 if (!lcc.isStarted() && !lcc.isStopped()) {
224 throw ManagementSupport.componentFailure("deploy", componentName, "Target component "
225 + componentName + " for service unit " + suName + " is not started");
226 }
227 if (lcc.getServiceUnitManager() == null) {
228 throw ManagementSupport.componentFailure("deploy", componentName, "Target component "
229 + componentName + " for service unit " + suName + " does not accept deployments");
230 }
231 }
232
233 protected File getServiceUnitRootPath() {
234 return rootDir;
235 }
236
237 protected ServiceUnitManager getServiceUnitManager() {
238 ComponentMBeanImpl lcc = registry.getComponent(getComponentName());
239 return lcc.getServiceUnitManager();
240 }
241
242 protected ClassLoader getComponentClassLoader() {
243 ComponentMBeanImpl lcc = registry.getComponent(getComponentName());
244 // TODO: should retrieve the real component class loader
245 return lcc.getComponent().getClass().getClassLoader();
246 }
247
248 public MBeanAttributeInfo[] getAttributeInfos() throws JMException {
249 AttributeInfoHelper helper = new AttributeInfoHelper();
250 helper.addAttribute(getObjectToManage(), "currentState", "current state of the service unit");
251 helper.addAttribute(getObjectToManage(), "name", "name of the service unit");
252 helper.addAttribute(getObjectToManage(), "componentName", "component name of the service unit");
253 helper.addAttribute(getObjectToManage(), "serviceAssembly", "service assembly name of the service unit");
254 helper.addAttribute(getObjectToManage(), "description", "description of the service unit");
255 return helper.getAttributeInfos();
256 }
257
258 public MBeanOperationInfo[] getOperationInfos() throws JMException {
259 OperationInfoHelper helper = new OperationInfoHelper();
260 helper.addOperation(getObjectToManage(), "getDescriptor", "retrieve the jbi descriptor for this unit");
261 return helper.getOperationInfos();
262 }
263
264 public Object getObjectToManage() {
265 return this;
266 }
267
268 public String getType() {
269 return "ServiceUnit";
270 }
271
272 public String getSubType() {
273 return getComponentName();
274 }
275
276 public void setPropertyChangeListener(PropertyChangeListener l) {
277 this.listener = l;
278 }
279
280 protected void firePropertyChanged(String name, Object oldValue, Object newValue) {
281 PropertyChangeListener l = listener;
282 if (l != null) {
283 PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue);
284 l.propertyChange(event);
285 }
286 }
287
288 public String getKey() {
289 return getComponentName() + "/" + getName();
290 }
291
292 protected void fireEvent(int type) {
293 ServiceUnitEvent event = new ServiceUnitEvent(this, type);
294 ServiceUnitListener[] listeners = (ServiceUnitListener[]) registry.getContainer().getListeners(ServiceUnitListener.class);
295 for (int i = 0; i < listeners.length; i++) {
296 switch (type) {
297 case ServiceUnitEvent.UNIT_STARTED:
298 listeners[i].unitStarted(event);
299 break;
300 case ServiceUnitEvent.UNIT_STOPPED:
301 listeners[i].unitStopped(event);
302 break;
303 case ServiceUnitEvent.UNIT_SHUTDOWN:
304 listeners[i].unitShutDown(event);
305 break;
306 default:
307 break;
308 }
309 }
310 }
311
312 }