use of fish.payara.nucleus.hotdeploy.ApplicationState in project Payara by payara.
the class DolProvider method processDOL.
private Application processDOL(DeploymentContext dc) throws IOException {
ReadableArchive sourceArchive = dc.getSource();
sourceArchive.setExtraData(Types.class, dc.getTransientAppMetaData(Types.class.getName(), Types.class));
sourceArchive.setExtraData(Parser.class, dc.getTransientAppMetaData(Parser.class.getName(), Parser.class));
Optional<ApplicationState> appState = hotDeployService.getApplicationState(dc);
appState.ifPresent(state -> sourceArchive.setExtraData(ApplicationState.class, state));
ClassLoader cl = dc.getClassLoader();
DeployCommandParameters params = dc.getCommandParameters(DeployCommandParameters.class);
sourceArchive.addArchiveMetaData(DeploymentProperties.APP_PROPS, dc.getAppProps());
sourceArchive.addArchiveMetaData(DeploymentProperties.COMMAND_PARAMS, params);
String name = params.name();
String archiveType = dc.getArchiveHandler().getArchiveType();
Archivist archivist = archivistFactory.getArchivist(archiveType, cl);
if (archivist == null) {
// an empty Application object
return Application.createApplication();
}
archivist.setAnnotationProcessingRequested(true);
String xmlValidationLevel = dasConfig.getDeployXmlValidation();
archivist.setXMLValidationLevel(xmlValidationLevel);
if (xmlValidationLevel.equals("none")) {
archivist.setXMLValidation(false);
}
archivist.setRuntimeXMLValidationLevel(xmlValidationLevel);
if (xmlValidationLevel.equals("none")) {
archivist.setRuntimeXMLValidation(false);
}
Collection<Sniffer> sniffers = dc.getTransientAppMetaData(DeploymentProperties.SNIFFERS, Collection.class);
archivist.setExtensionArchivists(archivistFactory.getExtensionsArchivists(sniffers, archivist.getModuleType()));
ApplicationHolder holder = dc.getModuleMetaData(ApplicationHolder.class);
File deploymentPlan = params.deploymentplan;
handleDeploymentPlan(deploymentPlan, archivist, sourceArchive, holder);
long start = System.currentTimeMillis();
Application application = appState.map(state -> state.getModuleMetaData(Application.class)).orElse(holder != null ? holder.app : null);
if (application != null) {
application.setAppName(name);
application.setClassLoader(cl);
application.setRoleMapper(null);
if (application.isVirtual()) {
ModuleDescriptor md = application.getStandaloneBundleDescriptor().getModuleDescriptor();
md.setModuleName(name);
if (appState.map(ApplicationState::isActive).orElse(false)) {
application.getStandaloneBundleDescriptor().setClassLoader(cl);
dc.addModuleMetaData(application.getStandaloneBundleDescriptor());
for (RootDeploymentDescriptor extension : application.getStandaloneBundleDescriptor().getExtensionsDescriptors()) {
extension.setClassLoader(cl);
dc.addModuleMetaData(extension);
}
}
}
try {
applicationFactory.openWith(application, sourceArchive, archivist);
} catch (SAXParseException e) {
throw new IOException(e);
}
} else {
// and it's a standalone module
try {
application = applicationFactory.openArchive(name, archivist, sourceArchive, true);
application.setAppName(name);
ModuleDescriptor md = application.getStandaloneBundleDescriptor().getModuleDescriptor();
md.setModuleName(name);
} catch (SAXParseException e) {
throw new IOException(e);
}
}
application.setRegistrationName(name);
sourceArchive.removeExtraData(Types.class);
sourceArchive.removeExtraData(Parser.class);
Logger.getAnonymousLogger().log(FINE, "DOL Loading time{0}", System.currentTimeMillis() - start);
return application;
}
use of fish.payara.nucleus.hotdeploy.ApplicationState in project Payara by payara.
the class DolProvider method load.
@Override
public Application load(DeploymentContext dc) throws IOException {
DeployCommandParameters params = dc.getCommandParameters(DeployCommandParameters.class);
Application application = processDOL(dc);
// write out xml files if needed
if (Boolean.valueOf(WRITEOUT_XML)) {
saveAppDescriptor(application, dc);
}
if (application.isVirtual()) {
dc.addModuleMetaData(application.getStandaloneBundleDescriptor());
for (RootDeploymentDescriptor extension : application.getStandaloneBundleDescriptor().getExtensionsDescriptors()) {
dc.addModuleMetaData(extension);
}
}
Optional<ApplicationState> appState = hotDeployService.getApplicationState(dc);
if (!appState.isPresent()) {
addModuleConfig(dc, application);
}
validateKeepStateOption(dc, params, application);
return application;
}
use of fish.payara.nucleus.hotdeploy.ApplicationState in project Payara by payara.
the class AbstractEjbHandler method processAnnotation.
/**
* Process a particular annotation which type is the same as the one
* returned by @see getAnnotationType().All information pertinent to the
* annotation and its context is encapsulated in the passed AnnotationInfo
* instance.This is a method in interface AnnotationHandler.
*
* @param ainfo the annotation information
* @return
* @throws org.glassfish.apf.AnnotationProcessorException
*/
@Override
public HandlerProcessingResult processAnnotation(AnnotationInfo ainfo) throws AnnotationProcessorException {
ApplicationState state = ainfo.getProcessingContext().getArchive().getExtraData(ApplicationState.class);
Class ejbClass = (Class) ainfo.getAnnotatedElement();
Annotation annotation = ainfo.getAnnotation();
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, "@ process ejb annotation {0} in {1}", new Object[] { annotation, ejbClass });
}
AnnotatedElementHandler aeHandler = ainfo.getProcessingContext().getHandler();
if (aeHandler != null && aeHandler instanceof EjbContext) {
EjbContext context = (EjbContext) aeHandler;
EjbDescriptor desc = (EjbDescriptor) context.getDescriptor();
if (isValidEjbDescriptor(desc, annotation)) {
return getDefaultProcessedResult();
} else {
log(Level.SEVERE, ainfo, localStrings.getLocalString("enterprise.deployment.annotation.handlers.notcompsuperclass", "The annotation symbol defined in super-class is not compatible with {0} ejb {1}.", new Object[] { desc.getType(), desc.getName() }));
return getDefaultFailedResult();
}
} else if (aeHandler == null || !(aeHandler instanceof EjbBundleContext)) {
return getInvalidAnnotatedElementHandlerResult(ainfo.getProcessingContext().getHandler(), ainfo);
}
EjbBundleContext ctx = (EjbBundleContext) aeHandler;
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "My context is {0}", ctx);
}
String elementName = getAnnotatedName(annotation);
if (elementName.length() == 0) {
elementName = ejbClass.getSimpleName();
} else {
elementName = TranslatedConfigView.expandValue(elementName);
}
EjbBundleDescriptorImpl currentBundle = (EjbBundleDescriptorImpl) ctx.getDescriptor();
EjbDescriptor ejbDesc = null;
try {
ejbDesc = currentBundle.getEjbByName(elementName);
} catch (IllegalArgumentException ex) {
// getEjbByName throws IllegalArgumentException when no ejb is found
}
if (state != null && ejbDesc != null) {
currentBundle.removeEjb(ejbDesc);
ejbDesc = null;
}
if (ejbDesc != null && !(ejbDesc instanceof DummyEjbDescriptor)) {
// overriding rules applies
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "Overriding rules apply for {0}", ejbClass.getName());
}
// don't allow ejb-jar.xml overwrite ejb type
if (!isValidEjbDescriptor(ejbDesc, annotation)) {
// this is an error
log(Level.SEVERE, ainfo, localStrings.getLocalString("enterprise.deployment.annotation.handlers.wrongejbtype", "Wrong annotation symbol for ejb {0}", new Object[] { ejbDesc }));
return getDefaultFailedResult();
}
// <ejb-class> is optional if a component-defining
// annotation is used. If present, <ejb-class> element
// must match the class on which the component defining annotation
// appears.
String descriptorEjbClass = ejbDesc.getEjbClassName();
if (descriptorEjbClass == null) {
ejbDesc.setEjbClassName(ejbClass.getName());
ejbDesc.applyDefaultClassToLifecycleMethods();
} else if (!descriptorEjbClass.equals(ejbClass.getName())) {
log(Level.SEVERE, ainfo, localStrings.getLocalString("enterprise.deployment.annotation.handlers.ejbclsmismatch", "", new Object[] { descriptorEjbClass, elementName, ejbClass.getName() }));
return getDefaultFailedResult();
}
} else {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "Creating a new descriptor for {0}", ejbClass.getName());
}
EjbDescriptor dummyEjbDesc = ejbDesc;
ejbDesc = createEjbDescriptor(elementName, ainfo);
// the information from dummy ejb descriptor if applicable
if (dummyEjbDesc != null) {
currentBundle.removeEjb(dummyEjbDesc);
ejbDesc.addEjbDescriptor(dummyEjbDesc);
// reset ejbClassName on ejbDesc
ejbDesc.setEjbClassName(ejbClass.getName());
}
// add the actual ejb descriptor to the ejb bundle
currentBundle.addEjb(ejbDesc);
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "New {0} bean {1}", new Object[] { getAnnotationType().getName(), elementName });
}
}
// We need to include all ejbs of the same name in the annotation processing context
// in order to handle the case that a bean class has both a component-defining
// annotation and there are other ejb-jar.xml-defined beans with the same bean class.
EjbDescriptor[] ejbDescs = currentBundle.getEjbByClassName(ejbClass.getName());
HandlerProcessingResult procResult = null;
for (EjbDescriptor next : ejbDescs) {
procResult = setEjbDescriptorInfo(next, ainfo);
doTimedObjectProcessing(ejbClass, next);
}
AnnotationContext annContext = null;
if (ejbDescs.length == 1) {
annContext = new EjbContext(ejbDesc, ejbClass);
} else {
annContext = new EjbsContext(ejbDescs, ejbClass);
}
// we push the new context on the stack...
ctx.getProcessingContext().pushHandler(annContext);
return procResult;
}
use of fish.payara.nucleus.hotdeploy.ApplicationState 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);
}
}
use of fish.payara.nucleus.hotdeploy.ApplicationState in project Payara by payara.
the class AnnotationProcessorImpl method process.
/**
* Starts the annotation processing tool passing the processing context which
* encapsulate all information necessary for the configuration of the tool.
* @param ctx is the initialised processing context
* @return the result of the annotations processing
* @throws AnnotationProcessorException
*/
@Override
public ProcessingResult process(ProcessingContext ctx) throws AnnotationProcessorException {
ApplicationState state = ctx.getArchive().getExtraData(ApplicationState.class);
Optional<AnnotationProcessorState> processorState = Optional.empty();
if (state != null) {
processorState = state.getProcessingState(ctx);
}
Scanner<Object> scanner = ctx.getProcessingInput();
ProcessingResultImpl result;
errorCount = 0;
if (state == null) {
result = new ProcessingResultImpl();
for (Class c : scanner.getElements()) {
result.add(process(ctx, c));
}
} else if (state.isInactive()) {
result = new ProcessingResultImpl();
for (Class c : scanner.getElements()) {
result.add(process(ctx, c));
}
processorState.ifPresent(s -> s.setProcessingResult(result));
} else {
result = processorState.get().getProcessingResult(ProcessingResultImpl.class);
for (Class modifiedClass : scanner.getElements(state.getClassesChanged().keySet())) {
result.add(process(ctx, modifiedClass));
}
}
return result;
}
Aggregations