com.sun.enterprise.v3.server.ApplicationLifecycle Maven / Gradle / Ivy
Show all versions of payara-micro Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2008-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2016] [Payara Foundation]
package com.sun.enterprise.v3.server;
import com.sun.enterprise.config.serverbeans.*;
import com.sun.enterprise.deploy.shared.ArchiveFactory;
import com.sun.enterprise.deploy.shared.FileArchive;
import com.sun.enterprise.util.LocalStringManagerImpl;
import java.beans.PropertyVetoException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.glassfish.api.*;
import org.glassfish.api.admin.ParameterMap;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.api.admin.config.ApplicationName;
import org.glassfish.api.container.Container;
import org.glassfish.api.container.Sniffer;
import org.glassfish.api.deployment.*;
import org.glassfish.api.deployment.archive.*;
import org.glassfish.api.event.*;
import org.glassfish.api.event.EventListener.Event;
import org.glassfish.api.virtualization.VirtualizationEnv;
import org.glassfish.common.util.admin.ParameterMapExtractor;
import org.glassfish.deployment.common.*;
import org.glassfish.deployment.monitor.DeploymentLifecycleProbeProvider;
import org.glassfish.deployment.versioning.VersioningSyntaxException;
import org.glassfish.deployment.versioning.VersioningUtils;
import org.glassfish.hk2.api.MultiException;
import org.glassfish.hk2.api.PostConstruct;
import org.glassfish.hk2.api.PreDestroy;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.classmodel.reflect.Parser;
import org.glassfish.hk2.classmodel.reflect.ParsingContext;
import org.glassfish.hk2.classmodel.reflect.Types;
import org.glassfish.internal.api.*;
import org.glassfish.internal.data.*;
import org.glassfish.internal.deployment.ApplicationLifecycleInterceptor;
import org.glassfish.internal.deployment.Deployment;
import org.glassfish.internal.deployment.DeploymentTracing;
import org.glassfish.internal.deployment.ExtendedDeploymentContext;
import org.glassfish.kernel.KernelLoggerInfo;
import org.glassfish.server.ServerEnvironmentImpl;
import org.jvnet.hk2.annotations.Optional;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.ConfigBean;
import org.jvnet.hk2.config.ConfigBeanProxy;
import org.jvnet.hk2.config.ConfigSupport;
import org.jvnet.hk2.config.RetryableException;
import org.jvnet.hk2.config.SingleConfigCode;
import org.jvnet.hk2.config.Transaction;
import org.jvnet.hk2.config.TransactionFailure;
import org.jvnet.hk2.config.types.Property;
/**
* Application Loader is providing useful methods to load applications
*
* @author Jerome Dochez, Sanjeeb Sahoo
*/
@Service
@Singleton
public class ApplicationLifecycle implements Deployment, PostConstruct {
private static final String[] UPLOADED_GENERATED_DIRS = new String [] {"policy", "xml", "ejb", "jsp"};
@Inject
protected SnifferManagerImpl snifferManager;
@Inject
ServiceLocator habitat;
@Inject
ArchiveFactory archiveFactory;
@Inject
ContainerRegistry containerRegistry;
@Inject
public ApplicationRegistry appRegistry;
@Inject
protected Applications applications;
@Inject @Named( ServerEnvironment.DEFAULT_INSTANCE_NAME)
Server server;
@Inject
protected Domain domain;
@Inject
ServerEnvironmentImpl env;
@Inject @Optional
VirtualizationEnv virtEnv;
@Inject
Events events;
@Inject
ConfigSupport configSupport;
protected Logger logger = KernelLoggerInfo.getLogger();
final private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(ApplicationLifecycle.class);
protected Deployer getDeployer(EngineInfo engineInfo) {
return engineInfo.getDeployer();
}
protected DeploymentLifecycleProbeProvider
deploymentLifecycleProbeProvider = null;
private ExecutorService executorService = null;
private Collection alcInterceptors = Collections.EMPTY_LIST;
public void postConstruct() {
executorService = createExecutorService();
deploymentLifecycleProbeProvider =
new DeploymentLifecycleProbeProvider();
alcInterceptors = habitat.getAllServices(
ApplicationLifecycleInterceptor.class);
}
/**
* Returns the ArchiveHandler for the passed archive abstraction or null
* if there are none.
*
* @param archive the archive to find the handler for
* @return the archive handler or null if not found.
* @throws IOException when an error occur
*/
public ArchiveHandler getArchiveHandler(ReadableArchive archive) throws IOException {
return getArchiveHandler(archive, null);
}
/**
* Returns the ArchiveHandler for the passed archive abstraction or null
* if there are none.
*
* @param archive the archive to find the handler for
* @param type the type of the archive
* @return the archive handler or null if not found.
* @throws IOException when an error occur
*/
public ArchiveHandler getArchiveHandler(ReadableArchive archive, String type) throws IOException {
if (type != null) {
return habitat.getService(ArchiveDetector.class, type).getArchiveHandler();
}
List detectors = new ArrayList(habitat.getAllServices(ArchiveDetector.class));
Collections.sort(detectors, new Comparator() {
// rank 2 is considered lower than rank 1, let's sort them in inceasing order
@Override
public int compare(ArchiveDetector o1, ArchiveDetector o2) {
return o1.rank() - o2.rank();
}
});
for (ArchiveDetector ad : detectors) {
if (ad.handles(archive)) {
return ad.getArchiveHandler();
}
}
return null;
}
public ApplicationInfo deploy(final ExtendedDeploymentContext context) {
return deploy(null, context);
}
public ApplicationInfo deploy(Collection extends Sniffer> sniffers, final ExtendedDeploymentContext context) {
long operationStartTime = Calendar.getInstance().getTimeInMillis();
events.send(new Event(Deployment.DEPLOYMENT_START, context), false);
final ActionReport report = context.getActionReport();
final DeployCommandParameters commandParams = context.getCommandParameters(DeployCommandParameters.class);
final String appName = commandParams.name();
if (commandParams.origin == OpsParams.Origin.deploy &&
appRegistry.get(appName) != null) {
report.setMessage(localStrings.getLocalString("appnamenotunique","Application name {0} is already in use. Please pick a different name.", appName));
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
return null;
}
// if the virtualservers param is not defined, set it to all
// defined virtual servers minus __asadmin on that target
if (commandParams.virtualservers == null) {
commandParams.virtualservers = DeploymentUtils.getVirtualServers(
commandParams.target, env, domain);
}
if (commandParams.enabled == null) {
commandParams.enabled = Boolean.TRUE;
}
if (commandParams.altdd != null) {
context.getSource().addArchiveMetaData(DeploymentProperties.ALT_DD, commandParams.altdd);
}
if (commandParams.runtimealtdd != null) {
context.getSource().addArchiveMetaData(DeploymentProperties.RUNTIME_ALT_DD, commandParams.runtimealtdd);
}
ProgressTracker tracker = new ProgressTracker() {
@Override
public void actOn(Logger logger) {
//loaded is used instead of started to include more modules to
//stop. In some modules, the setup and cleanup steps are not
//fully symmetric, and to ensure thorough cleanup, we need to
//call module.stop() for started modules, and modules that are
//loaded but may not be started. Issue 18263
for (EngineRef module : get("loaded", EngineRef.class)) {
try {
module.stop(context);
} catch (Exception e) {
// ignore
}
}
try {
PreDestroy.class.cast(context).preDestroy();
} catch (Exception e) {
// ignore
}
for (EngineRef module : get("loaded", EngineRef.class)) {
try {
module.unload(context);
} catch (Exception e) {
// ignore
}
}
try {
ApplicationInfo appInfo = appRegistry.get(appName);
if (appInfo != null) {
// send the event to close necessary resources
events.send(new Event(Deployment.APPLICATION_DISABLED, appInfo));
}
} catch (Exception e) {
// ignore
}
for (EngineRef module : get("prepared", EngineRef.class)) {
try {
module.clean(context);
} catch (Exception e) {
// ignore
}
}
// comment this out for now as the interceptor seems to use
// a different hook to roll back failure
// notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.REPLICATION, context);
if (!commandParams.keepfailedstubs) {
try {
context.clean();
} catch (Exception e) {
// ignore
}
}
appRegistry.remove(appName);
}
};
context.addTransientAppMetaData(ExtendedDeploymentContext.TRACKER,
tracker);
context.setPhase(DeploymentContextImpl.Phase.PREPARE);
ApplicationInfo appInfo = null;
try {
ArchiveHandler handler = context.getArchiveHandler();
if (handler == null) {
handler = getArchiveHandler(context.getSource(),
commandParams.type);
context.setArchiveHandler(handler);
}
if (handler==null) {
report.setMessage(localStrings.getLocalString("unknownarchivetype","Archive type of {0} was not recognized",context.getSourceDir()));
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
return null;
}
DeploymentTracing tracing = context.getModuleMetaData(DeploymentTracing.class);
if (tracing!=null) {
tracing.addMark(DeploymentTracing.Mark.ARCHIVE_HANDLER_OBTAINED);
}
if (handler.requiresAnnotationScanning(context.getSource())) {
getDeployableTypes(context);
}
if (tracing!=null) {
tracing.addMark(DeploymentTracing.Mark.PARSING_DONE);
}
// containers that are started are not stopped even if
// the deployment fail, the main reason
// is that some container do not support to be restarted.
if (sniffers!=null && logger.isLoggable(Level.FINE)) {
for (Sniffer sniffer : sniffers) {
logger.fine("Before Sorting" + sniffer.getModuleType());
}
}
sniffers = getSniffers(handler, sniffers, context);
ClassLoaderHierarchy clh = habitat.getService(ClassLoaderHierarchy.class);
if (tracing!=null) {
tracing.addMark(DeploymentTracing.Mark.CLASS_LOADER_HIERARCHY);
}
context.createDeploymentClassLoader(clh, handler);
events.send(new Event(Deployment.AFTER_DEPLOYMENT_CLASSLOADER_CREATION, context), false);
if (tracing!=null) {
tracing.addMark(DeploymentTracing.Mark.CLASS_LOADER_CREATED);
}
final ClassLoader cloader = context.getClassLoader();
final ClassLoader currentCL = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(cloader);
List sortedEngineInfos =
setupContainerInfos(handler, sniffers, context);
if (tracing!=null) {
tracing.addMark(DeploymentTracing.Mark.CONTAINERS_SETUP_DONE);
}
if (logger.isLoggable(Level.FINE)) {
for (EngineInfo info : sortedEngineInfos) {
logger.fine("After Sorting " + info.getSniffer().getModuleType());
}
}
if (sortedEngineInfos ==null || sortedEngineInfos.isEmpty()) {
report.failure(logger, localStrings.getLocalString("unknowncontainertype","There is no installed container capable of handling this application {0}",context.getSource().getName()));
tracker.actOn(logger);
return null;
}
// create a temporary application info to hold metadata
// so the metadata could be accessed at classloader
// construction time through ApplicationInfo
ApplicationInfo tempAppInfo = new ApplicationInfo(events,
context.getSource(), appName);
for (Object m : context.getModuleMetadata()) {
tempAppInfo.addMetaData(m);
}
tempAppInfo.setIsJavaEEApp(sortedEngineInfos);
// set the flag on the archive to indicate whether it's
// a JavaEE archive or not
context.getSource().setExtraData(Boolean.class, tempAppInfo.isJavaEEApp());
appRegistry.add(appName, tempAppInfo);
try {
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.PREPARE, context);
} catch(Throwable interceptorException) {
report.failure(logger, "Exception while invoking the lifecycle interceptor", null);
report.setFailureCause(interceptorException);
logger.log(Level.SEVERE, KernelLoggerInfo.lifecycleException, interceptorException);
tracker.actOn(logger);
return null;
}
events.send(new Event(Deployment.DEPLOYMENT_BEFORE_CLASSLOADER_CREATION, context), false);
context.createApplicationClassLoader(clh, handler);
events.send(new Event(Deployment.AFTER_APPLICATION_CLASSLOADER_CREATION, context), false);
if (tracing!=null) {
tracing.addMark(DeploymentTracing.Mark.CLASS_LOADER_CREATED);
}
// this is a first time deployment as opposed as load following an unload event,
// we need to create the application info
// todo : we should come up with a general Composite API solution
ModuleInfo moduleInfo = null;
try {
moduleInfo = prepareModule(sortedEngineInfos, appName, context, tracker);
// Now that the prepare phase is done, any artifacts
// should be available. Go ahead and create the
// downloadable client JAR. We want to do this now, or
// at least before the load and start phases, because
// (for example) the app client deployer start phase
// needs to find all generated files when it runs.
final ClientJarWriter cjw = new ClientJarWriter(context);
cjw.run();
} catch(Throwable prepareException) {
prepareException.printStackTrace();
report.failure(logger, "Exception while preparing the app", null);
report.setFailureCause(prepareException);
logger.log(Level.SEVERE, KernelLoggerInfo.lifecycleException, prepareException);
tracker.actOn(logger);
return null;
}
// the deployer did not take care of populating the application info, this
// is not a composite module.
appInfo=context.getModuleMetaData(ApplicationInfo.class);
if (appInfo==null) {
appInfo = new ApplicationInfo(events, context.getSource(), appName);
appInfo.addModule(moduleInfo);
for (Object m : context.getModuleMetadata()) {
moduleInfo.addMetaData(m);
appInfo.addMetaData(m);
}
} else {
for (EngineRef ref : moduleInfo.getEngineRefs()) {
appInfo.add(ref);
}
}
// remove the temp application info from the registry
// first, then register the real one
appRegistry.remove(appName);
appInfo.setIsJavaEEApp(sortedEngineInfos);
appRegistry.add(appName, appInfo);
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.PREPARE, context);
if (tracing!=null) {
tracing.addMark(DeploymentTracing.Mark.PREPARED);
}
// send the APPLICATION_PREPARED event
// set the phase and thread context classloader properly
// before sending the event
context.setPhase(DeploymentContextImpl.Phase.PREPARED);
Thread.currentThread().setContextClassLoader(context.getClassLoader());
appInfo.setAppClassLoader(context.getClassLoader());
events.send(new Event(Deployment.APPLICATION_PREPARED, context), false);
// now were falling back into the mainstream loading/starting sequence, at this
// time the containers are set up, all the modules have been prepared in their
// associated engines and the application info is created and registered
if (loadOnCurrentInstance(context)) {
appInfo.setLibraries(commandParams.libraries());
try {
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.LOAD, context);
appInfo.load(context, tracker);
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.LOAD, context);
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.START, context);
appInfo.start(context, tracker);
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.START, context);
} catch(Throwable loadException) {
logger.log(Level.SEVERE, KernelLoggerInfo.lifecycleException, loadException);
report.failure(logger, "Exception while loading the app", null);
report.setFailureCause(loadException);
tracker.actOn(logger);
return null;
}
}
return appInfo;
} finally {
context.postDeployClean(false /* not final clean-up yet */);
Thread.currentThread().setContextClassLoader(currentCL);
}
} catch (Throwable e) {
report.failure(logger, localStrings.getLocalString("error.deploying.app", "Exception while deploying the app [{0}]", appName), null);
report.setFailureCause(e);
logger.log(Level.SEVERE, KernelLoggerInfo.lifecycleException, e);
tracker.actOn(logger);
return null;
} finally {
if (report.getActionExitCode()==ActionReport.ExitCode.SUCCESS) {
events.send(new Event(Deployment.DEPLOYMENT_SUCCESS, appInfo));
long operationTime = Calendar.getInstance().getTimeInMillis() - operationStartTime;
if (appInfo != null) {
deploymentLifecycleProbeProvider.applicationDeployedEvent(appName, getApplicationType(appInfo), String.valueOf(operationTime));
}
} else {
events.send(new Event(Deployment.DEPLOYMENT_FAILURE, context));
}
}
}
@Override
public Types getDeployableTypes(DeploymentContext context) throws IOException {
synchronized(context) {
Types types = context.getTransientAppMetaData(Types.class.getName(), Types.class);
if (types!=null) {
return types;
} else {
try {
// scan the jar and store the result in the deployment context.
ParsingContext parsingContext = new ParsingContext.Builder().logger(context.getLogger()).executorService(executorService).build();
Parser parser = new Parser(parsingContext);
ReadableArchiveScannerAdapter scannerAdapter = new ReadableArchiveScannerAdapter(parser, context.getSource());
parser.parse(scannerAdapter, null);
for (ReadableArchive externalLibArchive :
getExternalLibraries(context)) {
ReadableArchiveScannerAdapter libAdapter = null;
try {
libAdapter = new ReadableArchiveScannerAdapter(parser, externalLibArchive);
parser.parse(libAdapter, null);
} finally {
if (libAdapter!=null) {
libAdapter.close();
}
}
}
parser.awaitTermination();
scannerAdapter.close();
context.addTransientAppMetaData(Types.class.getName(), parsingContext.getTypes());
context.addTransientAppMetaData(Parser.class.getName(), parser);
return parsingContext.getTypes();
} catch(InterruptedException e) {
throw new IOException(e);
}
}
}
}
private void notifyLifecycleInterceptorsBefore(final ExtendedDeploymentContext.Phase phase,
final ExtendedDeploymentContext dc) {
for (ApplicationLifecycleInterceptor i : alcInterceptors) {
i.before(phase, dc);
}
}
private void notifyLifecycleInterceptorsAfter(final ExtendedDeploymentContext.Phase phase,
final ExtendedDeploymentContext dc) {
for (ApplicationLifecycleInterceptor i : alcInterceptors) {
i.after(phase, dc);
}
}
private List getExternalLibraries(
DeploymentContext context) throws IOException {
List externalLibArchives = new ArrayList();
String skipScanExternalLibProp = context.getAppProps().getProperty(
DeploymentProperties.SKIP_SCAN_EXTERNAL_LIB);
if (Boolean.valueOf(skipScanExternalLibProp)) {
// if we skip scanning external libraries, we should just
// return an empty list here
return Collections.EMPTY_LIST;
}
List externalLibs = DeploymentUtils.getExternalLibraries(context.getSource());
for (URI externalLib : externalLibs) {
externalLibArchives.add(archiveFactory.openArchive(new File(externalLib.getPath())));
}
return externalLibArchives;
}
/**
* Suspends this application.
*
* @param appName the registration application ID
* @return true if suspending was successful, false otherwise.
*/
public boolean suspend(String appName) {
boolean isSuccess = true;
ApplicationInfo appInfo = appRegistry.get(appName);
if (appInfo != null) {
isSuccess = appInfo.suspend(logger);
}
return isSuccess;
}
/**
* Resumes this application.
*
* @param appName the registration application ID
* @return true if resumption was successful, false otherwise.
*/
public boolean resume(String appName) {
boolean isSuccess = true;
ApplicationInfo appInfo = appRegistry.get(appName);
if (appInfo != null) {
isSuccess = appInfo.resume(logger);
}
return isSuccess;
}
public List setupContainerInfos(DeploymentContext context)
throws Exception {
return setupContainerInfos(context.getArchiveHandler(), getSniffers(context.getArchiveHandler(), null, context), context);
}
public Collection extends Sniffer> getSniffers(final ArchiveHandler handler, Collection extends Sniffer> sniffers, DeploymentContext context) {
if (handler == null) {
return Collections.EMPTY_LIST;
}
if (sniffers==null) {
if (handler instanceof CompositeHandler) {
((CompositeHandler)handler).initCompositeMetaData(context);
context.getAppProps().setProperty(ServerTags.IS_COMPOSITE, "true");
}
sniffers = snifferManager.getSniffers(context);
}
context.addTransientAppMetaData(DeploymentProperties.SNIFFERS, sniffers);
snifferManager.validateSniffers(sniffers, context);
return sniffers;
}
// set up containers and prepare the sorted ModuleInfos
public List setupContainerInfos(final ArchiveHandler handler,
Collection extends Sniffer> sniffers, DeploymentContext context)
throws Exception {
final ActionReport report = context.getActionReport();
DeploymentTracing tracing = context.getModuleMetaData(DeploymentTracing.class);
Map containerInfosByDeployers = new LinkedHashMap();
for (Sniffer sniffer : sniffers) {
if (sniffer.getContainersNames() == null || sniffer.getContainersNames().length == 0) {
report.failure(logger, "no container associated with application of type : " + sniffer.getModuleType(), null);
return null;
}
final String containerName = sniffer.getContainersNames()[0];
if (tracing!=null) {
tracing.addContainerMark(DeploymentTracing.ContainerMark.SNIFFER_DONE, containerName );
}
// start all the containers associated with sniffers.
EngineInfo engineInfo = containerRegistry.getContainer(containerName);
if (engineInfo == null) {
// need to synchronize on the registry to not end up starting the same container from
// different threads.
Collection containersInfo=null;
synchronized (containerRegistry) {
if (containerRegistry.getContainer(containerName) == null) {
if (tracing!=null) {
tracing.addContainerMark(
DeploymentTracing.ContainerMark.BEFORE_CONTAINER_SETUP, containerName );
}
containersInfo = setupContainer(sniffer, logger, context);
if (tracing!=null) {
tracing.addContainerMark(
DeploymentTracing.ContainerMark.AFTER_CONTAINER_SETUP, containerName );
}
if (containersInfo == null || containersInfo.size() == 0) {
String msg = "Cannot start container(s) associated to application of type : " + sniffer.getModuleType();
report.failure(logger, msg, null);
throw new Exception(msg);
}
}
}
// now start all containers, by now, they should be all setup...
if (containersInfo != null && !startContainers(containersInfo, logger, context)) {
final String msg = "Aborting, Failed to start container " + containerName;
report.failure(logger, msg, null);
throw new Exception(msg);
}
}
engineInfo = containerRegistry.getContainer(sniffer.getContainersNames()[0]);
if (tracing!=null) {
tracing.addContainerMark(
DeploymentTracing.ContainerMark.GOT_CONTAINER, containerName );
}
if (engineInfo ==null) {
final String msg = "Aborting, Failed to start container " + containerName;
report.failure(logger, msg, null);
throw new Exception(msg);
}
Deployer deployer = getDeployer(engineInfo);
if (deployer==null) {
if (!startContainers(Collections.singleton(engineInfo), logger, context)) {
final String msg = "Aborting, Failed to start container " + containerName;
report.failure(logger, msg, null);
throw new Exception(msg);
}
deployer = getDeployer(engineInfo);
if (deployer == null) {
report.failure(logger, "Got a null deployer out of the " + engineInfo.getContainer().getClass() + " container, is it annotated with @Service ?");
return null;
}
}
if (tracing!=null) {
tracing.addContainerMark(
DeploymentTracing.ContainerMark.GOT_DEPLOYER, containerName );
}
containerInfosByDeployers.put(deployer, engineInfo);
}
// all containers that have recognized parts of the application being deployed
// have now been successfully started. Start the deployment process.
List providers = new LinkedList();
providers.addAll(habitat.getAllServices(ApplicationMetaDataProvider.class));
List sortedEngineInfos = new ArrayList();
Map typeByProvider = new HashMap();
for (ApplicationMetaDataProvider provider : habitat.getAllServices(ApplicationMetaDataProvider.class)) {
if (provider.getMetaData()!=null) {
for (Class provided : provider.getMetaData().provides()) {
typeByProvider.put(provided, provider);
}
}
}
// check if everything is provided.
for (ApplicationMetaDataProvider provider : habitat.getAllServices(ApplicationMetaDataProvider.class)) {
if (provider.getMetaData()!=null) {
for (Class dependency : provider.getMetaData().requires()) {
if (!typeByProvider.containsKey(dependency)) {
// at this point, I only log problems, because it maybe that what I am deploying now
// will not require this application metadata.
logger.log(Level.WARNING, KernelLoggerInfo.applicationMetaDataProvider,
new Object[] {provider, dependency});
}
}
}
}
Map typeByDeployer = new HashMap();
for (Deployer deployer : containerInfosByDeployers.keySet()) {
if (deployer.getMetaData()!=null) {
for (Class provided : deployer.getMetaData().provides()) {
typeByDeployer.put(provided, deployer);
}
}
}
for (Deployer deployer : containerInfosByDeployers.keySet()) {
if (deployer.getMetaData()!=null) {
for (Class dependency : deployer.getMetaData().requires()) {
if (!typeByDeployer.containsKey(dependency) && !typeByProvider.containsKey(dependency)) {
Service s = deployer.getClass().getAnnotation(Service.class);
String serviceName;
if (s!=null && s.name()!=null && s.name().length()>0) {
serviceName = s.name();
} else {
serviceName = deployer.getClass().getSimpleName();
}
report.failure(logger, serviceName + " deployer requires " + dependency + " but no other deployer provides it", null);
return null;
}
}
}
}
// ok everything is satisfied, just a matter of running things in order
List orderedDeployers = new ArrayList();
for (Deployer deployer : containerInfosByDeployers.keySet()) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Keyed Deployer " + deployer.getClass());
}
loadDeployer(orderedDeployers, deployer, typeByDeployer, typeByProvider, context);
}
// now load metadata from deployers.
for (Deployer deployer : orderedDeployers) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Ordered Deployer " + deployer.getClass());
}
final MetaData metadata = deployer.getMetaData();
try {
if (metadata!=null) {
if (metadata.provides()==null || metadata.provides().length==0) {
deployer.loadMetaData(null, context);
} else {
for (Class> provide : metadata.provides()) {
if (context.getModuleMetaData(provide)==null) {
context.addModuleMetaData(deployer.loadMetaData(provide, context));
} else {
deployer.loadMetaData(null, context);
}
}
}
} else {
deployer.loadMetaData(null, context);
}
} catch(Exception e) {
report.failure(logger, "Exception while invoking " + deployer.getClass() + " prepare method", e);
throw e;
}
sortedEngineInfos.add(containerInfosByDeployers.get(deployer));
}
return sortedEngineInfos;
}
private void loadDeployer(List results, Deployer deployer, Map typeByDeployer, Map typeByProvider, DeploymentContext dc)
throws IOException {
if (results.contains(deployer)) {
return;
}
results.add(deployer);
if (deployer.getMetaData()!=null) {
for (Class required : deployer.getMetaData().requires()) {
if (dc.getModuleMetaData(required)!=null) {
continue;
}
if (typeByDeployer.containsKey(required)) {
loadDeployer(results,typeByDeployer.get(required), typeByDeployer, typeByProvider, dc);
} else {
ApplicationMetaDataProvider provider = typeByProvider.get(required);
if (provider==null) {
logger.log(Level.SEVERE, KernelLoggerInfo.inconsistentLifecycleState, required);
} else {
LinkedList providers = new LinkedList();
addRecursively(providers, typeByProvider, provider);
for (ApplicationMetaDataProvider p : providers) {
dc.addModuleMetaData(p.load(dc));
}
}
}
}
}
}
private void addRecursively(LinkedList results, Map providers, ApplicationMetaDataProvider provider) {
results.addFirst(provider);
for (Class type : provider.getMetaData().requires()) {
if (providers.containsKey(type)) {
addRecursively(results, providers, providers.get(type));
}
}
}
public ModuleInfo prepareModule(
List sortedEngineInfos, String moduleName,
DeploymentContext context,
ProgressTracker tracker) throws Exception {
ActionReport report = context.getActionReport();
List addedEngines = new ArrayList();
DeploymentTracing tracing = context.getModuleMetaData(DeploymentTracing.class);
if (tracing!=null) {
tracing.addModuleMark(DeploymentTracing.ModuleMark.PREPARE,
moduleName);
}
for (EngineInfo engineInfo : sortedEngineInfos) {
// get the deployer
Deployer deployer = engineInfo.getDeployer();
try {
if (tracing!=null) {
tracing.addContainerMark(DeploymentTracing.ContainerMark.PREPARE,
engineInfo.getSniffer().getModuleType() );
}
deployer.prepare(context);
if (tracing!=null) {
tracing.addContainerMark(DeploymentTracing.ContainerMark.PREPARED,
engineInfo.getSniffer().getModuleType() );
}
// construct an incomplete EngineRef which will be later
// filled in at loading time
EngineRef engineRef = new EngineRef(engineInfo, null);
addedEngines.add(engineRef);
tracker.add("prepared", EngineRef.class, engineRef);
tracker.add(Deployer.class, deployer);
} catch(Exception e) {
report.failure(logger, "Exception while invoking " + deployer.getClass() + " prepare method", e);
throw e;
}
}
if (tracing!=null) {
tracing.addModuleMark(DeploymentTracing.ModuleMark.PREPARE_EVENTS, moduleName);
}
if (events!=null) {
events.send(new Event(Deployment.MODULE_PREPARED, context), false);
}
if (tracing!=null) {
tracing.addModuleMark(DeploymentTracing.ModuleMark.PREPARED,moduleName);
}
// I need to create the application info here from the context, or something like this.
// and return the application info from this method for automatic registration in the caller.
// set isComposite property on module props so we know whether to persist
// module level properties inside ModuleInfo
String isComposite = context.getAppProps().getProperty(
ServerTags.IS_COMPOSITE);
if (isComposite != null) {
context.getModuleProps().setProperty(ServerTags.IS_COMPOSITE, isComposite);
}
ModuleInfo mi = new ModuleInfo(events, moduleName, addedEngines,
context.getModuleProps());
/*
* Save the application config that is potentially attached to each
* engine in the corresponding EngineRefs that have already created.
*
* Later, in registerAppInDomainXML, the appInfo is saved, which in
* turn saves the moduleInfo children and their engineRef children.
* Saving the engineRef assigns the application config to the Engine
* which corresponds directly to the element in the XML.
* A long way to get this done.
*/
// Application existingApp = applications.getModule(Application.class, moduleName);
// if (existingApp != null) {
ApplicationConfigInfo savedAppConfig = new ApplicationConfigInfo(context.getAppProps());
for (EngineRef er : mi.getEngineRefs()) {
ApplicationConfig c = savedAppConfig.get(mi.getName(),
er.getContainerInfo().getSniffer().getModuleType());
if (c != null) {
er.setApplicationConfig(c);
}
}
// }
return mi;
}
protected Collection setupContainer(Sniffer sniffer, Logger logger, DeploymentContext context) {
ActionReport report = context.getActionReport();
ContainerStarter starter = habitat.getService(ContainerStarter.class);
Collection containersInfo = starter.startContainer(sniffer);
if (containersInfo == null || containersInfo.size()==0) {
report.failure(logger, "Cannot start container(s) associated to application of type : " + sniffer.getModuleType(), null);
return null;
}
return containersInfo;
}
protected boolean startContainers(Collection containersInfo, Logger logger, DeploymentContext context) {
ActionReport report = context.getActionReport();
for (EngineInfo engineInfo : containersInfo) {
Container container;
try {
container = engineInfo.getContainer();
} catch(Exception e) {
logger.log(Level.SEVERE, KernelLoggerInfo.cantStartContainer,
new Object[] {engineInfo.getSniffer().getModuleType(), e});
return false;
}
Class extends Deployer> deployerClass = container.getDeployer();
Deployer deployer;
try {
deployer = habitat.getService(deployerClass);
engineInfo.setDeployer(deployer);
} catch (MultiException e) {
report.failure(logger, "Cannot instantiate or inject "+deployerClass, e);
engineInfo.stop(logger);
return false;
} catch (ClassCastException e) {
engineInfo.stop(logger);
report.failure(logger, deployerClass+" does not implement " +
" the org.jvnet.glassfish.api.deployment.Deployer interface", e);
return false;
}
}
return true;
}
protected void stopContainers(EngineInfo[] ctrInfos, Logger logger) {
for (EngineInfo ctrInfo : ctrInfos) {
try {
ctrInfo.stop(logger);
} catch(Exception e) {
// this is not a failure per se but we need to document it.
logger.log(Level.INFO, KernelLoggerInfo.cantReleaseContainer,
new Object[] {ctrInfo.getSniffer().getModuleType(), e});
}
}
}
public ApplicationInfo unload(ApplicationInfo info, ExtendedDeploymentContext context) {
ActionReport report = context.getActionReport();
if (info==null) {
report.failure(context.getLogger(), "Application not registered", null);
return null;
}
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.STOP, context);
if (info.isLoaded()) {
info.stop(context, context.getLogger());
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.STOP, context);
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.UNLOAD, context);
info.unload(context);
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.UNLOAD, context);
}
events.send(new Event(Deployment.APPLICATION_DISABLED, info), false);
try {
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.CLEAN, context);
info.clean(context);
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.CLEAN, context);
} catch(Exception e) {
report.failure(context.getLogger(), "Exception while cleaning", e);
return info;
}
return info;
}
public void undeploy(String appName, ExtendedDeploymentContext context) {
ActionReport report = context.getActionReport();
UndeployCommandParameters params = context.getCommandParameters(UndeployCommandParameters.class);
ApplicationInfo info = appRegistry.get(appName);
if (info==null) {
report.failure(context.getLogger(), "Application " + appName + " not registered", null);
events.send(new Event(Deployment.UNDEPLOYMENT_FAILURE, context));
return;
}
events.send(new Event(Deployment.UNDEPLOYMENT_START, info));
// we unconditionally unload the application, even if it is not loaded, because we must clean the
// application, especially the classloaders need to be closed to release file handles
unload(info, context);
if (report != null && report.getActionExitCode().equals(ActionReport.ExitCode.SUCCESS)) {
events.send(new Event(Deployment.UNDEPLOYMENT_SUCCESS, context));
deploymentLifecycleProbeProvider.applicationUndeployedEvent(appName, getApplicationType(info));
} else {
events.send(new Event(Deployment.UNDEPLOYMENT_FAILURE, context));
}
appRegistry.remove(appName);
}
// prepare application config change for later registering
// in the domain.xml
public Transaction prepareAppConfigChanges(final DeploymentContext context)
throws TransactionFailure {
final Properties appProps = context.getAppProps();
final DeployCommandParameters deployParams = context.getCommandParameters(DeployCommandParameters.class);
Transaction t = new Transaction();
try {
// prepare the application element
ConfigBean newBean = ((ConfigBean)ConfigBean.unwrap(applications)).allocate(Application.class);
Application app = newBean.createProxy();
Application app_w = t.enroll(app);
setInitialAppAttributes(app_w, deployParams, appProps, context);
context.addTransientAppMetaData(ServerTags.APPLICATION, app_w);
} catch(TransactionFailure e) {
t.rollback();
throw e;
} catch (Exception e) {
t.rollback();
throw new TransactionFailure(e.getMessage(), e);
}
return t;
}
// register application information in domain.xml
public void registerAppInDomainXML(final ApplicationInfo
applicationInfo, final DeploymentContext context, Transaction t)
throws TransactionFailure {
registerAppInDomainXML(applicationInfo, context, t, false);
}
// register application information in domain.xml
public void registerAppInDomainXML(final ApplicationInfo
applicationInfo, final DeploymentContext context, Transaction t,
boolean appRefOnly)
throws TransactionFailure {
final Properties appProps = context.getAppProps();
final DeployCommandParameters deployParams = context.getCommandParameters(DeployCommandParameters.class);
if (t != null) {
try {
if (!appRefOnly) {
Application app_w = context.getTransientAppMetaData(
ServerTags.APPLICATION, Application.class);
// adding the application element
setRestAppAttributes(app_w, appProps);
Applications apps_w = t.enroll(applications);
apps_w.getModules().add(app_w);
if (applicationInfo != null) {
applicationInfo.save(app_w);
}
}
List targets = new ArrayList();
if (!DeploymentUtils.isDomainTarget(deployParams.target)) {
targets.add(deployParams.target);
} else {
List previousTargets = context.getTransientAppMetaData(DeploymentProperties.PREVIOUS_TARGETS, List.class);
if (previousTargets == null) {
previousTargets = domain.getAllReferencedTargetsForApplication(deployParams.name);
}
targets = previousTargets;
}
String origVS = deployParams.virtualservers;
Boolean origEnabled = deployParams.enabled;
Properties previousVirtualServers = context.getTransientAppMetaData(DeploymentProperties.PREVIOUS_VIRTUAL_SERVERS, Properties.class);
Properties previousEnabledAttributes = context.getTransientAppMetaData(DeploymentProperties.PREVIOUS_ENABLED_ATTRIBUTES, Properties.class);
for (String target : targets) {
// first reset the virtualservers, enabled attribute
deployParams.virtualservers = origVS;
deployParams.enabled = origEnabled;
// now if the target is domain target,
// restore the previous attributes if
// applicable
if (DeploymentUtils.isDomainTarget(deployParams.target)) {
String vs = previousVirtualServers.getProperty(target);
if (vs != null) {
deployParams.virtualservers = vs;
}
String enabledAttr = previousEnabledAttributes.getProperty(target);
if (enabledAttr != null) {
deployParams.enabled = Boolean.valueOf(enabledAttr);
}
}
if (deployParams.enabled == null) {
deployParams.enabled = Boolean.TRUE;
}
Server servr = domain.getServerNamed(target);
if (servr != null) {
// adding the application-ref element to the standalone
// server instance
ConfigBeanProxy servr_w = t.enroll(servr);
// adding the application-ref element to the standalone
// server instance
ApplicationRef appRef = servr_w.createChild(ApplicationRef.class);
setAppRefAttributes(appRef, deployParams);
((Server)servr_w).getApplicationRef().add(appRef);
}
Cluster cluster = domain.getClusterNamed(target);
if (cluster != null) {
// adding the application-ref element to the cluster
// and instances
ConfigBeanProxy cluster_w = t.enroll(cluster);
ApplicationRef appRef = cluster_w.createChild(ApplicationRef.class);
setAppRefAttributes(appRef, deployParams);
((Cluster)cluster_w).getApplicationRef().add(appRef);
for (Server svr : cluster.getInstances() ) {
ConfigBeanProxy svr_w = t.enroll(svr);
ApplicationRef appRef2 = svr_w.createChild(ApplicationRef.class);
setAppRefAttributes(appRef2, deployParams);
((Server)svr_w).getApplicationRef().add(appRef2);
}
}
}
} catch(TransactionFailure e) {
t.rollback();
throw e;
} catch (Exception e) {
t.rollback();
throw new TransactionFailure(e.getMessage(), e);
}
try {
t.commit();
} catch (RetryableException e) {
System.out.println("Retryable...");
// TODO : do something meaninful here
t.rollback();
} catch (TransactionFailure e) {
t.rollback();
throw e;
}
}
}
public void registerTenantWithAppInDomainXML(
final String appName,
final ExtendedDeploymentContext context) throws TransactionFailure {
final Transaction t = new Transaction();
try {
final AppTenant appTenant_w = writeableTenantForApp(
appName,
t);
appTenant_w.setContextRoot(context.getAppProps().getProperty(ServerTags.CONTEXT_ROOT));
appTenant_w.setTenant(context.getTenant());
t.commit();
} catch (TransactionFailure ex) {
t.rollback();
throw ex;
} catch (Throwable ex) {
t.rollback();
throw new TransactionFailure(ex.getLocalizedMessage(), ex);
}
}
public void unregisterTenantWithAppInDomainXML(
final String appName,
final String tenantName
) throws TransactionFailure, RetryableException {
final com.sun.enterprise.config.serverbeans.Application app =
applications.getApplication(appName);
if (app == null) {
throw new IllegalArgumentException("Application " + appName + " not found");
}
final AppTenants appTenants = app.getAppTenants();
final AppTenant appTenant = appTenants.getAppTenant(tenantName);
if (appTenant == null) {
throw new IllegalArgumentException("Tenant " + tenantName + " not provisioned for application " + appName);
}
Transaction t = new Transaction();
final AppTenants appTenants_w = t.enroll(appTenants);
appTenants_w.getAppTenant().remove(appTenant);
t.commit();
}
private AppTenant writeableTenantForApp(
final String appName,
final Transaction t) throws TransactionFailure, PropertyVetoException {
final com.sun.enterprise.config.serverbeans.Application app =
applications.getApplication(appName);
if (app == null) {
throw new IllegalArgumentException("Application " + appName + " not found");
}
/*
* The app-tenants subelement might or might not already be there.
*/
AppTenants appTenants = app.getAppTenants();
AppTenants appTenants_w;
if (appTenants == null) {
com.sun.enterprise.config.serverbeans.Application app_w =
t.enroll(app);
appTenants_w = app_w.createChild(AppTenants.class);
app_w.setAppTenants(appTenants_w);
} else {
appTenants_w = t.enroll(appTenants);
}
final List appTenantList = appTenants_w.getAppTenant();
AppTenant appTenant_w = appTenants_w.createChild(AppTenant.class);
appTenantList.add(appTenant_w);
return appTenant_w;
}
// application attributes that are set in the beginning of the deployment
// that will not be changed in the course of the deployment
private void setInitialAppAttributes(Application app,
DeployCommandParameters deployParams, Properties appProps,
DeploymentContext context)
throws PropertyVetoException {
Properties previousEnabledAttributes = context.getTransientAppMetaData(DeploymentProperties.PREVIOUS_ENABLED_ATTRIBUTES, Properties.class);
// various attributes
app.setName(deployParams.name);
if (deployParams.libraries != null) {
app.setLibraries(deployParams.libraries);
}
if (deployParams.description != null) {
app.setDescription(deployParams.description);
}
if (deployParams.deploymentorder != null) {
app.setDeploymentOrder(deployParams.deploymentorder.toString());
}
app.setEnabled(String.valueOf(true));
if (appProps.getProperty(ServerTags.LOCATION) != null) {
app.setLocation(appProps.getProperty(
ServerTags.LOCATION));
// when redeploy to domain we preserve the enable
// attribute
if (DeploymentUtils.isDomainTarget(deployParams.target)) {
if (previousEnabledAttributes != null) {
String enabledAttr = previousEnabledAttributes.getProperty(DeploymentUtils.DOMAIN_TARGET_NAME);
if (enabledAttr != null) {
app.setEnabled(enabledAttr);
}
}
}
app.setAvailabilityEnabled(deployParams.availabilityenabled.toString());
app.setAsyncReplication(deployParams.asyncreplication.toString());
}
if (appProps.getProperty(ServerTags.OBJECT_TYPE) != null) {
app.setObjectType(appProps.getProperty(
ServerTags.OBJECT_TYPE));
}
if (appProps.getProperty(ServerTags.DIRECTORY_DEPLOYED)
!= null) {
app.setDirectoryDeployed(appProps.getProperty(
ServerTags.DIRECTORY_DEPLOYED));
}
}
// set the rest of the application attributes at the end of the
// deployment
private void setRestAppAttributes(Application app, Properties appProps)
throws PropertyVetoException, TransactionFailure {
// context-root element
if (appProps.getProperty(ServerTags.CONTEXT_ROOT) != null) {
app.setContextRoot(appProps.getProperty(
ServerTags.CONTEXT_ROOT));
}
// property element
// trim the properties that have been written as attributes
// the rest properties will be written as property element
for (Iterator itr = appProps.keySet().iterator();
itr.hasNext();) {
String propName = (String) itr.next();
if (!propName.equals(ServerTags.LOCATION) &&
!propName.equals(ServerTags.CONTEXT_ROOT) &&
!propName.equals(ServerTags.OBJECT_TYPE) &&
!propName.equals(ServerTags.DIRECTORY_DEPLOYED) &&
!propName.startsWith(
DeploymentProperties.APP_CONFIG))
{
if (appProps.getProperty(propName) != null) {
Property prop = app.createChild(Property.class);
app.getProperty().add(prop);
prop.setName(propName);
prop.setValue(appProps.getProperty(propName));
}
}
}
}
public void unregisterAppFromDomainXML(final String appName,
final String target) throws TransactionFailure {
unregisterAppFromDomainXML(appName, target, false);
}
public void unregisterAppFromDomainXML(final String appName,
final String tgt, final boolean appRefOnly)
throws TransactionFailure {
ConfigSupport.apply(new SingleConfigCode() {
public Object run(ConfigBeanProxy param) throws PropertyVetoException, TransactionFailure {
// get the transaction
Transaction t = Transaction.getTransaction(param);
if (t!=null) {
List targets = new ArrayList();
if (!DeploymentUtils.isDomainTarget(tgt)) {
targets.add(tgt);
} else {
targets = domain.getAllReferencedTargetsForApplication(appName);
}
Domain dmn;
if (param instanceof Domain) {
dmn = (Domain)param;
} else {
return Boolean.FALSE;
}
for (String target : targets) {
Server servr = dmn.getServerNamed(target);
if (servr != null) {
// remove the application-ref from standalone
// server instance
ConfigBeanProxy servr_w = t.enroll(servr);
for (ApplicationRef appRef :
servr.getApplicationRef()) {
if (appRef.getRef().equals(appName)) {
((Server)servr_w).getApplicationRef().remove(
appRef);
break;
}
}
}
Cluster cluster = dmn.getClusterNamed(target);
if (cluster != null) {
// remove the application-ref from cluster
ConfigBeanProxy cluster_w = t.enroll(cluster);
for (ApplicationRef appRef :
cluster.getApplicationRef()) {
if (appRef.getRef().equals(appName)) {
((Cluster)cluster_w).getApplicationRef().remove(
appRef);
break;
}
}
// remove the application-ref from cluster instances
for (Server svr : cluster.getInstances() ) {
ConfigBeanProxy svr_w = t.enroll(svr);
for (ApplicationRef appRef :
svr.getApplicationRef()) {
if (appRef.getRef().equals(appName)) {
((Server)svr_w).getApplicationRef(
).remove(appRef);
break;
}
}
}
}
}
if (!appRefOnly) {
// remove application element
Applications apps = dmn.getApplications();
ConfigBeanProxy apps_w = t.enroll(apps);
for (ApplicationName module : apps.getModules()) {
if (module.getName().equals(appName)) {
((Applications)apps_w).getModules().remove(module);
break;
}
}
}
}
return Boolean.TRUE;
}
}, domain);
}
public void updateAppEnabledAttributeInDomainXML(final String appName,
final String target, final boolean enabled) throws TransactionFailure {
ConfigSupport.apply(new SingleConfigCode() {
public Object run(ConfigBeanProxy param) throws PropertyVetoException, TransactionFailure {
// get the transaction
Transaction t = Transaction.getTransaction(param);
if (t!=null) {
Domain dmn;
if (param instanceof Domain) {
dmn = (Domain)param;
} else {
return Boolean.FALSE;
}
if (enabled || DeploymentUtils.isDomainTarget(target)) {
Application app = dmn.getApplications().getApplication(appName);
ConfigBeanProxy app_w = t.enroll(app);
((Application)app_w).setEnabled(String.valueOf(enabled));
}
List targets = new ArrayList();
if (!DeploymentUtils.isDomainTarget(target)) {
targets.add(target);
} else {
targets = domain.getAllReferencedTargetsForApplication(appName);
}
for (String target : targets) {
Server servr = dmn.getServerNamed(target);
if (servr != null) {
// update the application-ref from standalone
// server instance
for (ApplicationRef appRef :
servr.getApplicationRef()) {
if (appRef.getRef().equals(appName)) {
ConfigBeanProxy appRef_w = t.enroll(appRef);
((ApplicationRef)appRef_w).setEnabled(String.valueOf(enabled));
break;
}
}
updateClusterAppRefWithInstanceUpdate(t, servr, appName, enabled);
}
Cluster cluster = dmn.getClusterNamed(target);
if (cluster != null) {
// update the application-ref from cluster
for (ApplicationRef appRef :
cluster.getApplicationRef()) {
if (appRef.getRef().equals(appName)) {
ConfigBeanProxy appRef_w = t.enroll(appRef);
((ApplicationRef)appRef_w).setEnabled(String.valueOf(enabled));
break;
}
}
// update the application-ref from cluster instances
for (Server svr : cluster.getInstances() ) {
for (ApplicationRef appRef :
svr.getApplicationRef()) {
if (appRef.getRef().equals(appName)) {
ConfigBeanProxy appRef_w = t.enroll(appRef);
((ApplicationRef)appRef_w).setEnabled(String.valueOf(enabled));
break;
}
}
}
}
}
}
return Boolean.TRUE;
}
}, domain);
}
// check if the application is registered in domain.xml
public boolean isRegistered(String appName) {
return applications.getApplication(appName)!=null;
}
public ApplicationInfo get(String appName) {
return appRegistry.get(appName);
}
private boolean isPaaSEnabled(Boolean isClassicStyle) {
if (isClassicStyle) {
return false;
}
if (virtEnv != null && virtEnv.isPaasEnabled()) {
return true;
}
return false;
}
// gets the default target when no target is specified for non-paas case
public String getDefaultTarget(Boolean isClassicStyle) {
if (!isPaaSEnabled(isClassicStyle)) {
return DeploymentUtils.DAS_TARGET_NAME;
}
return null;
}
// gets the default target when no target is specified
public String getDefaultTarget(String appName, OpsParams.Origin origin, Boolean isClassicStyle) {
if (!isPaaSEnabled(isClassicStyle)) {
return DeploymentUtils.DAS_TARGET_NAME;
} else {
// for deploy case, OE will set the deploy target later
if (origin == OpsParams.Origin.deploy) {
return null;
}
// for other cases, we try to derive it from domain.xml
List targets =
domain.getAllReferencedTargetsForApplication(appName);
if (targets.size() == 0) {
throw new IllegalArgumentException("Application not registered");
}
if (targets.size() > 1) {
throw new IllegalArgumentException("Cannot determine the default target. Please specify an explicit target for the operation.");
}
return targets.get(0);
}
}
public class DeploymentContextBuidlerImpl implements DeploymentContextBuilder {
private final Logger logger;
private final ActionReport report;
private final OpsParams params;
private File sFile;
private ReadableArchive sArchive;
private ArchiveHandler handler;
public DeploymentContextBuidlerImpl(Logger logger, OpsParams params, ActionReport report) {
this.logger = logger;
this.report = report;
this.params = params;
}
public DeploymentContextBuidlerImpl(DeploymentContextBuilder b) throws IOException {
this.logger = b.logger();
this.report = b.report();
this.params = b.params();
ReadableArchive archive = getArchive(b);
source(archive);
handler = b.archiveHandler();
}
public DeploymentContextBuilder source(File source) {
this.sFile = source;
return this;
}
public File sourceAsFile() {
return sFile;
}
public ReadableArchive sourceAsArchive() {
return sArchive;
}
public ArchiveHandler archiveHandler() {
return handler;
}
public DeploymentContextBuilder source(ReadableArchive archive) {
this.sArchive = archive;
return this;
}
public DeploymentContextBuilder archiveHandler(ArchiveHandler handler) {
this.handler = handler;
return this;
}
public ExtendedDeploymentContext build() throws IOException {
return build(null);
}
public Logger logger() { return logger; };
public ActionReport report() { return report; };
public OpsParams params() { return params; };
public ExtendedDeploymentContext build(ExtendedDeploymentContext initialContext) throws IOException {
return ApplicationLifecycle.this.getContext(initialContext, this);
}
}
public DeploymentContextBuilder getBuilder(Logger logger, OpsParams params, ActionReport report) {
return new DeploymentContextBuidlerImpl(logger, params, report);
}
/**
* Updates the "enabled" setting of the cluster's app ref for the
* given app if a change to the "enabled" setting of the app ref on one of
* the cluster's instances implies a cluster-level change.
*
* If the app is enabled on any single instance in a cluster
* then the cluster state needs to be enabled. If
* the app is disabled on all instances in the cluster
* then the cluster state should be disabled. This method makes sure the
* cluster-level app ref enabled state is correct, given the current values
* of the app refs on the cluster's instances combined with the new value
* for the specified instance.
*
* @param t current config Transaction in progress
* @param servr the Server for which the app ref has been enabled or disabled
* @param appName the name of the app whose app ref has been enabled or disabled
* @param isNewInstanceAppRefStateEnabled whether the new instance app ref state is enabled (false if disabled)
*/
private void updateClusterAppRefWithInstanceUpdate(
final Transaction t,
final Server servr,
final String appName,
final boolean isNewInstanceAppRefStateEnabled)
throws TransactionFailure, PropertyVetoException {
final Cluster clusterContainingInstance = servr.getCluster();
if (clusterContainingInstance != null) {
/*
* Update the cluster state also if needed.
*/
boolean isAppRefEnabledOnAnyClusterInstance = false;
for (Server inst : clusterContainingInstance.getInstances()) {
/*
* The app ref for the server just changed above
* still has its old state when fetched using
* inst.getApplicationRef(appName). So when we
* encounter the same server in the list of
* cluster instances, use the "enabled" value --
* which we just used above to update the app ref
* for the targeted instance -- below when
* we need to consider the "enabled" value for the
* just-changed instance.
*/
isAppRefEnabledOnAnyClusterInstance |= (
servr.getName().equals(inst.getName())
? isNewInstanceAppRefStateEnabled
: Boolean.parseBoolean(inst.getApplicationRef(appName).getEnabled()));
}
final ApplicationRef clusterAppRef =
clusterContainingInstance.getApplicationRef(appName);
if (Boolean.parseBoolean(clusterAppRef.getEnabled()) != isAppRefEnabledOnAnyClusterInstance) {
t.enroll(clusterAppRef).setEnabled(String.valueOf(isAppRefEnabledOnAnyClusterInstance));
}
}
}
// cannot put it on the builder itself since the builder is an official API.
private ReadableArchive getArchive(DeploymentContextBuilder builder) throws IOException {
ReadableArchive archive = builder.sourceAsArchive();
if (archive==null && builder.sourceAsFile()==null) {
throw new IOException("Source archive or file not provided to builder");
}
if (archive==null && builder.sourceAsFile()!=null) {
archive = habitat.getService(ArchiveFactory.class).openArchive(builder.sourceAsFile());
if (archive==null) {
throw new IOException("Invalid archive type : " + builder.sourceAsFile().getAbsolutePath());
}
}
return archive;
}
private ExtendedDeploymentContext getContext(ExtendedDeploymentContext initial, DeploymentContextBuilder builder) throws IOException {
DeploymentContextBuilder copy = new DeploymentContextBuidlerImpl(builder);
ReadableArchive archive = getArchive(copy);
copy.source(archive);
if (initial==null) {
initial = new DeploymentContextImpl(copy, env);
}
ArchiveHandler archiveHandler = copy.archiveHandler();
if (archiveHandler == null) {
String type = null;
OpsParams params = builder.params();
if (params != null) {
if (params instanceof DeployCommandParameters) {
type = ((DeployCommandParameters)params).type;
} else if (params instanceof UndeployCommandParameters) {
type = ((UndeployCommandParameters)params)._type;
}
}
archiveHandler = getArchiveHandler(archive, type);
}
// this is needed for autoundeploy to find the application
// with the archive name
File sourceFile = new File(archive.getURI().getSchemeSpecificPart());
initial.getAppProps().put(ServerTags.DEFAULT_APP_NAME,
DeploymentUtils.getDefaultEEName(sourceFile.getName()));
if (!(sourceFile.isDirectory())) {
String repositoryBitName = copy.params().name();
try {
repositoryBitName = VersioningUtils.getRepositoryName(repositoryBitName);
} catch (VersioningSyntaxException e) {
ActionReport report = copy.report();
report.setMessage(e.getMessage());
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
}
// create a temporary deployment context
File expansionDir = new File(domain.getApplicationRoot(),
repositoryBitName);
if (!expansionDir.mkdirs()) {
/*
* On Windows especially a previous directory might have
* remainded after an earlier undeployment, for example if
* a JAR file in the earlier deployment had been locked.
* Warn but do not fail in such a case.
*/
logger.fine(localStrings.getLocalString("deploy.cannotcreateexpansiondir", "Error while creating directory for jar expansion: {0}",expansionDir));
}
try {
Long start = System.currentTimeMillis();
final WritableArchive expandedArchive = archiveFactory.createArchive(expansionDir);
archiveHandler.expand(archive, expandedArchive, initial);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Deployment expansion took " + (System.currentTimeMillis() - start));
}
// Close the JAR archive before losing the reference to it or else the JAR remains locked.
try {
archive.close();
} catch(IOException e) {
logger.log(Level.SEVERE, KernelLoggerInfo.errorClosingArtifact,
new Object[] { archive.getURI().getSchemeSpecificPart(), e});
throw e;
}
archive = (FileArchive) expandedArchive;
initial.setSource(archive);
} catch(IOException e) {
logger.log(Level.SEVERE, KernelLoggerInfo.errorExpandingFile, e);
throw e;
}
}
initial.setArchiveHandler(archiveHandler);
return initial;
}
private void setAppRefAttributes(ApplicationRef appRef,
DeployCommandParameters deployParams)
throws PropertyVetoException {
appRef.setRef(deployParams.name);
if (deployParams.virtualservers != null) {
appRef.setVirtualServers(deployParams.virtualservers);
} else {
// deploy to all virtual-servers, we need to get the list.
appRef.setVirtualServers(DeploymentUtils.getVirtualServers(deployParams.target, env, domain));
}
if(deployParams.lbenabled != null){
appRef.setLbEnabled(deployParams.lbenabled);
} else {
//check if system property exists and use that
String lbEnabledDefault =
System.getProperty(Server.lbEnabledSystemProperty);
if (lbEnabledDefault != null) {
appRef.setLbEnabled(lbEnabledDefault);
}
}
appRef.setEnabled(deployParams.enabled.toString());
}
public ParameterMap prepareInstanceDeployParamMap(DeploymentContext dc)
throws Exception {
final DeployCommandParameters params = dc.getCommandParameters(DeployCommandParameters.class);
final Collection excludedParams = new ArrayList();
excludedParams.add(DeploymentProperties.PATH);
excludedParams.add(DeploymentProperties.DEPLOYMENT_PLAN);
excludedParams.add(DeploymentProperties.ALT_DD);
excludedParams.add(DeploymentProperties.RUNTIME_ALT_DD);
excludedParams.add(DeploymentProperties.UPLOAD); // We'll force it to true ourselves.
final ParameterMap paramMap;
final ParameterMapExtractor extractor = new ParameterMapExtractor(params);
paramMap = extractor.extract(excludedParams);
prepareGeneratedContent(dc, paramMap);
// set the path and plan params
// get the location properties from the application so the token
// will be resolved
Application application = applications.getApplication(params.name);
Properties appProperties = application.getDeployProperties();
String archiveLocation = appProperties.getProperty(Application.APP_LOCATION_PROP_NAME);
final File archiveFile = new File(new URI(archiveLocation));
paramMap.set("DEFAULT", archiveFile.getAbsolutePath());
String planLocation = appProperties.getProperty(Application.DEPLOYMENT_PLAN_LOCATION_PROP_NAME);
if (planLocation != null) {
final File actualPlan = new File(new URI(planLocation));
paramMap.set(DeployCommandParameters.ParameterNames.DEPLOYMENT_PLAN, actualPlan.getAbsolutePath());
}
String altDDLocation = appProperties.getProperty(Application.ALT_DD_LOCATION_PROP_NAME);
if (altDDLocation != null) {
final File altDD = new File(new URI(altDDLocation));
paramMap.set(DeployCommandParameters.ParameterNames.ALT_DD, altDD.getAbsolutePath());
}
String runtimeAltDDLocation = appProperties.getProperty(Application.RUNTIME_ALT_DD_LOCATION_PROP_NAME);
if (runtimeAltDDLocation != null) {
final File runtimeAltDD = new File(new URI(runtimeAltDDLocation));
paramMap.set(DeployCommandParameters.ParameterNames.RUNTIME_ALT_DD, runtimeAltDD.getAbsolutePath());
}
// always upload the archives to the instance side
// but not directories. Note that we prepare a zip file containing
// the generated directories and pass that as a single parameter so it
// will be uploaded even though a deployment directory is not.
paramMap.set(DeploymentProperties.UPLOAD, "true");
// pass the params we restored from the previous deployment in case of
// redeployment
if (params.previousContextRoot != null) {
paramMap.set(DeploymentProperties.PRESERVED_CONTEXT_ROOT, params.previousContextRoot);
}
// pass the app props so we have the information to persist in the
// domain.xml
Properties appProps = dc.getAppProps();
appProps.remove(DeploymentProperties.APP_CONFIG);
paramMap.set(DeploymentProperties.APP_PROPS, extractor.propertiesValue(appProps, ':'));
Properties previousVirtualServers = dc.getTransientAppMetaData(DeploymentProperties.PREVIOUS_VIRTUAL_SERVERS, Properties.class);
if (previousVirtualServers != null) {
paramMap.set(DeploymentProperties.PREVIOUS_VIRTUAL_SERVERS, extractor.propertiesValue(previousVirtualServers, ':'));
}
Properties previousEnabledAttributes = dc.getTransientAppMetaData(DeploymentProperties.PREVIOUS_ENABLED_ATTRIBUTES, Properties.class);
if (previousEnabledAttributes != null) {
paramMap.set(DeploymentProperties.PREVIOUS_ENABLED_ATTRIBUTES, extractor.propertiesValue(previousEnabledAttributes, ':'));
}
return paramMap;
}
private void prepareGeneratedContent(final DeploymentContext dc,
final ParameterMap paramMap) throws IOException {
/*
* Create a single ZIP file containing the various generated
* directories for this app.
*
* Note that some deployments - such as of OSGI modules - might not
* create any generated content.
*/
final File generatedContentZip = createGeneratedContentZip();
ZipOutputStream zipOS = null;
/*
* We want the ZIP file to contain xml/(appname), ejb/(appname), etc.
* directories, even if those directories don't contain anything.
* Then the instance deploy command can expand the uploaded zip file
* based at the instance's generated/ directory and the files - including
* empty directories if appropriate - will be stored in the right places.
*/
final File baseDir = dc.getScratchDir("xml").getParentFile().getParentFile();
for (String scratchType : UPLOADED_GENERATED_DIRS) {
zipOS = addScratchContentIfPresent(dc, baseDir, zipOS, generatedContentZip, scratchType);
}
if (zipOS != null) {
/*
* Because we did zip up some generated content, add the just-generated
* zip file as a parameter to the param map.
*/
zipOS.close();
// set the generated content param
paramMap.set("generatedcontent", generatedContentZip.getAbsolutePath());
}
}
private File createGeneratedContentZip() throws IOException {
final File tempFile = File.createTempFile("gendContent", ".zip");
tempFile.deleteOnExit();
return tempFile;
}
private ZipOutputStream addScratchContentIfPresent(final DeploymentContext dc,
final File baseDir,
ZipOutputStream zipOS,
final File generatedContentZip,
final String scratchDirName) throws IOException {
final File genDir = dc.getScratchDir(scratchDirName);
if (genDir.isDirectory()) {
if (zipOS == null) {
zipOS = new ZipOutputStream(
new BufferedOutputStream(new FileOutputStream(generatedContentZip)));
}
addFileToZip(zipOS, baseDir, genDir);
}
return zipOS;
}
private void addFileToZip(final ZipOutputStream zipOS, final File baseDir, final File f) throws IOException {
final String entryName = baseDir.toURI().relativize(f.toURI()).getPath();
final ZipEntry entry = new ZipEntry(entryName);
zipOS.putNextEntry(entry);
if ( ! f.isDirectory()) {
final byte[] buffer = new byte[1024];
final InputStream is = new BufferedInputStream(new FileInputStream(f));
int bytesRead;
try {
while ((bytesRead = is.read(buffer)) != -1) {
zipOS.write(buffer, 0, bytesRead);
}
} finally {
is.close();
zipOS.closeEntry();
}
} else {
/*
* A directory entry has no content itself.
*/
zipOS.closeEntry();
for (File subFile : f.listFiles()) {
addFileToZip(zipOS, baseDir, subFile);
}
}
}
public void validateDeploymentTarget(String target, String name,
boolean isRedeploy) {
List referencedTargets = domain.getAllReferencedTargetsForApplication(name);
if (referencedTargets.isEmpty()) {
if (isRegistered(name)) {
if (!isRedeploy && DeploymentUtils.isDomainTarget(target)) {
throw new IllegalArgumentException(localStrings.getLocalString("application.alreadyreg.redeploy", "Application with name {0} is already registered. Either specify that redeployment must be forced, or redeploy the application. Or if this is a new deployment, pick a different name.", name));
} else {
if (!DeploymentUtils.isDomainTarget(target)) {
throw new IllegalArgumentException(localStrings.getLocalString("use.create_app_ref_2", "Application {0} is already deployed in this domain. Please use create application ref to create application reference on target {1}.", name, target));
}
}
}
return;
}
if (!isRedeploy) {
if (DeploymentUtils.isDomainTarget(target)) {
throw new IllegalArgumentException(localStrings.getLocalString("application.deploy_domain", "Application with name {0} is already referenced by other target(s). Please specify force option to redeploy to domain.", name));
}
if (referencedTargets.size() == 1 &&
referencedTargets.contains(target)) {
throw new IllegalArgumentException(localStrings.getLocalString("application.alreadyreg.redeploy", "Application with name {0} is already registered. Either specify that redeployment must be forced, or redeploy the application. Or if this is a new deployment, pick a different name.", name));
} else {
throw new IllegalArgumentException(localStrings.getLocalString("use.create_app_ref", "Application {0} is already referenced by other target(s). Please use create application ref to create application reference on target {1}.", name, target));
}
} else {
if (referencedTargets.size() == 1 &&
referencedTargets.contains(target)) {
return;
} else {
if (!DeploymentUtils.isDomainTarget(target)) {
throw new IllegalArgumentException(localStrings.getLocalString("redeploy_on_multiple_targets", "Application {0} is referenced by more than one targets. Please remove other references or specify all targets (or domain target if using asadmin command line) before attempting redeploy operation.", name));
}
}
}
}
public void validateUndeploymentTarget(String target, String name) {
List referencedTargets = domain.getAllReferencedTargetsForApplication(name);
if (referencedTargets.size() > 1) {
Application app = applications.getApplication(name);
if (!DeploymentUtils.isDomainTarget(target)) {
if (app.isLifecycleModule()) {
throw new IllegalArgumentException(localStrings.getLocalString("delete_lifecycle_on_multiple_targets", "Lifecycle module {0} is referenced by more than one targets. Please remove other references before attempting delete operation.", name));
} else {
throw new IllegalArgumentException(localStrings.getLocalString("undeploy_on_multiple_targets", "Application {0} is referenced by more than one targets. Please remove other references or specify all targets (or domain target if using asadmin command line) before attempting undeploy operation.", name));
}
}
}
}
public void validateSpecifiedTarget(String target) {
if (env.isDas()) {
if (target == null) {
// we only validate the specified target
return;
}
Cluster cluster = domain.getClusterNamed(target);
if (cluster != null) {
if (cluster.isVirtual()) {
throw new IllegalArgumentException(localStrings.getLocalString("cannot_specify_managed_target", "Cannot specify target {0} for the operation. Target {0} is a managed target.", target));
}
}
}
}
public boolean isAppEnabled(Application app) {
if (Boolean.valueOf(app.getEnabled())) {
ApplicationRef appRef = server.getApplicationRef(app.getName());
if (appRef != null && Boolean.valueOf(appRef.getEnabled())) {
return true;
}
}
return false;
}
public ExtendedDeploymentContext disable(UndeployCommandParameters commandParams,
Application app, ApplicationInfo appInfo, ActionReport report,
Logger logger) throws Exception {
if (appInfo == null) {
report.failure(logger, "Application not registered", null);
return null;
}
// if it's not on DAS and the application is not loaded, do not unload
// when it's on DAS, there is some necessary clean up we need to do
if (!env.isDas() && !appInfo.isLoaded()) {
return null;
}
if (app != null) {
commandParams._type = app.archiveType();
}
final ExtendedDeploymentContext deploymentContext =
getBuilder(logger, commandParams, report).source(appInfo.getSource()).build();
if (app != null) {
deploymentContext.getAppProps().putAll(
app.getDeployProperties());
deploymentContext.setModulePropsMap(
app.getModulePropertiesMap());
}
if (commandParams.properties != null) {
deploymentContext.getAppProps().putAll(commandParams.properties);
}
unload(appInfo, deploymentContext);
return deploymentContext;
}
public ExtendedDeploymentContext enable(String target, Application app, ApplicationRef appRef,
ActionReport report, Logger logger) throws Exception {
ReadableArchive archive = null;
try {
DeployCommandParameters commandParams = app.getDeployParameters(appRef);
// if the application is already loaded, do not load again
ApplicationInfo appInfo = appRegistry.get(commandParams.name);
if (appInfo != null && appInfo.isLoaded()) {
return null;
}
commandParams.origin = DeployCommandParameters.Origin.load;
commandParams.command = DeployCommandParameters.Command.enable;
commandParams.target = target;
commandParams.enabled = Boolean.TRUE;
Properties contextProps = app.getDeployProperties();
Map modulePropsMap = app.getModulePropertiesMap();
ApplicationConfigInfo savedAppConfig = new ApplicationConfigInfo(app);
URI uri = new URI(app.getLocation());
File file = new File(uri);
if (!file.exists()) {
throw new Exception(localStrings.getLocalString("fnf", "File not found {0}", file.getAbsolutePath()));
}
archive = archiveFactory.openArchive(file);
final ExtendedDeploymentContext deploymentContext =
getBuilder(logger, commandParams, report).source(archive).build();
Properties appProps = deploymentContext.getAppProps();
appProps.putAll(contextProps);
savedAppConfig.store(appProps);
if (modulePropsMap != null) {
deploymentContext.setModulePropsMap(modulePropsMap);
}
deploy(getSniffersFromApp(app), deploymentContext);
return deploymentContext;
} finally {
try {
if (archive != null) {
archive.close();
}
} catch (IOException ioe) {
// ignore
}
}
}
private boolean loadOnCurrentInstance(DeploymentContext context) {
final DeployCommandParameters commandParams = context.getCommandParameters(DeployCommandParameters.class);
final Properties appProps = context.getAppProps();
if (commandParams.enabled) {
// if the current instance match with the target
if (domain.isCurrentInstanceMatchingTarget(commandParams.target, commandParams.name(), server.getName(), context.getTransientAppMetaData(DeploymentProperties.PREVIOUS_TARGETS, List.class))) {
return true;
}
if (server.isDas()) {
String objectType =
appProps.getProperty(ServerTags.OBJECT_TYPE);
if (objectType != null) {
// if it's a system application needs to be loaded on DAS
if (objectType.equals(DeploymentProperties.SYSTEM_ADMIN) ||
objectType.equals(DeploymentProperties.SYSTEM_ALL)) {
return true;
}
}
}
}
return false;
}
private String getApplicationType(ApplicationInfo appInfo) {
StringBuffer sb = new StringBuffer();
if (appInfo.getSniffers().size() > 0) {
for (Sniffer sniffer : appInfo.getSniffers()) {
if (sniffer.isUserVisible()) {
sb.append(sniffer.getModuleType() + ", ");
}
}
}
if (sb.length() > 2) {
return sb.substring(0, sb.length()-2);
}
return sb.toString();
}
public List getSniffersFromApp(Application app) {
List snifferTypes = new ArrayList();
for (com.sun.enterprise.config.serverbeans.Module module : app.getModule()) {
for (Engine engine : module.getEngines()) {
snifferTypes.add(engine.getSniffer());
}
}
if (snifferTypes.isEmpty()) {
// for the upgrade scenario, we cannot get the sniffers from the
// domain.xml, so we need to re-process it during deployment
return null;
}
List sniffers = new ArrayList();
if (app.isStandaloneModule()) {
for (String snifferType : snifferTypes) {
Sniffer sniffer = snifferManager.getSniffer(snifferType);
if (sniffer != null) {
sniffers.add(sniffer);
} else {
logger.log(Level.SEVERE, KernelLoggerInfo.cantFindSniffer, snifferType);
}
}
if (sniffers.isEmpty()) {
logger.log(Level.SEVERE, KernelLoggerInfo.cantFindSnifferForApp, app.getName());
return null;
}
} else {
// todo, this is a cludge to force the reload and reparsing of the
// composite application.
return null;
}
return sniffers;
}
private ExecutorService createExecutorService() {
Runtime runtime = Runtime.getRuntime();
int nrOfProcessors = runtime.availableProcessors();
return Executors.newFixedThreadPool(nrOfProcessors, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("deployment-jar-scanner");
t.setContextClassLoader(getClass().getClassLoader());
t.setDaemon(true);
return t;
}
});
}
}