1 17 package org.apache.servicemix.jbi.framework; 18 19 import java.io.File ; 20 import java.io.IOException ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import java.util.Properties ; 24 25 import javax.jbi.JBIException; 26 import javax.jbi.management.DeploymentException; 27 import javax.jbi.management.InstallationServiceMBean; 28 import javax.jbi.management.InstallerMBean; 29 import javax.management.Attribute ; 30 import javax.management.JMException ; 31 import javax.management.MBeanOperationInfo ; 32 import javax.management.MBeanServer ; 33 import javax.management.ObjectName ; 34 import javax.resource.spi.work.Work ; 35 import javax.resource.spi.work.WorkException ; 36 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 import org.apache.servicemix.jbi.container.ComponentEnvironment; 40 import org.apache.servicemix.jbi.container.EnvironmentContext; 41 import org.apache.servicemix.jbi.container.JBIContainer; 42 import org.apache.servicemix.jbi.deployment.Component; 43 import org.apache.servicemix.jbi.deployment.Descriptor; 44 import org.apache.servicemix.jbi.deployment.DescriptorFactory; 45 import org.apache.servicemix.jbi.deployment.SharedLibrary; 46 import org.apache.servicemix.jbi.management.BaseSystemService; 47 import org.apache.servicemix.jbi.management.ManagementContext; 48 import org.apache.servicemix.jbi.management.OperationInfoHelper; 49 import org.apache.servicemix.jbi.management.ParameterHelper; 50 import org.apache.servicemix.jbi.util.FileUtil; 51 import org.apache.servicemix.jbi.util.FileVersionUtil; 52 53 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; 54 55 60 public class InstallationService extends BaseSystemService implements InstallationServiceMBean { 61 62 private static final Log log=LogFactory.getLog(InstallationService.class); 63 64 private EnvironmentContext environmentContext; 65 private ManagementContext managementContext; 66 private Map installers=new ConcurrentHashMap(); 67 private Map nonLoadedInstallers = new ConcurrentHashMap(); 68 69 74 public String getDescription(){ 75 return "installs/uninstalls Components"; 76 } 77 78 85 public synchronized ObjectName loadNewInstaller(String installJarURL){ 86 try{ 87 ObjectName result=null; 88 if(log.isDebugEnabled()){ 89 log.debug("Loading new installer from "+installJarURL); 90 } 91 File tmpDir=AutoDeploymentService.unpackLocation(environmentContext.getTmpDir(),installJarURL); 92 if(tmpDir!=null){ 93 Descriptor root=DescriptorFactory.buildDescriptor(tmpDir); 94 if(root!=null&&root.getComponent()!=null){ 95 String componentName=root.getComponent().getIdentification().getName(); 96 if(!installers.containsKey(componentName)){ 97 InstallerMBeanImpl installer=doInstallArchive(tmpDir,root); 98 if(installer!=null){ 99 result=installer.getObjectName(); 100 installers.put(componentName,installer); 101 } 102 }else{ 103 throw new RuntimeException ("An installer already exists for "+componentName); 104 } 105 }else{ 106 throw new RuntimeException ("Could not find Component from: "+installJarURL); 107 } 108 }else{ 109 throw new RuntimeException ("location: "+installJarURL+" isn't valid"); 110 } 111 return result; 112 }catch(Throwable t){ 113 log.error("Deployment failed",t); 114 if(t instanceof Error ){ 115 throw (Error ) t; 116 } 117 if(t instanceof RuntimeException ){ 118 throw (RuntimeException ) t; 119 }else{ 120 throw new RuntimeException ("Deployment failed: "+t.getMessage()); 121 } 122 } 123 } 124 125 132 public ObjectName loadInstaller(String aComponentName) { 133 InstallerMBeanImpl installer = (InstallerMBeanImpl) installers.get(aComponentName); 134 if (installer == null) { 135 installer = (InstallerMBeanImpl) nonLoadedInstallers.get(aComponentName); 136 if (installer != null) { 137 try { 138 ObjectName objectName = managementContext.createCustomComponentMBeanName("Installer", aComponentName); 140 installer.setObjectName(objectName); 141 managementContext.registerMBean(objectName, installer, 142 InstallerMBean.class, 143 "standard installation controls for a Component"); 144 } catch (Exception e) { 145 throw new RuntimeException ("Could not load installer", e); 146 } 147 return installer.getObjectName(); 148 } 149 } 150 return null; 151 } 152 153 private InstallerMBeanImpl createInstaller(String componentName) throws IOException , DeploymentException { 154 File installationDir = environmentContext.getComponentInstallationDir(componentName); 155 Descriptor root = DescriptorFactory.buildDescriptor(installationDir); 156 Component descriptor = root.getComponent(); 157 158 InstallationContextImpl installationContext = new InstallationContextImpl(descriptor); 159 installationContext.setInstall(false); 160 installationContext.setInstallRoot(installationDir); 161 File componentRoot = environmentContext.getComponentRootDir(componentName); 163 ComponentContextImpl context = buildComponentContext(componentRoot, installationDir, componentName); 164 installationContext.setContext(context); 165 InstallerMBeanImpl installer = new InstallerMBeanImpl(container, 166 installationContext); 167 return installer; 168 } 169 170 179 public boolean unloadInstaller(String componentName, boolean isToBeDeleted) { 180 boolean result = false; 181 try { 182 container.getBroker().suspend(); 183 InstallerMBeanImpl installer = (InstallerMBeanImpl) installers.remove(componentName); 184 result = installer != null; 185 if(result) { 186 container.getManagementContext().unregisterMBean(installer); 187 if (isToBeDeleted) { 188 installer.uninstall(); 189 } else { 190 nonLoadedInstallers.put(componentName, installer); 191 } 192 } 193 } catch(JBIException e) { 194 String errStr = "Problem shutting down Component: " + componentName; 195 log.error(errStr, e); 196 } finally { 197 container.getBroker().resume(); 198 } 199 return result; 200 } 201 202 209 public String installSharedLibrary(String aSharedLibURI){ 210 String result=""; 211 try{ 212 File tmpDir=AutoDeploymentService.unpackLocation(environmentContext.getTmpDir(),aSharedLibURI); 213 if(tmpDir!=null){ 214 Descriptor root=DescriptorFactory.buildDescriptor(tmpDir); 215 SharedLibrary sl=root.getSharedLibrary(); 216 if(sl!=null){ 217 result=doInstallSharedLibrary(tmpDir,sl); 218 } 219 }else{ 220 log.warn("location: "+aSharedLibURI+" isn't valid"); 221 } 222 }catch(DeploymentException e){ 223 log.error("Deployment failed",e); 224 } 225 return result; 226 } 227 228 235 public boolean uninstallSharedLibrary(String aSharedLibName) { 236 container.getRegistry().unregisterSharedLibrary(aSharedLibName); 239 environmentContext.removeSharedLibraryDirectory(aSharedLibName); 240 return true; 241 } 242 243 250 public void init(JBIContainer container) throws JBIException { 251 super.init(container); 252 this.environmentContext = container.getEnvironmentContext(); 253 this.managementContext = container.getManagementContext(); 254 buildState(); 255 } 256 257 protected Class getServiceMBean() { 258 return InstallationServiceMBean.class; 259 } 260 261 269 public void install(String location, Properties props, boolean autoStart) throws DeploymentException { 270 File tmpDir = AutoDeploymentService.unpackLocation(environmentContext.getTmpDir(),location); 271 if (tmpDir != null) { 272 Descriptor root = DescriptorFactory.buildDescriptor(tmpDir); 273 if (root != null) { 274 install(tmpDir, props, root, autoStart); 275 }else{ 276 log.error("Could not find Descriptor from: " + location); 277 } 278 }else{ 279 log.warn("location: "+location+" isn't valid"); 280 } 281 } 282 283 291 protected void install(File tmpDir, Properties props, Descriptor root, boolean autoStart) throws DeploymentException { 292 if (root.getComponent() != null) { 293 String componentName = root.getComponent().getIdentification().getName(); 294 if (installers.containsKey(componentName)) { 295 throw new DeploymentException("Component " + componentName + " is already installed"); 296 } 297 InstallerMBeanImpl installer = doInstallArchive(tmpDir,root); 298 if (installer != null) { 299 try { 300 if (props != null && props.size() > 0) { 301 ObjectName on = installer.getInstallerConfigurationMBean(); 302 if (on == null ) { 303 log.warn("Could not find installation configuration MBean. Installation properties will be ignored."); 304 } else { 305 MBeanServer mbs = managementContext.getMBeanServer(); 306 for (Iterator it = props.keySet().iterator(); it.hasNext();) { 307 String key = (String ) it.next(); 308 String val = props.getProperty(key); 309 try { 310 mbs.setAttribute(on, new Attribute (key, val)); 311 } catch (JMException e) { 312 throw new DeploymentException("Could not set installation property: (" + key + " = " + val, e); 313 } 314 } 315 } 316 } 317 installer.install(); 318 } catch(JBIException e) { 319 throw new DeploymentException(e); 320 } 321 if (autoStart) { 322 try{ 323 ComponentMBeanImpl lcc = container.getComponent(componentName); 324 if (lcc != null) { 325 lcc.start(); 326 }else{ 327 log.warn("No ComponentConnector found for Component "+componentName); 328 } 329 }catch(JBIException e){ 330 String errStr="Failed to start Component: "+componentName; 331 log.error(errStr,e); 332 throw new DeploymentException(e); 333 } 334 } 335 installers.put(componentName,installer); 336 } 337 } 338 } 339 340 346 public MBeanOperationInfo [] getOperationInfos() throws JMException { 347 OperationInfoHelper helper=new OperationInfoHelper(); 348 ParameterHelper ph=helper.addOperation(getObjectToManage(),"loadNewInstaller",1,"load a new Installer "); 349 ph.setDescription(0,"installJarURL","URL locating the install Jar"); 350 ph=helper.addOperation(getObjectToManage(),"loadInstaller",1, 351 "load installer for a previously installed component"); 352 ph.setDescription(0,"componentName","Name of the Component"); 353 ph=helper.addOperation(getObjectToManage(),"unloadInstaller",2,"unload an installer"); 354 ph.setDescription(0,"componentName","Name of the Component"); 355 ph.setDescription(1,"isToBeDeleted","true if component is to be deleted"); 356 ph=helper.addOperation(getObjectToManage(),"installSharedLibrary",1,"Install a shared library jar"); 357 ph.setDescription(0,"sharedLibURI","URI for the jar to be installed"); 358 ph=helper.addOperation(getObjectToManage(),"uninstallSharedLibrary",1,"Uninstall a shared library jar"); 359 ph.setDescription(0,"sharedLibName","name of the shared library"); 360 ph=helper.addOperation(getObjectToManage(),"install",1,"install and deplot an archive"); 361 ph.setDescription(0,"location","location of archive"); 362 ph=helper.addOperation(getObjectToManage(),"install",2,"install and deplot an archive"); 363 ph.setDescription(0,"location","location of archive"); 364 ph.setDescription(1,"autostart","automatically start the Component"); 365 return OperationInfoHelper.join(super.getOperationInfos(),helper.getOperationInfos()); 366 } 367 368 protected InstallerMBeanImpl doInstallArchive(File tmpDirectory,Descriptor descriptor) throws DeploymentException{ 369 InstallerMBeanImpl installer=null; 370 Component component=descriptor.getComponent(); 371 if(component!=null){ 372 installer=doInstallComponent(tmpDirectory,component); 373 } 374 return installer; 375 } 376 377 protected String doInstallSharedLibrary(File tmpDirectory, SharedLibrary descriptor) throws DeploymentException{ 378 String result = null; 379 if (descriptor != null) { 380 File installationDir = null; 381 try { 382 result = descriptor.getIdentification().getName(); 383 File rootDir = environmentContext.createSharedLibraryDirectory(result); 384 installationDir = FileVersionUtil.getNewVersionDirectory(rootDir); 385 if (!tmpDirectory.renameTo(installationDir)) { 386 throw new DeploymentException("Unable to rename " + tmpDirectory + " to " + installationDir); 387 } 388 if (log.isDebugEnabled()) { 389 log.debug("Moved " + tmpDirectory + " to " + installationDir); 390 } 391 container.getRegistry().registerSharedLibrary(descriptor, installationDir); 392 } catch (Exception e) { 393 log.error("Deployment of Shared Library failed", e); 394 FileUtil.deleteFile(installationDir); 396 throw new DeploymentException(e); 397 } finally { 398 FileUtil.deleteFile(tmpDirectory); 399 } 400 } 401 return result; 402 } 403 404 protected InstallerMBeanImpl doInstallComponent(File tmpDirectory,Component descriptor) throws DeploymentException{ 405 InstallerMBeanImpl result=null; 407 String name=descriptor.getIdentification().getName(); 408 try{ 409 File oldInstallationDir=environmentContext.getComponentInstallationDir(name); 410 if(!FileUtil.deleteFile(oldInstallationDir)){ 412 log.warn("Failed to delete old installation directory: " + oldInstallationDir.getPath()); 413 } 414 File componentRoot=environmentContext.createComponentRootDir(name); 415 File installationDir=environmentContext.getNewComponentInstallationDir(name); 417 tmpDirectory.renameTo(installationDir); 418 if (log.isDebugEnabled()) { 419 log.debug("Moved " + tmpDirectory + " to " + installationDir); 420 } 421 result=initializeInstaller(installationDir,componentRoot,descriptor); 422 return result; 423 }catch(IOException e){ 424 throw new DeploymentException(e); 425 } 426 } 427 428 private InstallerMBeanImpl initializeInstaller(File installationDir,File componentRoot,Component descriptor) 429 throws DeploymentException{ 430 InstallerMBeanImpl result=null; 431 try{ 432 String name=descriptor.getIdentification().getName(); 433 InstallationContextImpl installationContext=new InstallationContextImpl(descriptor); 434 installationContext.setInstall(true); 435 installationContext.setInstallRoot(installationDir); 436 ComponentContextImpl context = buildComponentContext(componentRoot, installationDir, name); 438 installationContext.setContext(context); 439 result = new InstallerMBeanImpl(container, 440 installationContext); 441 ObjectName objectName = managementContext.createCustomComponentMBeanName("Installer", name); 443 result.setObjectName(objectName); 444 managementContext.registerMBean(objectName,result,InstallerMBean.class, 445 "standard installation controls for a Component"); 446 }catch(Throwable e){ 447 log.error("Deployment of Component failed",e); 448 environmentContext.removeComponentRootDirectory(descriptor.getIdentification().getName()); 450 throw new DeploymentException(e); 451 } 452 return result; 453 } 454 455 protected void buildState(){ 456 buildSharedLibs(); 457 buildComponents(); 458 } 459 460 466 protected boolean containsSharedLibrary(String name){ 467 return container.getRegistry().getSharedLibrary(name) != null; 468 } 469 470 protected void buildSharedLibs(){ 471 File top = environmentContext.getSharedLibDir(); 473 if (top != null && top.exists() && top.isDirectory()) { 474 File [] files = top.listFiles(); 476 if (files != null) { 477 for (int i = 0; i < files.length; i++) { 478 if (files[i].isDirectory()) { 479 File dir = FileVersionUtil.getLatestVersionDirectory(files[i]); 480 if (dir != null) { 481 Descriptor root = DescriptorFactory.buildDescriptor(dir); 482 if (root != null) { 483 SharedLibrary sl = root.getSharedLibrary(); 484 if (sl != null) { 485 try { 486 container.getRegistry().registerSharedLibrary(sl, dir); 487 } catch (Exception e) { 488 log.error("Failed to initialize sharted library", e); 489 } 490 } 491 } 492 } 493 } 494 } 495 } 496 } 497 } 498 499 protected void buildComponents(){ 500 File top=environmentContext.getComponentsDir(); 502 if(top!=null&&top.exists()&&top.isDirectory()){ 503 File [] files=top.listFiles(); 505 if(files!=null){ 506 for(int i=0;i<files.length;i++){ 507 if(files[i].isDirectory()){ 508 final File directory=files[i]; 509 try{ 510 container.getWorkManager().doWork(new Work (){ 511 public void release(){} 512 513 public void run(){ 514 try{ 515 buildComponent(directory); 516 }catch(DeploymentException e){ 517 log.error("Could not build Component: "+directory.getName(),e); 518 log.warn("Deleting Component directory: "+directory); 519 FileUtil.deleteFile(directory); 520 } 521 } 522 }); 523 }catch(WorkException e){ 524 log.error("Could not build Component: "+directory.getName(),e); 525 log.warn("Deleting Component directory: "+directory); 526 FileUtil.deleteFile(directory); 527 } 528 } 529 } 530 } 531 } 532 } 533 534 protected void buildComponent(File componentDirectory) 535 throws DeploymentException { 536 try { 537 String componentName = componentDirectory.getName(); 538 ComponentEnvironment env = container.getEnvironmentContext().getComponentEnvironment(componentName); 539 if (!env.getStateFile().exists()) { 540 FileUtil.deleteFile(componentDirectory); 543 } else { 544 InstallerMBeanImpl installer = createInstaller(componentName); 545 installer.activateComponent(); 546 nonLoadedInstallers.put(componentName, installer); 547 } 548 } catch (Throwable e) { 549 log.error("Failed to deploy component: " 550 + componentDirectory.getName(), e); 551 throw new DeploymentException(e); 552 } 553 } 554 555 protected ComponentContextImpl buildComponentContext(File componentRoot, File installRoot, String name) 556 throws IOException { 557 ComponentNameSpace cns = new ComponentNameSpace(container.getName(), name); 558 ComponentContextImpl context = new ComponentContextImpl(container, cns); 559 ComponentEnvironment env = new ComponentEnvironment(); 560 FileUtil.buildDirectory(componentRoot); 561 File privateWorkspace = environmentContext.createWorkspaceDirectory(name); 562 env.setWorkspaceRoot(privateWorkspace); 563 env.setComponentRoot(componentRoot); 564 env.setInstallRoot(installRoot); 565 context.setEnvironment(env); 566 return context; 567 } 568 569 } 570 | Popular Tags |