All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.petals.extension.autoloader.AutoLoaderServiceImpl Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
/**
 * Copyright (c) 2005-2012 EBM WebSourcing, 2012-2016 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.extension.autoloader;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Timer;
import java.util.logging.Logger;

import org.apache.commons.io.FileUtils;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.fraclet.annotations.Interface;
import org.objectweb.fractal.fraclet.annotations.Lifecycle;
import org.objectweb.fractal.fraclet.annotations.Requires;
import org.objectweb.fractal.fraclet.extensions.Controller;
import org.objectweb.fractal.fraclet.types.Step;
import org.ow2.petals.clientserverapi.configuration.ContainerConfiguration;
import org.ow2.petals.launcher.api.server.conf.ConfigurationProperties;
import org.ow2.petals.microkernel.api.configuration.ConfigurationService;
import org.ow2.petals.microkernel.api.extension.InstallationExtension;
import org.ow2.petals.microkernel.api.extension.InstallationExtensionException;
import org.ow2.petals.microkernel.api.extension.PetalsPostExtensionController;

import com.ebmwebsourcing.easycommons.log.LoggingUtil;
import com.ebmwebsourcing.easycommons.properties.PropertiesException;
import com.ebmwebsourcing.easycommons.properties.PropertiesHelper;

/**
 * This class is used to load automatically components which are placed in the "autoLoad" directory. 
 * 

* It scans the directory periodically and check if new * components are presents. The @ link InstallationServiceMBean} is called for * each of those components. The whole process of installation is done (install * + start) After being threat, the archives of the components are removed. A * file "fileName.success" will be created if success A file "fileName.failed" * will be created otherwise, containing the related exception. *

* * @author Adrien Louis - EBM WebSourcing */ @org.objectweb.fractal.fraclet.annotations.Component(provides = @Interface(name = PetalsPostExtensionController.INST_EXT_SRV_ITF_NAME, signature = InstallationExtension.class) ) public class AutoLoaderServiceImpl implements InstallationExtension { /** * The component. */ @Controller private Component comp; /** * Name of the property defining the directory scanned to install artifacts. */ public static final String PATH_INSTALL_PROPERTY_NAME = "petals.autoloader.path.install"; /** * Default value of the directory scanned to install artifacts: ${ * {@value ConfigurationProperties#DATA_ROOT_DIRECTORY_PROPERTY_NAME}/install */ private static final String DEFAULT_PATH_INSTALL = "${" + ConfigurationProperties.DATA_ROOT_DIRECTORY_PROPERTY_NAME + "}" + File.separator + "install"; /** * Name of the property defining the directory scanned to uninstall * artifacts. */ public static final String PATH_INSTALLED_PROPERTY_NAME = "petals.autoloader.path.installed"; /** * Default value of the directory scanned to uninstall artifacts: ${ * {@value ConfigurationProperties#DATA_ROOT_DIRECTORY_PROPERTY_NAME}/installed */ private static final String DEFAULT_PATH_INSTALLED = "${" + ConfigurationProperties.DATA_ROOT_DIRECTORY_PROPERTY_NAME + "}" + File.separator + "installed"; /** * Name of the property defining the scan period of the auto-loader. */ public static final String SCAN_PERIOD_PROPERTY_NAME = "petals.autoloader.scan.period"; /** * Default value, in milliseconds, of the period between two scans of * directories */ public static final long DEFAULT_SCAN_PERIOD = 4000L; @Requires(name = "configuration") private ConfigurationService configurationService; @Requires(name = "installDirectoryScanner") private DirectoryScanner installDirectoryScanner; @Requires(name = "installedDirectoryScanner") private DirectoryScanner installedDirectoryScanner; private File installDirectory; private File installedDirectory; private final LoggingUtil log = new LoggingUtil(Logger.getLogger(AutoLoaderService.FRACTAL_COMPONENT_LOGGER_NAME)); /** * The local container information. */ private ContainerConfiguration containerConfiguration; /** * Timer that launch scans of directories */ private Timer directoriesToScanTimer; /** * Initialize the autoloader. */ @Lifecycle(step = Step.START) public void start() throws PropertiesException { this.log.start(); this.containerConfiguration = this.configurationService.getContainerConfiguration(); final Map extraConfProperties = this.containerConfiguration .getExtraConfiguration(); { final String installDirectoryPropertyValue = extraConfProperties .get(PATH_INSTALL_PROPERTY_NAME); if (installDirectoryPropertyValue == null || installDirectoryPropertyValue.isEmpty()) { // No value defined for the directory to scan to install // artifacts, we use the default value final String installDirectoryStr = PropertiesHelper.resolveString( DEFAULT_PATH_INSTALL, this.configurationService.getServerProperties()); this.installDirectory = new File(installDirectoryStr); } else { this.installDirectory = new File(installDirectoryPropertyValue); } if (!this.installDirectory.exists()) { if (!this.installDirectory.mkdirs()) { this.log.warning(String .format("Unable to create the directory for installation '%s'. Potential problems can occurs later.", this.installDirectory.getAbsolutePath())); } } else if (!this.installDirectory.isDirectory()) { this.log.warning(String .format("The directory for installation '%s' is invalid. Potential problems can occurs later.", this.installDirectory.getAbsolutePath())); } } { final String installedDirectoryPropertyValue = extraConfProperties .get(PATH_INSTALLED_PROPERTY_NAME); if (installedDirectoryPropertyValue == null || installedDirectoryPropertyValue.isEmpty()) { // No value defined for the directory to scan to uninstall // artifacts, we use the default value final String installedDirectoryStr = PropertiesHelper.resolveString( DEFAULT_PATH_INSTALLED, this.configurationService.getServerProperties()); this.installedDirectory = new File(installedDirectoryStr); } else { this.installedDirectory = new File(installedDirectoryPropertyValue); } if (!this.installedDirectory.exists()) { if (!this.installedDirectory.mkdirs()) { this.log.warning(String .format("Unable to create the directory for uninstallation '%s'. Potential problems can occurs later.", this.installedDirectory.getAbsolutePath())); } } else if (!this.installedDirectory.isDirectory()) { this.log.warning(String .format("The directory for uninstallation '%s' is invalid. Potential problems can occurs later.", this.installedDirectory.getAbsolutePath())); } } final String scanPeriodStr = extraConfProperties.get(SCAN_PERIOD_PROPERTY_NAME); long scanPeriod; if (scanPeriodStr == null || scanPeriodStr.isEmpty()) { scanPeriod = DEFAULT_SCAN_PERIOD; } else { try { scanPeriod = Long.parseLong(scanPeriodStr); } catch (final NumberFormatException e) { this.log.warning(String.format( "Invalid value '%s' for property '%s'. Default value used: %d", scanPeriodStr, SCAN_PERIOD_PROPERTY_NAME, DEFAULT_SCAN_PERIOD)); scanPeriod = DEFAULT_SCAN_PERIOD; } } this.directoriesToScanTimer = new Timer("Autoloader Timer scanning directories"); this.installDirectoryScanner.startScanner(this.installDirectory, this.directoriesToScanTimer, scanPeriod); this.installedDirectoryScanner.startScanner(this.installedDirectory, this.directoriesToScanTimer, scanPeriod); this.log.info("Petals extension \"Autoloader\" started."); this.log.end(); } /** * Stop the autoload of the components. TODO : synchronization, does the * autoload must wait before the end of an installation before closing? */ @Lifecycle(step = Step.STOP) public void stop() { this.log.start(); this.directoriesToScanTimer.cancel(); this.log.info("Petals extension \"Autoloader\" stopped."); this.log.end(); } /** * {@inheritDoc} */ public void onInstallation(final String installedArchive) throws InstallationExtensionException { // On installation, the archive is copied into the direction scanned to uninstall artifacts. try { FileUtils.copyFileToDirectory(new File(installedArchive), this.installedDirectory); } catch (final IOException e) { throw new InstallationExtensionException( "Error copying the installed archive into the repository of the auto-loader.", e); } } /** * {@inheritDoc} */ public void onInstallationUndo(final String installedArchive) throws InstallationExtensionException { final File targetFile = new File(this.installedDirectory, new File(installedArchive).getName()); if (targetFile.exists()) { try { FileUtils.forceDelete(targetFile); } catch (final IOException e) { this.log.error("Installed archive can not be undo from the autoloader repository", e); } } } /** * {@inheritDoc} */ public void onUninstallation(final String uninstalledArchive) throws InstallationExtensionException { final File targetFile = new File(this.installedDirectory, new File(uninstalledArchive).getName()); if ((targetFile != null) && targetFile.exists()) { targetFile.delete(); } } /** * {@inheritDoc} */ public void onUninstallationUndo(final String uninstalledArchive) throws InstallationExtensionException { // NOP } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy