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

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

There is a newer version: 1.2.0
Show newest version
/**
 * Copyright (c) 2013-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.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TimerTask;

import org.ow2.petals.microkernel.api.jbi.management.DeploymentService;
import org.ow2.petals.microkernel.api.jbi.management.InstallationService;
import org.ow2.petals.microkernel.api.system.SystemStateService;
import org.ow2.petals.systemstate.generated.Component;
import org.ow2.petals.systemstate.generated.ServiceAssembly;
import org.ow2.petals.systemstate.generated.SharedLibrary;

import com.ebmwebsourcing.easycommons.log.LoggingUtil;

/**
 * The {@link TimerTask} scanning the uninstallation directory
 * 
 * @author Christophe DENEUX - Linagora
 * 
 */
public class InstalledDirectoryScanningTask extends TimerTask {

    private final InstallationService installationService;

    private final DeploymentService deploymentService;

    private final SystemStateService systemStateService;

    private final ArchiveFileFilter archiveFilter = ArchiveFileFilter.getInstance();

    private final File installedDir;

    private final List previousArchives = new ArrayList();

    private final LoggingUtil logger;

    public InstalledDirectoryScanningTask(final InstallationService installationService,
            final DeploymentService deploymentService, final SystemStateService systemStateService,
            final File installedDir, final LoggingUtil logger) {
        super();

        this.installationService = installationService;
        this.deploymentService = deploymentService;
        this.systemStateService = systemStateService;
        this.installedDir = installedDir;
        this.logger = logger;
    }

    @Override
    public void run() {
        final File[] newUninstalls = this.installedDir.listFiles(this.archiveFilter);
        if (newUninstalls != null) {
            final List currentArchives = Arrays.asList(newUninstalls);
            final List newUninstallList = new ArrayList();

            synchronized (this.previousArchives) {
                // get removed archives
                for (final File archive : this.previousArchives) {
                    if (!currentArchives.contains(archive)) {
                        newUninstallList.add(archive);
                    }
                }

                this.previousArchives.clear();

                if (!newUninstallList.isEmpty()) {
                    this.resolveJBIArtefactDependencies(newUninstallList);
                    this.uninstall(newUninstallList);

                }

                this.previousArchives.addAll(currentArchives);

            }
        } else {
            this.logger.warning("Error when the autoloader scanned the directory '"
                    + this.installedDir.getPath() + "'. Perhaps, the directory was deleted !");
        }
    }

    /**
     * For each JBI artefact to uninstall, search the dependent artefacts and
     * add them to the List if they are not already set.
     * 
     * @param filesToUninstall
     *            The initial collection of files to uninstall
     */
    private void resolveJBIArtefactDependencies(final List archivesToUninstall) {

        // resolve the dependent SAs against the components to uninstall
        final List componentsToUninstall = this.getComponentNames(archivesToUninstall);
        for (final String componentName : componentsToUninstall) {
            try {
                final String[] deployedSAOnComponent = this.deploymentService
                        .getDeployedServiceAssembliesForComponent(componentName);
                for (final String serviceAssemblyName : deployedSAOnComponent) {
                    final String archiveName = this.systemStateService.getServiceAssemblyStateHolder(
                            serviceAssemblyName).getArchiveName();
                    final File archiveFile = new File(this.installedDir, archiveName);
                    if (!archivesToUninstall.contains(archiveFile)) {
                        archivesToUninstall.add(archiveFile);
                    }
                }
            } catch (final Exception e) {
                // The implementation of
                // DeploymentService.getDeployedServiceAssembliesForComponent
                // does not throw exception even if one is declared, so we
                // only log it in case the implementation will be changed
                // and will throw an exception.
                this.logger.warning("Error resolving JBI artifacts dependencies", e);
            }
        }

        // resolve the dependent components against the SLs to uninstall
        final List sharedLibrariesToUninstall = this
                .getSharedLibraryNames(archivesToUninstall);
        for (final String[] sharedLibraryName : sharedLibrariesToUninstall) {
            try {
                final String[] componentNames = this.installationService.getInstalledComponentsForSharedLibrary(
                        sharedLibraryName[0], sharedLibraryName[1]);
                for (String componentName : componentNames) {
                    final String archiveName = this.systemStateService
                            .getServiceAssemblyStateHolder(componentName).getArchiveName();
                    final File archiveFile = new File(this.installedDir, archiveName);
                    if (!archivesToUninstall.contains(archiveFile)) {
                        archivesToUninstall.add(archiveFile);
                    }
                }
            } catch (Exception e) {
                this.logger.warning(
                        "Exception while getting components for SL " + Arrays.deepToString(sharedLibraryName), e);
                continue;
            }
        }
    }

    /**
     * Get the component names from the archive list.
     * 
     * @param archivesToUninstall
     *            The archive list
     * @return The list of shared library names
     */
    private List getComponentNames(final List archivesToUninstall) {
        final List componentStateNames = new ArrayList();

        final List componentStateHolders = this.systemStateService
                .getComponentStateHolders();
        for (final File archive : archivesToUninstall) {
            for (final Component componentStateHolder : componentStateHolders) {
                if (archive.getName().equals(componentStateHolder.getArchiveName())) {
                    componentStateNames.add(componentStateHolder.getName());
                }
            }
        }

        return componentStateNames;
    }

    /**
     * Get the shared library names and version from the archive list
     * 
     * @param archivesToUninstall
     *            The archive list
     * @return The list of shared library names
     */
    private List getSharedLibraryNames(final List archivesToUninstall) {
        final List sharedLibraryNames = new ArrayList();

        final List sharedLibraryStateHolders = this.systemStateService
                .getSharedLibraryStateHolders();
        for (final File archive : archivesToUninstall) {
            for (final SharedLibrary sharedLibraryStateHolder : sharedLibraryStateHolders) {
                if (archive.getName().equals(sharedLibraryStateHolder.getArchiveName())) {
                    sharedLibraryNames.add(new String[] { sharedLibraryStateHolder.getName(),
                            sharedLibraryStateHolder.getVersion() });
                }
            }
        }

        return sharedLibraryNames;
    }

    /**
     * Uninstall the given list of files.
     * 
     * @param archiveFiles
     *            the list of JBI archives
     */
    private void uninstall(List archiveFiles) {
        this.logger.call();

        try {
            // Check if one of the files to uninstall match one of the
            // archiveUrl of the installed entities. If yes, this entity must be
            // uninstalled.
            final List serviceAssemblyToUninstall = this
                    .getServiceAssemblyNames(archiveFiles);
            final List componentToUninstall = this.getComponentNames(archiveFiles);
            final List sharedLibraryToUninstall = this.getSharedLibraryNames(archiveFiles);

            for (final String name : serviceAssemblyToUninstall) {
                this.performUndeploySA(name);
            }
            for (final String name : componentToUninstall) {
                this.performUninstallComponent(name);
            }
            for (final String[] sl : sharedLibraryToUninstall) {
                this.performUninstallSL(sl[0]);
            }
        } catch (final Throwable e) {
            this.logger.error("Error during uninstallation of JBI artifact(s)", e);
        }

    }

    /**
     * Undeploy the specified service assembly. isToBeDeleted is set to true.
     * 
     * @param name
     *            The service assembly
     */
    private void performUndeploySA(String name) {
        this.deploymentService.forceUndeploy(name);
    }

    /**
     * Uninstall the specified component.
     * 
     * @param name
     *            The component
     */
    private void performUninstallComponent(String name) {
        this.installationService.forceUnloadInstaller(name);
    }

    /**
     * Uninstall a shared library.
     * 
     * @param name
     *            The shared library
     */
    private void performUninstallSL(String name) {
        this.installationService.uninstallSharedLibrary(name);
    }

    /**
     * Get the service assembly names from the archive list.
     * 
     * @param archivesToUninstall
     *            The archive list
     * @return The list of service assembly names
     */
    private List getServiceAssemblyNames(final List archivesToUninstall) {
        final List serviceAssemblyNames = new ArrayList();

        final List serviceAssemblyStateHolders = this.systemStateService
                .getServiceAssemblyStateHolders();
        for (final File archive : archivesToUninstall) {
            for (final ServiceAssembly serviceAssemblyStateHolder : serviceAssemblyStateHolders) {
                if (archive.getName().equals(serviceAssemblyStateHolder.getArchiveName())) {
                    serviceAssemblyNames.add(serviceAssemblyStateHolder.getName());
                    break;
                }
            }
        }

        return serviceAssemblyNames;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy