use of fish.payara.nucleus.hotdeploy.ApplicationState 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 fish.payara.nucleus.hotdeploy.ApplicationState 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 fish.payara.nucleus.hotdeploy.ApplicationState in project Payara by payara.
the class DeploymentContextImpl method postDeployClean.
@Override
public void postDeployClean(boolean isFinalClean) {
boolean hotSwap = false;
ServiceLocator serviceLocator = Globals.getDefaultHabitat();
if (serviceLocator != null) {
hotSwap = serviceLocator.getService(HotDeployService.class).getApplicationState(this).map(ApplicationState::isHotswap).orElse(false);
}
if (transientAppMetaData != null && !hotSwap) {
if (isFinalClean) {
transientAppMetaData.clear();
} else {
final String[] classNamesToClean = { Types.class.getName(), Parser.class.getName() };
for (String className : classNamesToClean) {
transientAppMetaData.remove(className);
}
com.sun.enterprise.deploy.shared.FileArchive.clearCache();
}
}
actionReport = null;
}
use of fish.payara.nucleus.hotdeploy.ApplicationState in project Payara by payara.
the class Archivist method readRestDeploymentDescriptors.
private T readRestDeploymentDescriptors(T descriptor, ReadableArchive descriptorArchive, ReadableArchive contentArchive, Application app) throws IOException, SAXParseException {
ApplicationState state = descriptorArchive.getExtraData(ApplicationState.class);
Map<ExtensionsArchivist, RootDeploymentDescriptor> extensions = new HashMap<>();
if (extensionsArchivists != null) {
for (ExtensionsArchivist extension : extensionsArchivists) {
Object extDescriptor = null;
if (state != null && state.isActive() && extension.getDefaultDescriptor() != null) {
extDescriptor = state.getDeploymentContext().getModuleMetaData(extension.getDefaultDescriptor().getClass());
}
if (extDescriptor == null) {
extDescriptor = extension.open(this, descriptorArchive, descriptor);
}
if (extDescriptor instanceof RootDeploymentDescriptor) {
if (extDescriptor != descriptor) {
extension.addExtension(descriptor, (RootDeploymentDescriptor) extDescriptor);
}
extensions.put(extension, (RootDeploymentDescriptor) extDescriptor);
} else {
// maybe annotation processing will yield results
extensions.put(extension, null);
}
}
}
postStandardDDsRead(descriptor, contentArchive, extensions);
readAnnotations(contentArchive, descriptor, extensions);
postStandardDDsRead(descriptor, contentArchive, extensions);
ApplicationState appState = contentArchive.getExtraData(ApplicationState.class);
if (appState == null || !appState.isHotswap()) {
postAnnotationProcess(descriptor, contentArchive);
}
// now read the runtime deployment descriptors
readRuntimeDeploymentDescriptor(descriptorArchive, descriptor);
// read extensions runtime deployment descriptors if any
for (Map.Entry<ExtensionsArchivist, RootDeploymentDescriptor> extension : extensions.entrySet()) {
// an extension descriptor now
if (extension.getValue() != null) {
extension.getKey().readRuntimeDeploymentDescriptor(this, descriptorArchive, extension.getValue());
}
}
postRuntimeDDsRead(descriptor, contentArchive);
return descriptor;
}
use of fish.payara.nucleus.hotdeploy.ApplicationState in project Payara by payara.
the class Archivist method getProcessingContext.
private ProcessingContext getProcessingContext(RootDeploymentDescriptor bundleDesc, ReadableArchive archive, AnnotationProcessor ap) {
ProcessingContext ctx = null;
ApplicationState state = archive.getExtraData(ApplicationState.class);
if (state != null) {
ctx = state.getProcessingContext(bundleDesc.getClass(), ProcessingContext.class);
}
if (ctx == null) {
ctx = ap.createContext();
if (state != null) {
state.addProcessingContext(bundleDesc.getClass(), ctx);
}
}
return ctx;
}
Aggregations