use of org.glassfish.internal.deployment.analysis.SpanSequence in project Payara by payara.
the class ApplicationLifecycle method prepare.
@Override
public ApplicationDeployment prepare(Collection<? extends Sniffer> sniffers, final ExtendedDeploymentContext context) {
StructuredDeploymentTracing tracing = StructuredDeploymentTracing.load(context);
DeploymentSpan eventSpan = tracing.startSpan(DeploymentTracing.AppStage.PROCESS_EVENTS, Deployment.DEPLOYMENT_START.type());
events.send(new Event<>(Deployment.DEPLOYMENT_START, context), false);
eventSpan.close();
currentDeploymentContext.get().push(context);
final ActionReport report = context.getActionReport();
final DeployCommandParameters commandParams = context.getCommandParameters(DeployCommandParameters.class);
final String appName = commandParams.name();
ApplicationInfo appInfo;
Optional<ApplicationState> appState = hotDeployService.getApplicationState(context);
final ClassLoader currentCL = Thread.currentThread().getContextClassLoader();
ProgressTracker tracker = new ProgressTracker() {
@Override
public void actOn(Logger logger) {
// 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
}
}
if (!commandParams.keepfailedstubs) {
try {
context.clean();
} catch (Exception e) {
// ignore
}
}
appRegistry.remove(appName);
}
};
try (DeploymentSpan topSpan = tracing.startSpan(DeploymentTracing.AppStage.PREPARE);
SpanSequence span = tracing.startSequence(DeploymentTracing.AppStage.PREPARE, "ArchiveMetadata")) {
if (commandParams.origin == OpsParams.Origin.deploy && appRegistry.get(appName) != null && !commandParams.hotDeploy) {
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;
}
// 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);
}
context.addTransientAppMetaData(ExtendedDeploymentContext.TRACKER, tracker);
context.setPhase(DeploymentContextImpl.Phase.PREPARE);
span.start("ArchiveHandler");
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;
}
span.start(DeploymentTracing.AppStage.CLASS_SCANNING);
if (handler.requiresAnnotationScanning(context.getSource())) {
getDeployableTypes(context);
}
span.finish();
// is that some container do not support to be restarted.
if (sniffers != null && logger.isLoggable(Level.FINE)) {
for (Sniffer sniffer : sniffers) {
logger.log(FINE, "Before Sorting{0}", sniffer.getModuleType());
}
}
span.start(DeploymentTracing.AppStage.PREPARE, "Sniffer");
sniffers = getSniffers(handler, sniffers, context);
final Collection<? extends Sniffer> selectedSniffers = sniffers;
appState.ifPresent(s -> s.setSniffers(selectedSniffers));
span.start(DeploymentTracing.AppStage.PREPARE, "ClassLoaderHierarchy");
ClassLoaderHierarchy clh = habitat.getService(ClassLoaderHierarchy.class);
span.start(DeploymentTracing.AppStage.PREPARE, "ClassLoader");
context.createDeploymentClassLoader(clh, handler);
events.send(new Event<>(Deployment.AFTER_DEPLOYMENT_CLASSLOADER_CREATION, context), false);
Thread.currentThread().setContextClassLoader(context.getClassLoader());
span.start(DeploymentTracing.AppStage.PREPARE, "Container");
final List<EngineInfo> sortedEngineInfos;
if (appState.map(ApplicationState::getEngineInfos).isPresent()) {
sortedEngineInfos = appState.get().getEngineInfos();
loadDeployers(sortedEngineInfos.stream().collect(toMap(EngineInfo::getDeployer, Function.identity())), context);
} else {
sortedEngineInfos = setupContainerInfos(handler, sniffers, context);
appState.ifPresent(s -> s.setEngineInfos(sortedEngineInfos));
}
// a bit more is happening here, but I cannot quite describe it yet
span.start(DeploymentTracing.AppStage.CREATE_CLASSLOADER);
if (sortedEngineInfos.isEmpty()) {
throw new DeploymentException(localStrings.getLocalString("unknowncontainertype", "There is no installed container capable of handling this application {0}", context.getSource().getName()));
}
if (logger.isLoggable(Level.FINE)) {
for (EngineInfo info : sortedEngineInfos) {
logger.log(FINE, "After Sorting {0}", info.getSniffer().getModuleType());
}
}
// 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(SEVERE, KernelLoggerInfo.lifecycleException, interceptorException);
tracker.actOn(logger);
return null;
}
events.send(new Event<>(Deployment.DEPLOYMENT_BEFORE_CLASSLOADER_CREATION, context), false);
context.createApplicationClassLoader(clh, handler);
tempAppInfo.setAppClassLoader(context.getFinalClassLoader());
events.send(new Event<>(Deployment.AFTER_APPLICATION_CLASSLOADER_CREATION, context), false);
// 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
final ModuleInfo moduleInfo;
try (SpanSequence innerSpan = span.start(DeploymentTracing.AppStage.PREPARE, "Module")) {
if (appState.map(ApplicationState::getModuleInfo).isPresent()) {
moduleInfo = appState.get().getModuleInfo();
moduleInfo.reset();
} else {
moduleInfo = prepareModule(sortedEngineInfos, appName, context, tracker);
appState.ifPresent(s -> s.setModuleInfo(moduleInfo));
}
// 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) {
report.failure(logger, "Exception while preparing the app", null);
report.setFailureCause(prepareException);
logger.log(SEVERE, KernelLoggerInfo.lifecycleException, prepareException);
tracker.actOn(logger);
return null;
}
span.start(DeploymentTracing.AppStage.PROCESS_EVENTS, Deployment.APPLICATION_PREPARED.type());
// is not a composite module.
if (appState.map(ApplicationState::getApplicationInfo).isPresent()) {
appInfo = appState.get().getApplicationInfo();
appInfo.reset(context.getSource());
for (Object metadata : context.getModuleMetadata()) {
moduleInfo.addMetaData(metadata);
appInfo.addMetaData(metadata);
}
} else if ((appInfo = context.getModuleMetaData(ApplicationInfo.class)) == null) {
ApplicationInfo applicationInfo = new ApplicationInfo(events, context.getSource(), appName);
appInfo = applicationInfo;
appInfo.addModule(moduleInfo);
appState.ifPresent(s -> s.setApplicationInfo(applicationInfo));
for (Object metadata : context.getModuleMetadata()) {
moduleInfo.addMetaData(metadata);
appInfo.addMetaData(metadata);
}
} 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);
// 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());
appState.ifPresent(s -> s.setApplicationClassLoader(context.getClassLoader()));
events.send(new Event<>(Deployment.APPLICATION_PREPARED, context), false);
if (loadOnCurrentInstance(context)) {
appInfo.setLibraries(commandParams.libraries());
try (SpanSequence innerSpan = span.start(DeploymentTracing.AppStage.LOAD)) {
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.LOAD, context);
appInfo.load(context, tracker);
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.LOAD, context);
} catch (Throwable loadException) {
logger.log(SEVERE, KernelLoggerInfo.lifecycleException, loadException);
report.failure(logger, "Exception while loading the app", null);
report.setFailureCause(loadException);
tracker.actOn(logger);
return null;
}
}
} catch (DeploymentException de) {
report.failure(logger, de.getMessage());
tracker.actOn(logger);
return null;
} catch (Exception e) {
report.failure(logger, localStrings.getLocalString("error.deploying.app", "Exception while deploying the app [{0}]", appName), null);
report.setFailureCause(e);
logger.log(SEVERE, KernelLoggerInfo.lifecycleException, e);
tracker.actOn(logger);
return null;
} finally {
Thread.currentThread().setContextClassLoader(currentCL);
if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) {
context.postDeployClean(false);
events.send(new Event<>(Deployment.DEPLOYMENT_FAILURE, context));
}
}
ApplicationDeployment depl = new ApplicationDeployment(appInfo, context);
appRegistry.addTransient(depl);
return depl;
}
use of org.glassfish.internal.deployment.analysis.SpanSequence in project Payara by payara.
the class DeployCommand method preAuthorization.
@Override
public boolean preAuthorization(AdminCommandContext context) {
logger = context.getLogger();
events.register(this);
suppInfo = new DeployCommandSupplementalInfo();
context.getActionReport().setResultType(DeployCommandSupplementalInfo.class, suppInfo);
structuredTracing = System.getProperty("org.glassfish.deployment.trace") != null ? StructuredDeploymentTracing.create(path.getName()) : StructuredDeploymentTracing.createDisabled(path.getName());
timing = new DeploymentTracing(structuredTracing);
final ActionReport report = context.getActionReport();
originalPathValue = path;
if (!path.exists()) {
report.setMessage(localStrings.getLocalString("fnf", "File not found", path.getAbsolutePath()));
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
return false;
}
if (!path.canRead()) {
report.setMessage(localStrings.getLocalString("fnr", "File {0} does not have read permission", path.getAbsolutePath()));
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
return false;
}
if (snifferManager.hasNoSniffers()) {
String msg = localStrings.getLocalString("nocontainer", "No container services registered, done...");
report.failure(logger, msg);
return false;
}
try (DeploymentSpan span = structuredTracing.startSpan(DeploymentTracing.AppStage.OPENING_ARCHIVE)) {
archive = archiveFactory.openArchive(path, this);
} catch (IOException e) {
final String msg = localStrings.getLocalString("deploy.errOpeningArtifact", "deploy.errOpeningArtifact", path.getAbsolutePath());
if (logReportedErrors) {
report.failure(logger, msg, e);
} else {
report.setMessage(msg + path.getAbsolutePath() + e.toString());
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
}
return false;
}
if (altdd != null) {
archive.addArchiveMetaData(DeploymentProperties.ALT_DD, altdd);
}
if (runtimealtdd != null) {
archive.addArchiveMetaData(DeploymentProperties.RUNTIME_ALT_DD, runtimealtdd);
}
expansionDir = null;
deploymentContext = null;
try (SpanSequence span = structuredTracing.startSequence(DeploymentTracing.AppStage.VALIDATE_TARGET, "command")) {
deployment.validateSpecifiedTarget(target);
span.start(DeploymentTracing.AppStage.OPENING_ARCHIVE, "ArchiveHandler");
archiveHandler = deployment.getArchiveHandler(archive, type);
if (archiveHandler == null) {
report.failure(logger, localStrings.getLocalString("deploy.unknownarchivetype", "Archive type of {0} was not recognized", path));
return false;
}
span.start(DeploymentTracing.AppStage.CREATE_DEPLOYMENT_CONTEXT, "Initial");
Optional<ApplicationState> appState = hotDeployService.getApplicationState(path);
boolean hotswap = hotDeploy && !metadataChanged && appState.map(ApplicationState::isHotswap).orElse(false);
if (!hotswap) {
// create an initial context
initialContext = new DeploymentContextImpl(report, archive, this, env);
} else {
initialContext = hotDeployService.getApplicationState(path).map(ApplicationState::getDeploymentContext).orElseThrow(() -> new RuntimeException());
}
initialContext.setArchiveHandler(archiveHandler);
if (hotDeploy && !metadataChanged && appState.isPresent()) {
if (!appState.get().start(this, initialContext, events)) {
appState.get().close();
return false;
}
} else {
hotDeployService.removeApplicationState(path);
}
structuredTracing.register(initialContext);
span.finish();
span.start(DeploymentTracing.AppStage.PROCESS_EVENTS, Deployment.INITIAL_CONTEXT_CREATED.type());
events.send(new Event<DeploymentContext>(Deployment.INITIAL_CONTEXT_CREATED, initialContext), false);
span.start(DeploymentTracing.AppStage.DETERMINE_APP_NAME);
if (!forceName) {
boolean isModuleDescriptorAvailable = false;
if (archiveHandler.getArchiveType().equals("ejb") && (archive.exists(EJB_JAR_XML) || archive.exists(SUN_EJB_JAR_XML) || archive.exists(GF_EJB_JAR_XML))) {
isModuleDescriptorAvailable = true;
} else if (archiveHandler.getArchiveType().equals("ear") && (archive.exists(APPLICATION_XML) || archive.exists(SUN_APPLICATION_XML) || archive.exists(GF_APPLICATION_XML))) {
isModuleDescriptorAvailable = true;
} else if (archiveHandler.getArchiveType().equals("car") && (archive.exists(APPLICATION_CLIENT_XML) || archive.exists(SUN_APPLICATION_CLIENT_XML) || archive.exists(GF_APPLICATION_CLIENT_XML))) {
isModuleDescriptorAvailable = true;
} else if (archiveHandler.getArchiveType().equals("rar") && (archive.exists(RA_XML))) {
isModuleDescriptorAvailable = true;
}
if (isModuleDescriptorAvailable) {
name = archiveHandler.getDefaultApplicationName(initialContext.getSource(), initialContext, name);
}
}
if (name == null) {
name = archiveHandler.getDefaultApplicationName(initialContext.getSource(), initialContext);
} else {
DeploymentUtils.validateApplicationName(name);
}
boolean isUntagged = VersioningUtils.isUntagged(name);
// no GlassFish versioning support for OSGi budles
if (name != null && !isUntagged && type != null && type.equals("osgi")) {
ActionReport.MessagePart msgPart = context.getActionReport().getTopMessagePart();
msgPart.setChildrenType("WARNING");
ActionReport.MessagePart childPart = msgPart.addChild();
childPart.setMessage(VersioningUtils.LOCALSTRINGS.getLocalString("versioning.deployment.osgi.warning", "OSGi bundles will not use the GlassFish versioning, any version information embedded as part of the name option will be ignored"));
name = VersioningUtils.getUntaggedName(name);
}
// we try to retrieve the version-identifier element's value from DD
if (isUntagged) {
String versionIdentifier = archiveHandler.getVersionIdentifier(initialContext.getSource());
if (versionIdentifier != null && !versionIdentifier.isEmpty()) {
name = name + VersioningUtils.EXPRESSION_SEPARATOR + versionIdentifier;
}
}
if (target == null) {
target = deployment.getDefaultTarget(name, origin, _classicstyle);
}
boolean isRegistered = deployment.isRegistered(name);
isredeploy = isRegistered && force;
return true;
} catch (Exception ex) {
events.unregister(this);
if (initialContext != null && initialContext.getSource() != null) {
try {
initialContext.getSource().close();
} catch (IOException ioex) {
throw new RuntimeException(ioex);
}
}
throw new RuntimeException(ex);
}
}
use of org.glassfish.internal.deployment.analysis.SpanSequence in project Payara by payara.
the class ApplicationLifecycle method initialize.
@Override
public void initialize(ApplicationInfo appInfo, Collection<? extends Sniffer> sniffers, ExtendedDeploymentContext context) {
if (appInfo == null) {
return;
}
appRegistry.removeTransient(appInfo.getName());
final ActionReport report = context.getActionReport();
ProgressTracker tracker = context.getTransientAppMetaData(ExtendedDeploymentContext.TRACKER, ProgressTracker.class);
StructuredDeploymentTracing tracing = StructuredDeploymentTracing.load(context);
// associated engines and the application info is created and registered
if (loadOnCurrentInstance(context)) {
try (SpanSequence span = tracing.startSequence(DeploymentTracing.AppStage.INITIALIZE)) {
notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.START, context);
appInfo.initialize();
appInfo.getModuleInfos().forEach(moduleInfo -> moduleInfo.getEngineRefs().forEach(engineRef -> tracker.add("initialized", EngineRef.class, engineRef)));
span.start(DeploymentTracing.AppStage.START);
appInfo.start(context, tracker);
notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.START, context);
} catch (Throwable loadException) {
logger.log(SEVERE, KernelLoggerInfo.lifecycleException, loadException);
report.failure(logger, "Exception while loading the app", null);
report.setFailureCause(loadException);
tracker.actOn(logger);
} finally {
context.postDeployClean(false);
if (report.getActionExitCode() == ActionReport.ExitCode.FAILURE) {
// warning status code is not a failure
events.send(new Event<>(Deployment.DEPLOYMENT_FAILURE, context));
} else {
events.send(new Event<>(Deployment.DEPLOYMENT_SUCCESS, appInfo));
}
}
currentDeploymentContext.get().pop();
}
}
use of org.glassfish.internal.deployment.analysis.SpanSequence in project Payara by payara.
the class DeployCommand method execute.
/**
* Entry point from the framework into the command execution
*
* @param context context for the command.
*/
@Override
public void execute(AdminCommandContext context) {
long timeTakenToDeploy = 0;
long deploymentTimeMillis = 0;
Optional<ApplicationState> appState = Optional.empty();
final ActionReport report = context.getActionReport();
try (SpanSequence span = structuredTracing.startSequence(DeploymentTracing.AppStage.VALIDATE_TARGET, "registry")) {
if (!hotDeploy) {
hotDeployService.removeApplicationState(initialContext.getSourceDir());
} else if (!(appState = hotDeployService.getApplicationState(initialContext.getSourceDir())).isPresent()) {
ApplicationState applicationState = new ApplicationState(name, path, initialContext);
applicationState.setTarget(target);
appState = Optional.of(applicationState);
}
// needs to be fixed in hk2, we don't generate the right innerclass index. it should use $
Collection<Interceptor> interceptors = habitat.getAllServices(Interceptor.class);
if (interceptors != null) {
for (Interceptor interceptor : interceptors) {
interceptor.intercept(this, initialContext);
}
}
deployment.validateDeploymentTarget(target, name, isredeploy);
ActionReport.MessagePart part = report.getTopMessagePart();
part.addProperty(DeploymentProperties.NAME, name);
ApplicationConfigInfo savedAppConfig = new ApplicationConfigInfo(apps.getModule(Application.class, name));
Properties undeployProps = null;
if (appState.map(ApplicationState::isInactive).orElse(true)) {
undeployProps = handleRedeploy(name, report, context);
}
appState.filter(ApplicationState::isInactive).ifPresent(hotDeployService::addApplicationState);
if (enabled == null) {
enabled = Boolean.TRUE;
}
// clean up any left over repository files
if (!keepreposdir) {
span.start(DeploymentTracing.AppStage.CLEANUP, "applications");
final File reposDir = new File(env.getApplicationRepositoryPath(), VersioningUtils.getRepositoryName(name));
if (reposDir.exists()) {
for (int i = 0; i < domain.getApplications().getApplications().size(); i++) {
File existrepos = new File(new URI(domain.getApplications().getApplications().get(i).getLocation()));
String appname = domain.getApplications().getApplications().get(i).getName();
if (!appname.equals(name) && existrepos.getAbsoluteFile().equals(reposDir.getAbsoluteFile())) {
report.failure(logger, localStrings.getLocalString("deploy.dupdeployment", "Application {0} is trying to use the same repository directory as application {1}, please choose a different application name to deploy", name, appname));
return;
}
}
/*
* Delete the repository directory as an archive to allow
* any special processing (such as stale file handling)
* to run.
*/
final FileArchive arch = DeploymentUtils.openAsFileArchive(reposDir, archiveFactory);
arch.delete();
}
span.finish();
}
if (!DeploymentUtils.isDomainTarget(target) && enabled) {
// try to disable the enabled version, if exist
try (SpanSequence innerSpan = span.start(DeploymentTracing.AppStage.SWITCH_VERSIONS)) {
versioningService.handleDisable(name, target, report, context.getSubject());
} catch (VersioningSyntaxException e) {
report.failure(logger, e.getMessage());
return;
}
}
File source = new File(archive.getURI().getSchemeSpecificPart());
boolean isDirectoryDeployed = true;
if (!source.isDirectory()) {
isDirectoryDeployed = false;
expansionDir = new File(domain.getApplicationRoot(), VersioningUtils.getRepositoryName(name));
path = expansionDir;
} else {
// test if a version is already directory deployed from this dir
String versionFromSameDir = versioningService.getVersionFromSameDir(source);
if (!force && versionFromSameDir != null) {
report.failure(logger, VersioningUtils.LOCALSTRINGS.getLocalString("versioning.deployment.dual.inplace", "GlassFish do not support versioning for directory deployment when using the same directory. The directory {0} is already assigned to the version {1}.", source.getPath(), versionFromSameDir));
return;
}
}
span.start(DeploymentTracing.AppStage.CREATE_DEPLOYMENT_CONTEXT, "Full");
// create the parent class loader
deploymentContext = deployment.getBuilder(logger, this, report).source(initialContext.getSource()).archiveHandler(archiveHandler).build(initialContext);
String transformNS = System.getProperty(TRANSFORM_NAMESPACE);
Types types = deployment.getDeployableTypes(deploymentContext);
if (Boolean.valueOf(transformNS) || (transformNS == null && PayaraTransformer.isJakartaEEApplication(types))) {
span.start(DeploymentTracing.AppStage.TRANSFORM_ARCHIVE);
deploymentContext.getSource().close();
File output = PayaraTransformer.transformApplication(path, context, isDirectoryDeployed);
if (output == null) {
return;
}
deploymentContext.setSource((FileArchive) archiveFactory.createArchive(output));
// reset transient and module data of orignal deployed archive
deploymentContext.removeTransientAppMetaData(Types.class.getName());
deploymentContext.removeTransientAppMetaData(Parser.class.getName());
deploymentContext.resetModuleMetaData();
structuredTracing.register(deploymentContext);
}
// reset the properties (might be null) set by the deployers when undeploying.
if (undeployProps != null) {
deploymentContext.getAppProps().putAll(undeployProps);
}
if (properties != null || property != null) {
// check for both
if (properties == null) {
properties = new Properties();
}
if (property != null) {
properties.putAll(property);
}
}
if (properties != null) {
deploymentContext.getAppProps().putAll(properties);
validateDeploymentProperties(properties, deploymentContext);
}
span.start(DeploymentTracing.AppStage.CLEANUP, "generated");
// clean up any generated files
deploymentContext.clean();
span.start(DeploymentTracing.AppStage.PREPARE, "ServerConfig");
Properties appProps = deploymentContext.getAppProps();
/*
* If the app's location is within the domain's directory then
* express it in the config as ${com.sun.aas.instanceRootURI}/rest-of-path
* so users can relocate the entire installation without having
* to modify the app locations. Leave the location alone if
* it does not fall within the domain directory.
*/
String appLocation = DeploymentUtils.relativizeWithinDomainIfPossible(deploymentContext.getSource().getURI());
appProps.setProperty(ServerTags.LOCATION, appLocation);
// set to default "user", deployers can override it
// during processing
appProps.setProperty(ServerTags.OBJECT_TYPE, "user");
if (contextroot != null) {
appProps.setProperty(ServerTags.CONTEXT_ROOT, contextroot);
}
appProps.setProperty(ServerTags.DIRECTORY_DEPLOYED, String.valueOf(isDirectoryDeployed));
if (type == null) {
type = archiveHandler.getArchiveType();
}
appProps.setProperty(Application.ARCHIVE_TYPE_PROP_NAME, type);
if (appProps.getProperty(ServerTags.CDI_DEV_MODE_ENABLED_PROP) == null) {
appProps.setProperty(ServerTags.CDI_DEV_MODE_ENABLED_PROP, Boolean.FALSE.toString());
}
savedAppConfig.store(appProps);
deploymentContext.addTransientAppMetaData(DeploymentProperties.PREVIOUS_TARGETS, previousTargets);
deploymentContext.addTransientAppMetaData(DeploymentProperties.PREVIOUS_VIRTUAL_SERVERS, previousVirtualServers);
deploymentContext.addTransientAppMetaData(DeploymentProperties.PREVIOUS_ENABLED_ATTRIBUTES, previousEnabledAttributes);
Transaction tx = deployment.prepareAppConfigChanges(deploymentContext);
// next phase is launched by prepare
span.finish();
Deployment.ApplicationDeployment deplResult = deployment.prepare(null, deploymentContext);
if (deplResult != null && !loadOnly) {
appState.ifPresent(s -> s.storeMetaData(deploymentContext));
// initialize makes its own phase as well
deployment.initialize(deplResult.appInfo, deplResult.appInfo.getSniffers(), deplResult.context);
}
ApplicationInfo appInfo = deplResult != null ? deplResult.appInfo : null;
/*
* Various deployers might have added to the downloadable or
* generated artifacts. Extract them and, if the command succeeded,
* persist both into the app properties (which will be recorded
* in domain.xml).
*/
final Artifacts downloadableArtifacts = DeploymentUtils.downloadableArtifacts(deploymentContext);
final Artifacts generatedArtifacts = DeploymentUtils.generatedArtifacts(deploymentContext);
if (report.getActionExitCode() == ActionReport.ExitCode.SUCCESS) {
try (SpanSequence innerSpan = span.start(DeploymentTracing.AppStage.REGISTRATION)) {
moveAppFilesToPermanentLocation(deploymentContext, logger);
recordFileLocations(appProps);
downloadableArtifacts.record(appProps);
generatedArtifacts.record(appProps);
timeTakenToDeploy = timing.elapsed();
deploymentTimeMillis = System.currentTimeMillis();
if (tx != null) {
Application application = deploymentContext.getTransientAppMetaData("application", Application.class);
// Set the application deploy time
application.setDeploymentTime(Long.toString(timeTakenToDeploy));
application.setTimeDeployed(Long.toString(deploymentTimeMillis));
// register application information in domain.xml
deployment.registerAppInDomainXML(appInfo, deploymentContext, tx);
}
if (retrieve != null) {
retrieveArtifacts(context, downloadableArtifacts.getArtifacts(), retrieve, false, name);
}
suppInfo.setDeploymentContext(deploymentContext);
// send new event to notify the deployment process is finish
events.send(new Event<ApplicationInfo>(Deployment.DEPLOYMENT_COMMAND_FINISH, appInfo), false);
// Fix for issue 14442
// We want to report the worst subreport value.
ActionReport.ExitCode worstExitCode = ExitCode.SUCCESS;
for (ActionReport subReport : report.getSubActionsReport()) {
ActionReport.ExitCode actionExitCode = subReport.getActionExitCode();
if (actionExitCode.isWorse(worstExitCode)) {
worstExitCode = actionExitCode;
}
}
report.setActionExitCode(worstExitCode);
report.setResultType(String.class, name);
} catch (Exception e) {
// roll back the deployment and re-throw the exception
deployment.undeploy(name, deploymentContext);
deploymentContext.clean();
throw e;
}
}
} catch (Throwable e) {
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
report.setFailureCause(e);
if (e.getMessage() != null) {
report.setMessage(e.getMessage());
}
} finally {
events.unregister(this);
try {
archive.close();
} catch (IOException e) {
logger.log(Level.FINE, localStrings.getLocalString("errClosingArtifact", "Error while closing deployable artifact : ", path.getAbsolutePath()), e);
}
if (structuredTracing.isEnabled()) {
structuredTracing.print(System.out);
}
if (report.getActionExitCode().equals(ActionReport.ExitCode.SUCCESS)) {
// Set the app name in the result so that embedded deployer can retrieve it.
report.setResultType(String.class, name);
report.setMessage(localStrings.getLocalString("deploy.command.success", "Application deployed with name {0}", name));
logger.info(localStrings.getLocalString("deploy.done", "Deployment of {0} done is {1} ms at {2}", name, timeTakenToDeploy, DateFormat.getDateInstance().format(new Date(deploymentTimeMillis))));
} else if (report.getActionExitCode().equals(ActionReport.ExitCode.FAILURE)) {
String errorMessage = report.getMessage();
Throwable cause = report.getFailureCause();
if (cause != null) {
String causeMessage = cause.getMessage();
if (causeMessage != null && !causeMessage.equals(errorMessage)) {
errorMessage = errorMessage + " : " + cause.getMessage();
}
logger.log(Level.SEVERE, errorMessage, cause.getCause());
}
report.setMessage(localStrings.getLocalString("deploy.errDuringDepl", "Error occur during deployment: {0}.", errorMessage));
// reset the failure cause so command framework will not try
// to print the same message again
report.setFailureCause(null);
if (expansionDir != null) {
final FileArchive arch;
try {
/*
* Open and then delete the expansion directory as
* a file archive so stale file handling can run.
*/
arch = DeploymentUtils.openAsFileArchive(expansionDir, archiveFactory);
arch.delete();
} catch (IOException ex) {
final String msg = localStrings.getLocalString("deploy.errDelRepos", "Error deleting repository directory {0}", expansionDir.getAbsolutePath());
report.failure(logger, msg, ex);
}
}
appState.map(ApplicationState::getPath).ifPresent(hotDeployService::removeApplicationState);
}
if (deploymentContext != null && !loadOnly) {
deploymentContext.postDeployClean(true);
}
appState.ifPresent(ApplicationState::close);
}
}
Aggregations