1 17 package org.apache.servicemix.jbi.framework; 18 19 import java.beans.PropertyChangeEvent ; 20 import java.beans.PropertyChangeListener ; 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.StringReader ; 24 import java.util.ArrayList ; 25 import java.util.List ; 26 import java.util.Properties ; 27 28 import javax.jbi.JBIException; 29 import javax.jbi.management.DeploymentException; 30 import javax.management.JMException ; 31 import javax.management.MBeanAttributeInfo ; 32 import javax.management.MBeanOperationInfo ; 33 import javax.management.ObjectName ; 34 import javax.xml.namespace.QName ; 35 import javax.xml.parsers.DocumentBuilder ; 36 import javax.xml.parsers.DocumentBuilderFactory ; 37 import javax.xml.parsers.ParserConfigurationException ; 38 39 import org.apache.commons.logging.Log; 40 import org.apache.commons.logging.LogFactory; 41 import org.apache.servicemix.jbi.container.ServiceAssemblyEnvironment; 42 import org.apache.servicemix.jbi.deployment.Connection; 43 import org.apache.servicemix.jbi.deployment.Consumes; 44 import org.apache.servicemix.jbi.deployment.DescriptorFactory; 45 import org.apache.servicemix.jbi.deployment.ServiceAssembly; 46 import org.apache.servicemix.jbi.deployment.Services; 47 import org.apache.servicemix.jbi.event.ServiceAssemblyEvent; 48 import org.apache.servicemix.jbi.event.ServiceAssemblyListener; 49 import org.apache.servicemix.jbi.management.AttributeInfoHelper; 50 import org.apache.servicemix.jbi.management.MBeanInfoProvider; 51 import org.apache.servicemix.jbi.management.OperationInfoHelper; 52 import org.apache.servicemix.jbi.util.XmlPersistenceSupport; 53 import org.w3c.dom.Document ; 54 import org.w3c.dom.Element ; 55 import org.w3c.dom.NodeList ; 56 import org.xml.sax.InputSource ; 57 import org.xml.sax.SAXException ; 58 59 64 public class ServiceAssemblyLifeCycle implements ServiceAssemblyMBean, MBeanInfoProvider { 65 66 private static final Log log = LogFactory.getLog(ServiceAssemblyLifeCycle.class); 67 68 private ServiceAssembly serviceAssembly; 69 70 private String currentState = SHUTDOWN; 71 72 private ServiceUnitLifeCycle[] sus; 73 74 private Registry registry; 75 76 private PropertyChangeListener listener; 77 78 private ServiceAssemblyEnvironment env; 79 80 86 public ServiceAssemblyLifeCycle(ServiceAssembly sa, 87 ServiceAssemblyEnvironment env, 88 Registry registry) { 89 this.serviceAssembly = sa; 90 this.env = env; 91 this.registry = registry; 92 } 93 94 protected void setServiceUnits(ServiceUnitLifeCycle[] sus) { 95 this.sus = sus; 96 } 97 98 104 public String start() throws Exception { 105 return start(true); 106 } 107 108 public synchronized String start(boolean writeState) throws Exception { 109 log.info("Starting service assembly: " + getName()); 110 try { 112 startConnections(); 113 } catch (JBIException e) { 114 throw ManagementSupport.failure("start", e.getMessage()); 115 } 116 List componentFailures = new ArrayList (); 118 for (int i = 0; i < sus.length; i++) { 119 if (sus[i].isShutDown()) { 120 try { 121 sus[i].init(); 122 } catch (DeploymentException e) { 123 componentFailures.add(getComponentFailure(e, "start", sus[i].getComponentName())); 124 } 125 } 126 } 127 for (int i = 0; i < sus.length; i++) { 128 if (sus[i].isStopped()) { 129 try { 130 sus[i].start(); 131 } catch (DeploymentException e) { 132 componentFailures.add(getComponentFailure(e, "start", sus[i].getComponentName())); 133 } 134 } 135 } 136 if (componentFailures.size() == 0) { 137 currentState = STARTED; 138 if (writeState) { 139 writeRunningState(); 140 } 141 fireEvent(ServiceAssemblyEvent.ASSEMBLY_STARTED); 142 return ManagementSupport.createSuccessMessage("start"); 143 } else { 144 throw ManagementSupport.failure("start", componentFailures); 145 } 146 } 147 148 154 public String stop() throws Exception { 155 return stop(true, false); 156 } 157 158 public synchronized String stop(boolean writeState, boolean forceInit) throws Exception { 159 log.info("Stopping service assembly: " + getName()); 160 stopConnections(); 162 List componentFailures = new ArrayList (); 164 if (forceInit) { 165 for (int i = 0; i < sus.length; i++) { 166 try { 167 sus[i].init(); 168 } catch (DeploymentException e) { 169 componentFailures.add(getComponentFailure(e, "stop", sus[i].getComponentName())); 170 } 171 } 172 } 173 for (int i = 0; i < sus.length; i++) { 174 if (sus[i].isStarted()) { 175 try { 176 sus[i].stop(); 177 } catch (DeploymentException e) { 178 componentFailures.add(getComponentFailure(e, "stop", sus[i].getComponentName())); 179 } 180 } 181 } 182 if (componentFailures.size() == 0) { 183 currentState = STOPPED; 184 if (writeState) { 185 writeRunningState(); 186 } 187 fireEvent(ServiceAssemblyEvent.ASSEMBLY_STOPPED); 188 return ManagementSupport.createSuccessMessage("stop"); 189 } else { 190 throw ManagementSupport.failure("stop", componentFailures); 191 } 192 } 193 194 200 public String shutDown() throws Exception { 201 return shutDown(true); 202 } 203 204 public synchronized String shutDown(boolean writeState) throws Exception { 205 log.info("Shutting down service assembly: " + getName()); 206 List componentFailures = new ArrayList (); 207 for (int i = 0; i < sus.length; i++) { 208 if (sus[i].isStarted()) { 209 try { 210 sus[i].stop(); 211 } catch (DeploymentException e) { 212 componentFailures.add(getComponentFailure(e, "shutDown", sus[i].getComponentName())); 213 } 214 } 215 } 216 for (int i = 0; i < sus.length; i++) { 217 if (sus[i].isStopped()) { 218 try { 219 sus[i].shutDown(); 220 } catch (DeploymentException e) { 221 componentFailures.add(getComponentFailure(e, "shutDown", sus[i].getComponentName())); 222 } 223 } 224 } 225 if (componentFailures.size() == 0) { 226 currentState = SHUTDOWN; 227 if (writeState) { 228 writeRunningState(); 229 } 230 fireEvent(ServiceAssemblyEvent.ASSEMBLY_SHUTDOWN); 231 return ManagementSupport.createSuccessMessage("shutDown"); 232 } else { 233 throw ManagementSupport.failure("shutDown", componentFailures); 234 } 235 } 236 237 240 public String getCurrentState() { 241 return currentState; 242 } 243 244 boolean isShutDown() { 245 return currentState.equals(SHUTDOWN); 246 } 247 248 boolean isStopped() { 249 return currentState.equals(STOPPED); 250 } 251 252 boolean isStarted() { 253 return currentState.equals(STARTED); 254 } 255 256 259 public String getName() { 260 return serviceAssembly.getIdentification().getName(); 261 } 262 263 267 public String getDescription() { 268 return serviceAssembly.getIdentification().getDescription(); 269 } 270 271 274 public ServiceAssembly getServiceAssembly() { 275 return serviceAssembly; 276 } 277 278 public String getDescriptor() { 279 File saDir = env.getInstallDir(); 280 return DescriptorFactory.getDescriptorAsText(saDir); 281 } 282 283 286 public String toString() { 287 return "ServiceAssemblyLifeCycle[name=" + getName() + ",state=" + getCurrentState() + "]"; 288 } 289 290 293 void writeRunningState() { 294 try { 295 if (env.getStateFile() != null) { 296 String currentState = getCurrentState(); 297 Properties props = new Properties (); 298 props.setProperty("state", currentState); 299 XmlPersistenceSupport.write(env.getStateFile(), props); 300 } 301 } catch (IOException e) { 302 log.error("Failed to write current running state for ServiceAssembly: " + getName(), e); 303 } 304 } 305 306 309 String getRunningStateFromStore() { 310 try { 311 if (env.getStateFile() != null && env.getStateFile().exists()) { 312 Properties props = (Properties ) XmlPersistenceSupport.read(env.getStateFile()); 313 return props.getProperty("state", SHUTDOWN); 314 } 315 } catch (Exception e) { 316 log.error("Failed to read current running state for ServiceAssembly: " + getName(), e); 317 } 318 return null; 319 } 320 321 325 public synchronized void restore() throws Exception { 326 String state = getRunningStateFromStore(); 327 if (STARTED.equals(state)) { 328 start(false); 329 } else { 330 stop(false, true); 331 if (SHUTDOWN.equals(state)) { 332 shutDown(false); 333 } 334 } 335 } 336 337 public ServiceUnitLifeCycle[] getDeployedSUs() { 338 return sus; 339 } 340 341 protected void startConnections() throws JBIException { 342 if (serviceAssembly.getConnections() == null || 343 serviceAssembly.getConnections().getConnections() == null) { 344 return; 345 } 346 Connection[] connections = serviceAssembly.getConnections().getConnections(); 347 for (int i = 0; i < connections.length; i++) { 348 if (connections[i].getConsumer().getInterfaceName() != null) { 349 QName fromItf = connections[i].getConsumer().getInterfaceName(); 350 QName toSvc = connections[i].getProvider().getServiceName(); 351 String toEp = connections[i].getProvider().getEndpointName(); 352 registry.registerInterfaceConnection(fromItf, toSvc, toEp); 353 } else { 354 QName fromSvc = connections[i].getConsumer().getServiceName(); 355 String fromEp = connections[i].getConsumer().getEndpointName(); 356 QName toSvc = connections[i].getProvider().getServiceName(); 357 String toEp = connections[i].getProvider().getEndpointName(); 358 String link = getLinkType(fromSvc, fromEp); 359 registry.registerEndpointConnection(fromSvc, fromEp, toSvc, toEp, link); 360 } 361 } 362 } 363 364 protected String getLinkType(QName svc, String ep) { 365 for (int i = 0; i < sus.length; i++) { 366 Services s = sus[i].getServices(); 367 if (s != null && s.getConsumes() != null) { 368 Consumes[] consumes = s.getConsumes(); 369 for (int j = 0; j < consumes.length; j++) { 370 if (svc.equals(consumes[j].getServiceName()) && 371 ep.equals(consumes[j].getEndpointName())) { 372 return consumes[j].getLinkType(); 373 } 374 } 375 } 376 } 377 return null; 378 } 379 380 protected void stopConnections() { 381 if (serviceAssembly.getConnections() == null || 382 serviceAssembly.getConnections().getConnections() == null) { 383 return; 384 } 385 Connection[] connections = serviceAssembly.getConnections().getConnections(); 386 for (int i = 0; i < connections.length; i++) { 387 if (connections[i].getConsumer().getInterfaceName() != null) { 388 QName fromItf = connections[i].getConsumer().getInterfaceName(); 389 registry.unregisterInterfaceConnection(fromItf); 390 } else { 391 QName fromSvc = connections[i].getConsumer().getServiceName(); 392 String fromEp = connections[i].getConsumer().getEndpointName(); 393 registry.unregisterEndpointConnection(fromSvc, fromEp); 394 } 395 } 396 } 397 398 protected Element getComponentFailure(Exception exception, String task, String component) { 399 Element result = null; 400 String resultMsg = exception.getMessage(); 401 try { 402 Document doc = parse(resultMsg); 403 result = getElement(doc, "component-task-result"); 404 } catch (Exception e) { 405 log.warn("Could not parse result exception", e); 406 } 407 if (result == null) { 408 result = ManagementSupport.createComponentFailure( 409 task, component, 410 "Unable to parse result string", exception); 411 } 412 return result; 413 } 414 415 protected Document parse(String result) throws ParserConfigurationException , SAXException , IOException { 416 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 417 factory.setNamespaceAware(true); 418 factory.setIgnoringElementContentWhitespace(true); 419 factory.setIgnoringComments(true); 420 DocumentBuilder builder = factory.newDocumentBuilder(); 421 return builder.parse(new InputSource (new StringReader (result))); 422 } 423 424 protected Element getElement(Document doc, String name) { 425 NodeList l = doc.getElementsByTagNameNS("http://java.sun.com/xml/ns/jbi/management-message", name); 426 Element e = (Element ) l.item(0); 427 return e; 428 } 429 430 public MBeanAttributeInfo [] getAttributeInfos() throws JMException { 431 AttributeInfoHelper helper = new AttributeInfoHelper(); 432 helper.addAttribute(getObjectToManage(), "currentState", "current state of the assembly"); 433 helper.addAttribute(getObjectToManage(), "name", "name of the assembly"); 434 helper.addAttribute(getObjectToManage(), "description", "description of the assembly"); 435 helper.addAttribute(getObjectToManage(), "serviceUnits", "list of service units contained in this assembly"); 436 return helper.getAttributeInfos(); 437 } 438 439 public MBeanOperationInfo [] getOperationInfos() throws JMException { 440 OperationInfoHelper helper = new OperationInfoHelper(); 441 helper.addOperation(getObjectToManage(), "start", "start the assembly"); 442 helper.addOperation(getObjectToManage(), "stop", "stop the assembly"); 443 helper.addOperation(getObjectToManage(), "shutDown", "shutdown the assembly"); 444 helper.addOperation(getObjectToManage(), "getDescriptor", "retrieve the jbi descriptor for this assembly"); 445 return helper.getOperationInfos(); 446 } 447 448 public Object getObjectToManage() { 449 return this; 450 } 451 452 public String getType() { 453 return "ServiceAssembly"; 454 } 455 456 public String getSubType() { 457 return null; 458 } 459 460 public void setPropertyChangeListener(PropertyChangeListener listener) { 461 this.listener = listener; 462 } 463 464 protected void firePropertyChanged(String name,Object oldValue, Object newValue){ 465 PropertyChangeListener l = listener; 466 if (l != null){ 467 PropertyChangeEvent event = new PropertyChangeEvent (this,name,oldValue,newValue); 468 l.propertyChange(event); 469 } 470 } 471 472 public ObjectName [] getServiceUnits() { 473 return null; 475 } 476 477 public ServiceAssemblyEnvironment getEnvironment() { 478 return env; 479 } 480 481 protected void fireEvent(int type) { 482 ServiceAssemblyEvent event = new ServiceAssemblyEvent(this, type); 483 ServiceAssemblyListener[] listeners = (ServiceAssemblyListener[]) registry.getContainer().getListeners(ServiceAssemblyListener.class); 484 for (int i = 0; i < listeners.length; i++) { 485 switch (type) { 486 case ServiceAssemblyEvent.ASSEMBLY_STARTED: 487 listeners[i].assemblyStarted(event); 488 break; 489 case ServiceAssemblyEvent.ASSEMBLY_STOPPED: 490 listeners[i].assemblyStopped(event); 491 break; 492 case ServiceAssemblyEvent.ASSEMBLY_SHUTDOWN: 493 listeners[i].assemblyShutDown(event); 494 break; 495 } 496 } 497 498 } 499 500 } 501 | Popular Tags |