package org.jboss.as.patching.installation;
import static org.jboss.as.patching.Constants.JBOSS_PATCHING;
import static org.jboss.as.patching.Constants.JBOSS_PRODUCT_CONFIG_SERVICE;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import org.jboss.as.patching.installation.PatchableTarget.TargetInfo;
import org.jboss.as.patching.logging.PatchLogger;
import org.jboss.as.patching.validation.PatchingFileRenamingCollector;
import org.jboss.as.patching.validation.PatchingGarbageLocator;
import org.jboss.as.version.ProductConfig;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;
/**
* @author Emanuel Muckenhuber
*/
public class InstallationManagerService implements Service<InstallationManager> {
public static ServiceName NAME = JBOSS_PATCHING.append("manager");
private static final String MODULE_PATH = "module.path";
private static final String BUNDLES_DIR = "jboss.bundles.dir";
private volatile InstallationManager manager;
private final InjectedValue<ProductConfig> productConfig = new InjectedValue<ProductConfig>();
/**
* Install the installation manager service.
*
* @param serviceTarget
* @return the service controller for the installed installation manager
*/
public static ServiceController<InstallationManager> installService(ServiceTarget serviceTarget) {
final InstallationManagerService service = new InstallationManagerService();
return serviceTarget.addService(InstallationManagerService.NAME, service)
.addDependency(JBOSS_PRODUCT_CONFIG_SERVICE, ProductConfig.class, service.productConfig)
.setInitialMode(ServiceController.Mode.ACTIVE)
.install();
}
private InstallationManagerService() {
}
@Override
public synchronized void start(StartContext startContext) throws StartException {
try {
final File jbossHome = new File(SecurityActions.getSystemProperty("jboss.home.dir"));
final ProductConfig productConfig = this.productConfig.getValue();
this.manager = load(jbossHome, productConfig);
final File cleanupMaker = new File(manager.getInstalledImage().getInstallationMetadata(), "cleanup-patching-dirs");
boolean cleanup = cleanupMaker.exists();
for(InstalledIdentity installedIdentity : manager.getInstalledIdentities()) {
final Identity identity = manager.getDefaultIdentity().getIdentity();
final TargetInfo patchingInfo = identity.loadTargetInfo();
final StringBuilder buf = new StringBuilder();
for(String id : patchingInfo.getPatchIDs()) {
if(buf.length() > 0) {
buf.append(", ");
}
buf.append(id);
}
if(buf.length() == 0) {
buf.append("none");
}
PatchLogger.ROOT_LOGGER.logPatchingInfo(identity.getName(), patchingInfo.getCumulativePatchID(), buf.toString());
if(cleanup) {
try {
final PatchingGarbageLocator garbageLocator = PatchingGarbageLocator.getIninitialized(installedIdentity);
garbageLocator.deleteInactiveContent();
} catch (Exception e) {
PatchLogger.ROOT_LOGGER.debugf(e, "failed to garbage collect changes");
cleanup = false;
}
}
}
if(cleanup) {
cleanupMaker.delete();
}
final File renamingMaker = new File(manager.getInstalledImage().getInstallationMetadata(), "cleanup-renaming-files");
if (renamingMaker.exists()) {
try {
final PatchingFileRenamingCollector renaming = new PatchingFileRenamingCollector(renamingMaker);
renaming.renameFiles();
} catch (Exception e) {
PatchLogger.ROOT_LOGGER.debugf(e, "failed to rename files");
}
}
} catch (Exception e) {
throw new StartException(e);
}
}
@Override
public synchronized void stop(StopContext stopContext) {
this.manager = null;
}
@Override
public InstallationManager getValue() throws IllegalStateException, IllegalArgumentException {
final InstallationManager manager = this.manager;
if (manager == null) {
throw new IllegalStateException();
}
return manager;
}
protected static InstallationManager load(final File jbossHome, final ProductConfig productConfig) throws IOException {
final InstalledImage installedImage = InstalledIdentity.installedImage(jbossHome);
final List<File> moduleRoots = getModulePath(installedImage);
final List<File> bundlesRoots = getBundlePath(installedImage);
return InstallationManager.load(jbossHome, moduleRoots, bundlesRoots, productConfig);
}
private static List<File> getModulePath(final InstalledImage image) {
final List<File> path = new ArrayList<File>();
final String modulePath = SecurityActions.getSystemProperty(MODULE_PATH, SecurityActions.getEnv("JAVA_MODULEPATH"));
if (modulePath != null) {
final String[] paths = modulePath.split(Pattern.quote(File.pathSeparator));
for (final String s : paths) {
final File file = new File(s);
path.add(file);
}
} else {
path.add(image.getModulesDir());
}
return path;
}
private static List<File> getBundlePath(final InstalledImage image) {
final String prop = SecurityActions.getSystemProperty(BUNDLES_DIR);
final File bundleRoots = prop != null ? new File(prop) : image.getBundlesDir();
return Collections.singletonList(bundleRoots);
}
}