use of org.glassfish.hk2.classmodel.reflect.Type in project Payara by payara.
the class ConfigSupport method sortAndDispatch.
/**
* sort events and dispatch the changes. There will be only one notification of event
* per event type, per object, meaning that if an object has had 3 attributes changes, the
* Changed interface implementation will get notified only once.
*
* @param events of events that resulted of a successful configuration transaction
* @param target the intended receiver of the changes notification
* @param logger to log any issues.
*/
public static UnprocessedChangeEvents sortAndDispatch(PropertyChangeEvent[] events, Changed target, Logger logger) {
if (logger == null) {
throw new IllegalArgumentException();
}
List<UnprocessedChangeEvent> unprocessed = new ArrayList<>();
List<Dom> added = new ArrayList<>();
List<Dom> changed = new ArrayList<>();
for (PropertyChangeEvent event : events) {
if (event.getOldValue() == null && event.getNewValue() instanceof ConfigBeanProxy) {
// something was added
try {
final ConfigBeanProxy proxy = ConfigBeanProxy.class.cast(event.getNewValue());
added.add(Dom.unwrap(proxy));
final NotProcessed nc = target.changed(Changed.TYPE.ADD, proxyType(proxy), proxy);
if (nc != null) {
unprocessed.add(new UnprocessedChangeEvent(event, nc.getReason()));
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception while processing config bean changes : ", e);
}
}
}
for (PropertyChangeEvent event : events) {
try {
Dom eventSource = Dom.unwrap((ConfigBeanProxy) event.getSource());
if (added.contains(eventSource)) {
// we don't really send the changed events for new comers.
continue;
}
ConfigBeanProxy proxy = null;
if (event.getNewValue() == null) {
try {
// getOldValue() can be null, we will notify a CHANGE event
proxy = ConfigBeanProxy.class.cast(event.getOldValue());
} catch (ClassCastException e) {
// this is ok, the old value was probably a string or something like this...
// we will notify the event.getSource() that it changed.
}
// new value is null, but not old value, we removed something
if (proxy != null) {
final NotProcessed nc = target.changed(Changed.TYPE.REMOVE, proxyType(proxy), proxy);
if (nc != null) {
unprocessed.add(new UnprocessedChangeEvent(event, nc.getReason()));
}
continue;
}
}
// and added config bean.
if (!changed.contains(eventSource)) {
proxy = ConfigBeanProxy.class.cast(event.getSource());
changed.add(eventSource);
final NotProcessed nc = target.changed(Changed.TYPE.CHANGE, proxyType(proxy), proxy);
if (nc != null) {
unprocessed.add(new UnprocessedChangeEvent(event, nc.getReason()));
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception while processing config bean changes : ", e);
}
}
return new UnprocessedChangeEvents(unprocessed);
}
use of org.glassfish.hk2.classmodel.reflect.Type 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 org.glassfish.hk2.classmodel.reflect.Type in project Payara by payara.
the class SetHealthCheckServiceConfiguration method execute.
@Override
public void execute(AdminCommandContext context) {
report = context.getActionReport();
if (report.getExtraProperties() == null) {
report.setExtraProperties(new Properties());
}
targetConfig = targetUtil.getConfig(target);
serviceType = parseServiceType(serviceName);
if (serviceType == null) {
String values = Arrays.asList(CheckerType.values()).stream().map(type -> type.name().toLowerCase().replace('_', '-')).collect(Collectors.joining(", "));
report.setMessage("No such service: " + serviceName + ".\nChoose one of: " + values + ".\nThe name can also be given in short form consisting only of the first letters of each word.");
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
return;
}
// update the service to unify the way it is printed later on
serviceName = serviceType.name().toLowerCase().replace('_', '-');
BaseHealthCheck<?, ?> service = getService();
if (service == null) {
report.appendMessage(strings.getLocalString("healthcheck.service.configure.status.error", "Service with name {0} could not be found.", serviceName));
report.setActionExitCode(ActionReport.ExitCode.FAILURE);
return;
}
updateServiceConfiguration(service);
}
use of org.glassfish.hk2.classmodel.reflect.Type in project Payara by payara.
the class GenericCrudCommand method getInjectionResolver.
public InjectionResolver<Param> getInjectionResolver() {
final InjectionResolver<Param> delegate = injector;
return new InjectionResolver<Param>(Param.class) {
@Override
public <V> V getValue(Object component, AnnotatedElement annotated, Type genericType, Class<V> type) throws MultiException {
if (type.isAssignableFrom(List.class)) {
final List<ConfigBeanProxy> values;
try {
if (annotated instanceof Method) {
values = (List<ConfigBeanProxy>) ((Method) annotated).invoke(component);
} else if (annotated instanceof Field) {
values = (List<ConfigBeanProxy>) ((Field) annotated).get(component);
} else {
String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.invalid_type", "Invalid annotated type {0} passed to InjectionResolver:getValue()", annotated.getClass().toString());
LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.INVALID_ANNO_TYPE, annotated.getClass().toString());
throw new MultiException(new IllegalArgumentException(msg));
}
} catch (IllegalAccessException | InvocationTargetException e) {
String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.invocation_failure", "Failure {0} while getting List<?> values from component", e.getMessage());
LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.INVOKE_FAILURE);
throw new MultiException(new IllegalStateException(msg, e));
}
Object value = delegate.getValue(component, annotated, genericType, type);
if (value == null) {
LOGGER.log(level, "Value of {0} is null", annotated);
return null;
}
Type genericReturnType = null;
if (annotated instanceof Method) {
genericReturnType = ((Method) annotated).getGenericReturnType();
} else if (annotated instanceof Field) {
genericReturnType = ((Field) annotated).getGenericType();
}
if (genericReturnType == null) {
throw new MultiException(new IllegalArgumentException("Cannot determine parametized type from " + annotated));
}
final Class<? extends ConfigBeanProxy> itemType = Types.erasure(Types.getTypeArgument(genericReturnType, 0));
if (LOGGER.isLoggable(level)) {
LOGGER.log(level, "Found that List<?> really is a List<{0}>", itemType);
}
if (itemType == null) {
String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.nongeneric_type", "The List type returned by {0} must be a generic type", annotated.toString());
LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.LIST_NOT_GENERIC_TYPE, annotated.toString());
throw new MultiException(new IllegalArgumentException(msg));
}
if (!ConfigBeanProxy.class.isAssignableFrom(itemType)) {
String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.wrong_type", "The generic type {0} is not supported, only List<? extends ConfigBeanProxy> is", annotated.toString());
LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.GENERIC_TYPE_NOT_SUPPORTED, annotated.toString());
throw new MultiException(new IllegalArgumentException(msg));
}
Properties props = convertStringToProperties(value.toString(), ':');
if (LOGGER.isLoggable(level)) {
for (Map.Entry<Object, Object> entry : props.entrySet()) {
LOGGER.log(level, "Subtype {0} key:{1} value:{2}", new Object[] { itemType, entry.getKey(), entry.getValue() });
}
}
final BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(itemType);
} catch (IntrospectionException e) {
String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.introspection_failure", "Failure {0} while instrospecting {1} to find all getters and setters", e.getMessage(), itemType.getName());
LogHelper.log(LOGGER, Level.SEVERE, ConfigApiLoggerInfo.INTROSPECTION_FAILED, e, itemType.getName());
throw new MultiException(new IllegalStateException(msg, e));
}
for (final Map.Entry<Object, Object> entry : props.entrySet()) {
ConfigBeanProxy child = (ConfigBeanProxy) component;
try {
ConfigBeanProxy cc = child.createChild(itemType);
new InjectionManager().inject(cc, itemType, new InjectionResolver<Attribute>(Attribute.class) {
@Override
public boolean isOptional(AnnotatedElement annotated, Attribute annotation) {
return true;
}
@Override
public Method getSetterMethod(Method annotated, Attribute annotation) {
// variant.
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
if (pd.getReadMethod().equals(annotated)) {
return pd.getWriteMethod();
}
}
return annotated;
}
@Override
public <V> V getValue(Object component, AnnotatedElement annotated, Type genericType, Class<V> type) throws MultiException {
String name = annotated.getAnnotation(Attribute.class).value();
if ((name == null || name.length() == 0) && annotated instanceof Method) {
// maybe there is a better way to do this...
name = ((Method) annotated).getName().substring(3);
if (name.equalsIgnoreCase("name") || name.equalsIgnoreCase("key")) {
return type.cast(entry.getKey());
}
if (name.equalsIgnoreCase("value")) {
return type.cast(entry.getValue());
}
}
return null;
}
});
values.add(cc);
} catch (TransactionFailure transactionFailure) {
String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.transactionException", "Transaction exception {0} while injecting {1}", transactionFailure.getMessage(), itemType);
LogHelper.log(LOGGER, Level.SEVERE, ConfigApiLoggerInfo.TX_FAILED, transactionFailure, itemType);
throw new MultiException(new IllegalStateException(msg, transactionFailure));
}
}
return null;
}
return delegate.getValue(component, annotated, genericType, type);
}
@Override
public boolean isOptional(AnnotatedElement annotated, Param annotation) {
return annotation.optional();
}
};
}
use of org.glassfish.hk2.classmodel.reflect.Type in project Payara by payara.
the class TemplateRestResource method createDataBasedOnForm.
/**
* allows for remote files to be put in a tmp area and we pass the
* local location of this file to the corresponding command instead of the content of the file
* * Yu need to add enctype="multipart/form-data" in the form
* for ex: <form action="http://localhost:4848/management/domain/applications/application" method="post" enctype="multipart/form-data">
* then any param of type="file" will be uploaded, stored locally and the param will use the local location
* on the server side (ie. just the path)
*/
public static HashMap<String, String> createDataBasedOnForm(FormDataMultiPart formData) {
HashMap<String, String> data = new HashMap<String, String>();
try {
// data passed to the generic command running
Map<String, List<FormDataBodyPart>> m1 = formData.getFields();
Set<String> ss = m1.keySet();
for (String fieldName : ss) {
for (FormDataBodyPart bodyPart : formData.getFields(fieldName)) {
if (bodyPart.getContentDisposition().getFileName() != null) {
// we have a file
// save it and mark it as delete on exit.
InputStream fileStream = bodyPart.getValueAs(InputStream.class);
String mimeType = bodyPart.getMediaType().toString();
// Use just the filename without complete path. File creation
// in case of remote deployment failing because fo this.
String fileName = bodyPart.getContentDisposition().getFileName();
if (fileName.contains("/")) {
fileName = Util.getName(fileName, '/');
} else {
if (fileName.contains("\\")) {
fileName = Util.getName(fileName, '\\');
}
}
File f = Util.saveFile(fileName, mimeType, fileStream);
FileUtils.deleteOnExit(f);
// put only the local path of the file in the same field.
data.put(fieldName, f.getAbsolutePath());
} else {
data.put(fieldName, bodyPart.getValue());
}
}
}
} catch (Exception ex) {
RestLogging.restLogger.log(Level.SEVERE, null, ex);
} finally {
formData.cleanup();
}
return data;
}
Aggregations