Search in sources :

Example 1 with InstallableUnitEvent

use of org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent 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 InstallableUnitEvent

use of org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent in project felix by apache.

the class DeploymentInstaller method invalidateAllUnits.

private void invalidateAllUnits(String reason) {
    List<File> affectedFiles = new LinkedList<>();
    List<InstallableUnitEvent> events = new LinkedList<>();
    withLock(this.unitsLock.writeLock(), () -> {
        for (Entry<File, InstallableUnitImpl> entry : this.units.entrySet()) {
            InstallableUnitImpl unit = entry.getValue();
            State currentState = unit.getState();
            if (EnumSet.of(State.RESOLVED, State.ERROR).contains(currentState)) {
                unit.setState(State.REMOVED);
                affectedFiles.add(entry.getKey());
                events.add(new InstallableUnitEvent(currentState, State.REMOVED, unit));
                debug("invalidated %s because: %s%n", entry.getKey(), reason);
            }
        }
    });
    notifyListeners(events);
    // Schedule re-resolution of the affected files.
    for (File file : affectedFiles) {
        putResolveJob(file);
    }
}
Also used : State(org.apache.felix.fileinstall.plugins.installer.State) JarFile(java.util.jar.JarFile) File(java.io.File) LinkedList(java.util.LinkedList) InstallableUnitEvent(org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent)

Example 3 with InstallableUnitEvent

use of org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent in project felix by apache.

the class DeploymentInstaller method installArtifacts.

private List<Bundle> installArtifacts(InstallableUnitImpl unit) {
    Supplier<List<Bundle>> func = () -> {
        State oldState = unit.getState();
        unit.setState(State.INSTALLING);
        notifyListeners(Collections.singleton(new InstallableUnitEvent(oldState, State.INSTALLING, unit)));
        try {
            // Install Bundles
            Collection<Artifact> artifacts = unit.getArtifacts();
            List<String> locations = artifacts.stream().map(Artifact::getLocation).collect(Collectors.toList());
            List<Bundle> installed = this.frameworkInstaller.addLocations(unit, locations);
            // Start bundles
            for (Bundle bundle : installed) {
                if (!isFragment(bundle)) {
                    bundle.start();
                }
            }
            // Mark unit installed
            oldState = unit.getState();
            unit.setState(State.INSTALLED);
            notifyListeners(Collections.singleton(new InstallableUnitEvent(oldState, State.INSTALLED, unit)));
            return installed;
        } catch (BundleException | IOException e) {
            oldState = unit.getState();
            unit.setState(State.ERROR);
            unit.setErrorMessage(e.getMessage());
            if (log != null) {
                log.log(LogService.LOG_ERROR, "Error installing artifact(s)", e);
            }
            notifyListeners(Collections.singleton(new InstallableUnitEvent(oldState, State.ERROR, unit)));
            return Collections.emptyList();
        }
    };
    return withLock(this.unitsLock.writeLock(), func);
}
Also used : State(org.apache.felix.fileinstall.plugins.installer.State) Bundle(org.osgi.framework.Bundle) Collection(java.util.Collection) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Artifact(org.apache.felix.fileinstall.plugins.installer.Artifact) InstallableUnitEvent(org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent)

Example 4 with InstallableUnitEvent

use of org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent 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 5 with InstallableUnitEvent

use of org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent in project felix by apache.

the class DeploymentInstaller method uninstallArtifacts.

private List<Bundle> uninstallArtifacts(InstallableUnitImpl unit) {
    List<Bundle> bundles = this.frameworkInstaller.removeSponsor(unit);
    // Mark unit uninstalled
    withLock(this.unitsLock.writeLock(), () -> {
        State oldState = unit.getState();
        if (unit.setState(State.REMOVED)) {
            notifyListeners(Collections.singleton(new InstallableUnitEvent(oldState, State.REMOVED, unit)));
        }
    });
    return bundles;
}
Also used : Bundle(org.osgi.framework.Bundle) State(org.apache.felix.fileinstall.plugins.installer.State) InstallableUnitEvent(org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent)

Aggregations

InstallableUnitEvent (org.apache.felix.fileinstall.plugins.installer.InstallableUnitEvent)7 State (org.apache.felix.fileinstall.plugins.installer.State)5 LinkedList (java.util.LinkedList)4 File (java.io.File)3 ArrayList (java.util.ArrayList)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 Collection (java.util.Collection)2 List (java.util.List)2 ArtifactInstaller (org.apache.felix.fileinstall.ArtifactInstaller)2 InstallableListener (org.apache.felix.fileinstall.plugins.installer.InstallableListener)2 Test (org.junit.Test)2 Bundle (org.osgi.framework.Bundle)2 JarFile (java.util.jar.JarFile)1 Artifact (org.apache.felix.fileinstall.plugins.installer.Artifact)1 InstallableUnit (org.apache.felix.fileinstall.plugins.installer.InstallableUnit)1