Search in sources :

Example 1 with ArtifactInstaller

use of org.apache.felix.fileinstall.ArtifactInstaller in project felix by apache.

the class InstallerIntegrationTest method testInstallArchives.

/*
     * This is a complex case that tests the interplay of multiple archives with
     * overlapping content.
     *
     * - Archive 1 contains bundles A and B.
     *
     * - Archive 2 contains bundles A and C.
     *
     * The process is as follows:
     *
     * i.   Make installer aware of both archives. Both now present as an
     * installable unit with 2 artifacts (A+B and A+C).
     *
     * ii.  Install archive 1.
     * Archive 2 gets invalidated and re-resolved. It now presents as an
     * installable unit with 1 artifact (C) because A is already in the
     * framework.
     *
     * iii. Remove archive 1. Archive 2 gets invalidated and
     * re-resolved. It now presents as an installable unit with 2 artifacts
     * (A+C) because A is no longer in the framework.
     *
     * Note that step (iii) is equivalent to deleting the archive from
     * FileInstall's load directory. Therefore it doesn't reappear as a RESOLVED
     * installable unit. To reinstall this archive, the user would have to copy
     * it back into the load directory.
     *
     */
@Test
public void testInstallArchives() throws Exception {
    // Register InstallableListener
    EventQueue eventQueue = new EventQueue();
    ServiceRegistration<InstallableListener> mockListenerReg = this.bundleContext.registerService(InstallableListener.class, eventQueue, null);
    try {
        assertEquals("Shouldn't be any install events yet", 0, eventQueue.depth());
        InstallableUnitEvent event;
        // Provide the sample archive
        File sampleArchive1 = new File(this.dataDir, "valid1.bar");
        ArtifactInstaller installer = this.artifactInstallerTracker.getService();
        assertNotNull("ArtifactInstaller service should exist", installer);
        assertTrue("installer should handle sample archive", installer.canHandle(sampleArchive1));
        installer.install(sampleArchive1);
        // Wait for resolve to occur
        Thread.sleep(2000);
        assertEquals(1, eventQueue.depth());
        event = eventQueue.pop();
        InstallableUnit unit1 = event.getUnit();
        assertEquals(State.RESOLVED, event.getNewState());
        assertEquals("samples.valid1", event.getUnit().getSymbolicName());
        assertEquals("samples.valid1 requires 2 bundles to be installed", 2, event.getUnit().getArtifacts().size());
        // Add a second archive
        File sampleArchive2 = new File(this.dataDir, "valid2.bar");
        assertTrue("installer should handle sample archive", installer.canHandle(sampleArchive2));
        installer.install(sampleArchive2);
        // Wait for resolve to occur
        Thread.sleep(2000);
        assertEquals(1, eventQueue.depth());
        event = eventQueue.pop();
        assertEquals(State.RESOLVED, event.getNewState());
        assertEquals("samples.valid2", event.getUnit().getSymbolicName());
        assertEquals("samples.valid2 requires 2 bundles to be installed", 2, event.getUnit().getArtifacts().size());
        // Install first archive.
        unit1.install().getValue();
        // Check bundles were actually installed!
        assertNotNull(findBundle("org.example.a"));
        assertNotNull(findBundle("org.example.b"));
        // The installation of first archive should cause invalidation of second archive resolution result, followed by re-resolve.
        // First, installing #1
        event = eventQueue.pop();
        assertEquals(State.INSTALLING, event.getNewState());
        assertEquals("samples.valid1", event.getUnit().getSymbolicName());
        // Next installed #1
        event = eventQueue.pop();
        assertEquals(State.INSTALLED, event.getNewState());
        assertEquals("samples.valid1", event.getUnit().getSymbolicName());
        // Next removed #2 (due to invalidation)
        // Short sleep necessary because the invalidate can happen on another thread (eg framework refresh)
        Thread.sleep(500);
        event = eventQueue.pop();
        assertEquals(State.REMOVED, event.getNewState());
        assertEquals("samples.valid2", event.getUnit().getSymbolicName());
        // Next resolved #2 (re-resolve after invalidation)
        // Another sleep because the re-resolve happens after at least 1 sec delay
        Thread.sleep(2000);
        event = eventQueue.pop();
        assertEquals(State.RESOLVED, event.getNewState());
        assertEquals("samples.valid2", event.getUnit().getSymbolicName());
        assertEquals("samples.valid2 now requires 1 bundle to be installed", 1, event.getUnit().getArtifacts().size());
        assertEquals(0, eventQueue.depth());
        // Now uninstall first archive
        installer.uninstall(sampleArchive1);
        Thread.sleep(500);
        // Check bundles were actually uninstalled!
        assertNull(findBundle("org.example.a"));
        assertNull(findBundle("org.example.b"));
        // Removed event for #1
        Thread.sleep(500);
        event = eventQueue.pop();
        assertEquals(State.REMOVED, event.getNewState());
        assertEquals("samples.valid1", event.getUnit().getSymbolicName());
        // Removed event for #2 due to invalidation
        event = eventQueue.pop();
        assertEquals(State.REMOVED, event.getNewState());
        assertEquals("samples.valid2", event.getUnit().getSymbolicName());
        // Re-resolution of #2 after a little sleep
        Thread.sleep(2000);
        event = eventQueue.pop();
        assertEquals(State.RESOLVED, event.getNewState());
        assertEquals("samples.valid2", event.getUnit().getSymbolicName());
        assertEquals("samples.valid2 now requires 2 bundle to be installed", 2, event.getUnit().getArtifacts().size());
        assertEquals(0, eventQueue.depth());
    } finally {
        mockListenerReg.unregister();
    }
}
Also used : ArtifactInstaller(org.apache.felix.fileinstall.ArtifactInstaller) InstallableUnit(org.apache.felix.fileinstall.plugins.installer.InstallableUnit) File(java.io.File) InstallableListener(org.apache.felix.fileinstall.plugins.installer.InstallableListener) InstallableUnitEvent(org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent) Test(org.junit.Test)

Example 2 with ArtifactInstaller

use of org.apache.felix.fileinstall.ArtifactInstaller in project felix by apache.

the class DirectoryWatcher method install.

/**
 * Install an artifact and return the bundle object.
 * It uses {@link Artifact#getPath()} as location
 * of the new bundle. Before installing a file,
 * it sees if the file has been identified as a bad file in
 * earlier run. If yes, then it compares to see if the file has changed
 * since then. It installs the file if the file has changed.
 * If the file has not been identified as a bad file in earlier run,
 * then it always installs it.
 *
 * @param artifact the artifact to be installed
 * @return Bundle object that was installed
 */
private Bundle install(Artifact artifact) {
    File path = artifact.getPath();
    Bundle bundle = null;
    AtomicBoolean modified = new AtomicBoolean();
    try {
        // If the listener is an installer, ask for an update
        if (artifact.getListener() instanceof ArtifactInstaller) {
            ((ArtifactInstaller) artifact.getListener()).install(path);
        } else // if the listener is an url transformer
        if (artifact.getListener() instanceof ArtifactUrlTransformer) {
            Artifact badArtifact = installationFailures.get(path);
            if (badArtifact != null && badArtifact.getChecksum() == artifact.getChecksum()) {
                // Don't attempt to install it; nothing has changed.
                return null;
            }
            URL transformed = artifact.getTransformedUrl();
            String location = transformed.toString();
            BufferedInputStream in = new BufferedInputStream(transformed.openStream());
            bundle = installOrUpdateBundle(location, in, artifact.getChecksum(), modified);
            artifact.setBundleId(bundle.getBundleId());
        } else // if the listener is an artifact transformer
        if (artifact.getListener() instanceof ArtifactTransformer) {
            Artifact badArtifact = installationFailures.get(path);
            if (badArtifact != null && badArtifact.getChecksum() == artifact.getChecksum()) {
                // Don't attempt to install it; nothing has changed.
                return null;
            }
            File transformed = artifact.getTransformed();
            String location = path.toURI().normalize().toString();
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(transformed != null ? transformed : path));
            bundle = installOrUpdateBundle(location, in, artifact.getChecksum(), modified);
            artifact.setBundleId(bundle.getBundleId());
        }
        installationFailures.remove(path);
        setArtifact(path, artifact);
    } catch (Exception e) {
        log(Logger.LOG_ERROR, "Failed to install artifact: " + path, e);
        // Add it our bad jars list, so that we don't
        // attempt to install it again and again until the underlying
        // jar has been modified.
        installationFailures.put(path, artifact);
    }
    return modified.get() ? bundle : null;
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArtifactInstaller(org.apache.felix.fileinstall.ArtifactInstaller) BufferedInputStream(java.io.BufferedInputStream) Bundle(org.osgi.framework.Bundle) ArtifactTransformer(org.apache.felix.fileinstall.ArtifactTransformer) ArtifactUrlTransformer(org.apache.felix.fileinstall.ArtifactUrlTransformer) File(java.io.File) URL(java.net.URL) FileInputStream(java.io.FileInputStream) URISyntaxException(java.net.URISyntaxException) BundleException(org.osgi.framework.BundleException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 3 with ArtifactInstaller

use of org.apache.felix.fileinstall.ArtifactInstaller in project felix by apache.

the class InstallerIntegrationTest method testErrorFromInvalidArchive.

@Test
public void testErrorFromInvalidArchive() throws Exception {
    Object[] artifactInstallers = this.artifactInstallerTracker.getServices();
    assertNotNull("Should be exactly one ArtifactInstaller service", artifactInstallers);
    assertEquals("Should be exactly one ArtifactInstaller service", 1, artifactInstallers.length);
    // Register mock InstallableListener
    List<String> installEvents = new LinkedList<>();
    InstallableListener mockInstallListener = new InstallableListener() {

        @Override
        public void installableUnitsChanged(Collection<InstallableUnitEvent> events) {
            for (InstallableUnitEvent event : events) {
                String message = String.format("%s %s", event.getNewState(), event.getUnit().getSymbolicName());
                installEvents.add(message);
            }
        }
    };
    ServiceRegistration<InstallableListener> mockListenerReg = this.bundleContext.registerService(InstallableListener.class, mockInstallListener, null);
    try {
        assertEquals("Shouldn't be any install events yet", 0, installEvents.size());
        // Provide the sample archive
        File sampleArchive = new File(this.dataDir, "org.example.invalid-missing-rb.bar");
        ArtifactInstaller installer = this.artifactInstallerTracker.getService();
        assertTrue("installer should handle sample archive", installer.canHandle(sampleArchive));
        installer.install(sampleArchive);
        // Wait for resolve to occur
        Thread.sleep(2000);
        assertEquals(1, installEvents.size());
        assertEquals("ERROR org.example.invalid-missing-rb", installEvents.get(0));
    } finally {
        mockListenerReg.unregister();
    }
}
Also used : ArtifactInstaller(org.apache.felix.fileinstall.ArtifactInstaller) Collection(java.util.Collection) File(java.io.File) LinkedList(java.util.LinkedList) InstallableListener(org.apache.felix.fileinstall.plugins.installer.InstallableListener) InstallableUnitEvent(org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent) Test(org.junit.Test)

Example 4 with ArtifactInstaller

use of org.apache.felix.fileinstall.ArtifactInstaller in project felix by apache.

the class InstallerIntegrationTest method before.

@Before
public void before() throws Exception {
    assertAllBundlesResolved();
    // Track ArtifactInstaller service ONLY from bundle org.apache.felix.fileinstall.plugins.installer, to avoid potential interference
    Bundle installerBundle = findBundle("org.apache.felix.fileinstall.plugins.installer");
    Filter artifactInstallerTrackerFilter = FrameworkUtil.createFilter(String.format("(&(objectClass=%s)(service.bundleid=%d))", ArtifactInstaller.class.getName(), installerBundle.getBundleId()));
    this.artifactInstallerTracker = new ServiceTracker<>(this.bundleContext, artifactInstallerTrackerFilter, null);
    this.artifactInstallerTracker.open();
    // Wait up to 5 seconds for ArtifactInstaller to appear
    ArtifactInstaller artifactInstaller = this.artifactInstallerTracker.waitForService(5000);
    if (artifactInstaller == null) {
        fail("ArtifactInstaller service not available within 5 seconds");
    }
    this.fwkInstallerTracker = new ServiceTracker<>(this.bundleContext, FrameworkInstaller.class, null);
    this.fwkInstallerTracker.open();
}
Also used : Filter(org.osgi.framework.Filter) ArtifactInstaller(org.apache.felix.fileinstall.ArtifactInstaller) Bundle(org.osgi.framework.Bundle) FrameworkInstaller(org.apache.felix.fileinstall.plugins.installer.FrameworkInstaller) Before(org.junit.Before)

Example 5 with ArtifactInstaller

use of org.apache.felix.fileinstall.ArtifactInstaller in project felix by apache.

the class DirectoryWatcher method uninstall.

/**
 * Uninstall a jar file.
 */
private Bundle uninstall(Artifact artifact) {
    Bundle bundle = null;
    try {
        File path = artifact.getPath();
        // Find a listener for this artifact if needed
        if (artifact.getListener() == null) {
            artifact.setListener(findListener(path, fileInstall.getListeners()));
        }
        // Forget this artifact
        removeArtifact(path);
        // Delete transformed file
        deleteTransformedFile(artifact);
        // if the listener is an installer, uninstall the artifact
        if (artifact.getListener() instanceof ArtifactInstaller) {
            ((ArtifactInstaller) artifact.getListener()).uninstall(path);
        } else // else we need uninstall the bundle
        if (artifact.getBundleId() != 0) {
            // old can't be null because of the way we calculate deleted list.
            bundle = context.getBundle(artifact.getBundleId());
            if (bundle == null) {
                log(Logger.LOG_WARNING, "Failed to uninstall bundle: " + path + " with id: " + artifact.getBundleId() + ". The bundle has already been uninstalled", null);
                return null;
            }
            log(Logger.LOG_INFO, "Uninstalling bundle " + bundle.getBundleId() + " (" + bundle.getSymbolicName() + ")", null);
            bundle.uninstall();
        }
    } catch (Exception e) {
        log(Logger.LOG_WARNING, "Failed to uninstall artifact: " + artifact.getPath(), e);
    }
    return bundle;
}
Also used : ArtifactInstaller(org.apache.felix.fileinstall.ArtifactInstaller) Bundle(org.osgi.framework.Bundle) File(java.io.File) URISyntaxException(java.net.URISyntaxException) BundleException(org.osgi.framework.BundleException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Aggregations

ArtifactInstaller (org.apache.felix.fileinstall.ArtifactInstaller)6 File (java.io.File)5 Bundle (org.osgi.framework.Bundle)4 BufferedInputStream (java.io.BufferedInputStream)2 FileInputStream (java.io.FileInputStream)2 IOException (java.io.IOException)2 MalformedURLException (java.net.MalformedURLException)2 URISyntaxException (java.net.URISyntaxException)2 URL (java.net.URL)2 ArtifactTransformer (org.apache.felix.fileinstall.ArtifactTransformer)2 ArtifactUrlTransformer (org.apache.felix.fileinstall.ArtifactUrlTransformer)2 InstallableListener (org.apache.felix.fileinstall.plugins.installer.InstallableListener)2 InstallableUnitEvent (org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent)2 Test (org.junit.Test)2 BundleException (org.osgi.framework.BundleException)2 InputStream (java.io.InputStream)1 Collection (java.util.Collection)1 LinkedList (java.util.LinkedList)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 JarInputStream (java.util.jar.JarInputStream)1