Search in sources :

Example 91 with BundleWiring

use of org.osgi.framework.wiring.BundleWiring in project karaf by apache.

the class GuardProxyCatalogTest method testHandleServiceModified2.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testHandleServiceModified2() throws Exception {
    // no configuration used in this test...
    BundleContext bc = mockConfigAdminBundleContext();
    GuardProxyCatalog gpc = new GuardProxyCatalog(bc);
    // The service being proxied has these properties
    long serviceID = 1L;
    final Hashtable<String, Object> serviceProps = new Hashtable<>();
    serviceProps.put(Constants.OBJECTCLASS, new String[] { TestServiceAPI.class.getName() });
    serviceProps.put(Constants.SERVICE_ID, serviceID);
    BundleContext providerBC = EasyMock.createNiceMock(BundleContext.class);
    EasyMock.expect(providerBC.registerService(EasyMock.aryEq(new String[] { TestServiceAPI.class.getName() }), EasyMock.anyObject(), EasyMock.anyObject(Dictionary.class))).andAnswer((IAnswer) () -> {
        final Dictionary props = (Dictionary) EasyMock.getCurrentArguments()[2];
        assertEquals(Boolean.TRUE, props.get(GuardProxyCatalog.PROXY_SERVICE_KEY));
        ServiceRegistration reg = EasyMock.createMock(ServiceRegistration.class);
        ServiceReference sr = mockServiceReference(props);
        EasyMock.expect(reg.getReference()).andReturn(sr).anyTimes();
        reg.setProperties(EasyMock.isA(Dictionary.class));
        EasyMock.expectLastCall().andAnswer(() -> {
            // Push the update into the service reference
            ArrayList<String> oldKeys = Collections.list(props.keys());
            for (String key : oldKeys) {
                props.remove(key);
            }
            Dictionary<String, Object> newProps = (Dictionary<String, Object>) EasyMock.getCurrentArguments()[0];
            for (String key : Collections.list(newProps.keys())) {
                props.put(key, newProps.get(key));
            }
            return null;
        }).once();
        EasyMock.replay(reg);
        return reg;
    }).anyTimes();
    EasyMock.replay(providerBC);
    // In some cases the proxy-creating code is looking for a classloader (e.g. when run through
    // a coverage tool such as EclEmma). This will satisfy that.
    BundleWiring bw = EasyMock.createMock(BundleWiring.class);
    EasyMock.expect(bw.getClassLoader()).andReturn(getClass().getClassLoader()).anyTimes();
    EasyMock.replay(bw);
    // The mock bundle that provides the original service (and also the proxy is registered with this)
    Bundle providerBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(providerBundle.getBundleContext()).andReturn(providerBC).anyTimes();
    EasyMock.expect(providerBundle.adapt(BundleWiring.class)).andReturn(bw).anyTimes();
    EasyMock.replay(providerBundle);
    ServiceReference sr = mockServiceReference(providerBundle, serviceProps);
    gpc.proxyIfNotAlreadyProxied(sr);
    GuardProxyCatalog.CreateProxyRunnable runnable = gpc.createProxyQueue.take();
    runnable.run(getProxyManager());
    ServiceRegistrationHolder holder = gpc.proxyMap.get(serviceID);
    ServiceRegistration<?> reg = holder.registration;
    assertFalse("No roles defined for this service using configuration, so roles property should not be set", Arrays.asList(reg.getReference().getPropertyKeys()).contains(GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY));
    for (String key : serviceProps.keySet()) {
        assertEquals(serviceProps.get(key), reg.getReference().getProperty(key));
    }
    assertEquals(Boolean.TRUE, reg.getReference().getProperty(GuardProxyCatalog.PROXY_SERVICE_KEY));
    // now change the original service and let the proxy react
    serviceProps.put(GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY, "foobar");
    assertEquals("Precondition, the mocked reference should have picked up this change", "foobar", sr.getProperty(GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY));
    gpc.serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED, sr));
    assertEquals("Changing the service should not change the number of proxies", 1, gpc.proxyMap.size());
    assertFalse("The roles property set on the modified service should have been removed", Arrays.asList(reg.getReference().getPropertyKeys()).contains(GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY));
    assertEquals(Boolean.TRUE, reg.getReference().getProperty(GuardProxyCatalog.PROXY_SERVICE_KEY));
}
Also used : Dictionary(java.util.Dictionary) CreateProxyRunnable(org.apache.karaf.service.guard.impl.GuardProxyCatalog.CreateProxyRunnable) Hashtable(java.util.Hashtable) Bundle(org.osgi.framework.Bundle) BundleWiring(org.osgi.framework.wiring.BundleWiring) ArrayList(java.util.ArrayList) ServiceRegistrationHolder(org.apache.karaf.service.guard.impl.GuardProxyCatalog.ServiceRegistrationHolder) ServiceReference(org.osgi.framework.ServiceReference) IAnswer(org.easymock.IAnswer) ServiceEvent(org.osgi.framework.ServiceEvent) BundleContext(org.osgi.framework.BundleContext) ServiceRegistration(org.osgi.framework.ServiceRegistration) Test(org.junit.Test)

Example 92 with BundleWiring

use of org.osgi.framework.wiring.BundleWiring in project karaf by apache.

the class GuardProxyCatalogTest method testCreateProxy.

@SuppressWarnings({ "unchecked", "rawtypes" })
public Object testCreateProxy(BundleContext bc, Class[] objectClasses, final Class[] proxyRegClasses, Object testService, final Map<ServiceReference, Object> serviceMap) throws Exception {
    // A linked hash map to keep iteration order over the keys predictable
    final LinkedHashMap<String, Class> objClsMap = new LinkedHashMap<>();
    for (Class cls : objectClasses) {
        objClsMap.put(cls.getName(), cls);
    }
    // A linked hash map to keep iteration order over the keys predictable
    final LinkedHashMap<String, Class> proxyRegClsMap = new LinkedHashMap<>();
    for (Class cls : proxyRegClasses) {
        proxyRegClsMap.put(cls.getName(), cls);
    }
    // Create the object that is actually being tested here
    GuardProxyCatalog gpc = new GuardProxyCatalog(bc);
    // The service being proxied has these properties
    long serviceID = Long.MAX_VALUE;
    final Hashtable<String, Object> serviceProps = new Hashtable<>();
    serviceProps.put(Constants.OBJECTCLASS, objClsMap.keySet().toArray(new String[] {}));
    serviceProps.put(Constants.SERVICE_ID, serviceID);
    // will be overwritten
    serviceProps.put(GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY, Arrays.asList("everyone"));
    serviceProps.put("bar", "foo");
    // The mock bundle context for the bundle providing the service is set up here
    BundleContext providerBC = EasyMock.createMock(BundleContext.class);
    // These are the expected service properties of the proxy registration. Note the proxy marker...
    final Hashtable<String, Object> expectedProxyProps = new Hashtable<>(serviceProps);
    expectedProxyProps.put(GuardProxyCatalog.PROXY_SERVICE_KEY, Boolean.TRUE);
    // This will check that the right proxy is being registered.
    EasyMock.expect(providerBC.registerService(EasyMock.isA(String[].class), EasyMock.anyObject(), EasyMock.isA(Dictionary.class))).andAnswer((IAnswer) () -> {
        if (!runningUnderCoverage) {
            // Some of these checks don't work when running under coverage
            assertArrayEquals(proxyRegClsMap.keySet().toArray(new String[] {}), (String[]) EasyMock.getCurrentArguments()[0]);
            Object svc = EasyMock.getCurrentArguments()[1];
            assertTrue(svc instanceof ServiceFactory);
        }
        Dictionary<String, Object> props = (Dictionary<String, Object>) EasyMock.getCurrentArguments()[2];
        for (String key : expectedProxyProps.keySet()) {
            if (GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY.equals(key)) {
                assertTrue("The roles property should have been overwritten", !Arrays.asList("everyone").equals(props.get(key)));
            } else {
                assertEquals(expectedProxyProps.get(key), props.get(key));
            }
        }
        ServiceRegistration reg = EasyMock.createMock(ServiceRegistration.class);
        ServiceReference sr = mockServiceReference(props);
        EasyMock.expect(reg.getReference()).andReturn(sr).anyTimes();
        reg.unregister();
        EasyMock.expectLastCall().once();
        EasyMock.replay(reg);
        serviceMap.put(sr, EasyMock.getCurrentArguments()[1]);
        return reg;
    }).once();
    EasyMock.expect(providerBC.getService(EasyMock.isA(ServiceReference.class))).andAnswer(() -> serviceMap.get(EasyMock.getCurrentArguments()[0])).anyTimes();
    EasyMock.replay(providerBC);
    // In some cases the proxy-creating code is looking for a classloader (e.g. when run through
    // a coverage tool such as EclEmma). This will satisfy that.
    BundleWiring bw = EasyMock.createMock(BundleWiring.class);
    EasyMock.expect(bw.getClassLoader()).andReturn(getClass().getClassLoader()).anyTimes();
    EasyMock.replay(bw);
    // The mock bundle that provides the original service (and also the proxy is registered with this)
    Bundle providerBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(providerBundle.getBundleContext()).andReturn(providerBC).anyTimes();
    EasyMock.expect(providerBundle.adapt(BundleWiring.class)).andReturn(bw).anyTimes();
    EasyMock.replay(providerBundle);
    ServiceReference sr = mockServiceReference(providerBundle, serviceProps);
    // The mock bundle context for the client bundle
    BundleContext clientBC = EasyMock.createMock(BundleContext.class);
    EasyMock.expect(clientBC.getService(sr)).andReturn(testService).anyTimes();
    EasyMock.replay(clientBC);
    // The mock bundle that consumes the service
    Bundle clientBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(clientBundle.getBundleId()).andReturn(2999L).anyTimes();
    EasyMock.expect(clientBundle.getBundleContext()).andReturn(clientBC).anyTimes();
    EasyMock.expect(clientBundle.loadClass(EasyMock.isA(String.class))).andAnswer((IAnswer) () -> objClsMap.get(EasyMock.getCurrentArguments()[0])).anyTimes();
    EasyMock.replay(clientBundle);
    assertEquals("Precondition", 0, gpc.proxyMap.size());
    assertEquals("Precondition", 0, gpc.createProxyQueue.size());
    // Create the proxy for the service
    gpc.proxyIfNotAlreadyProxied(sr);
    assertEquals(1, gpc.proxyMap.size());
    // The actual proxy creation is done asynchronously.
    GuardProxyCatalog.ServiceRegistrationHolder holder = gpc.proxyMap.get(serviceID);
    assertNull("The registration shouldn't have happened yet", holder.registration);
    assertEquals(1, gpc.createProxyQueue.size());
    // Mimic the thread that works the queue to create the proxy
    GuardProxyCatalog.CreateProxyRunnable runnable = gpc.createProxyQueue.take();
    ProxyManager pm = getProxyManager();
    runnable.run(pm);
    // The runnable should have put the actual registration in the holder
    ServiceReference<?> proxySR = holder.registration.getReference();
    for (String key : expectedProxyProps.keySet()) {
        if (GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY.equals(key)) {
            assertTrue("The roles property should have been overwritten", !Arrays.asList("everyone").equals(proxySR.getProperty(key)));
        } else {
            assertEquals(expectedProxyProps.get(key), proxySR.getProperty(key));
        }
    }
    // Check that the proxy registration was done on the original provider bundle's context
    EasyMock.verify(providerBC);
    // Test that the actual proxy invokes the original service...
    ServiceFactory proxyServiceSF = (ServiceFactory) serviceMap.get(proxySR);
    Object proxyService = proxyServiceSF.getService(clientBundle, null);
    assertNotSame("The proxy should not be the same object as the original service", testService, proxyService);
    return proxyService;
}
Also used : Dictionary(java.util.Dictionary) ServiceFactory(org.osgi.framework.ServiceFactory) CreateProxyRunnable(org.apache.karaf.service.guard.impl.GuardProxyCatalog.CreateProxyRunnable) Hashtable(java.util.Hashtable) Bundle(org.osgi.framework.Bundle) ServiceRegistrationHolder(org.apache.karaf.service.guard.impl.GuardProxyCatalog.ServiceRegistrationHolder) BundleWiring(org.osgi.framework.wiring.BundleWiring) ProxyManager(org.apache.aries.proxy.ProxyManager) AsmProxyManager(org.apache.aries.proxy.impl.AsmProxyManager) LinkedHashMap(java.util.LinkedHashMap) ServiceReference(org.osgi.framework.ServiceReference) IAnswer(org.easymock.IAnswer) BundleContext(org.osgi.framework.BundleContext) ServiceRegistration(org.osgi.framework.ServiceRegistration)

Example 93 with BundleWiring

use of org.osgi.framework.wiring.BundleWiring in project fabric8 by jboss-fuse.

the class Deployer method computeBundlesToRefresh.

private void computeBundlesToRefresh(Map<Bundle, String> toRefresh, Collection<Bundle> bundles, Map<Resource, Bundle> resources, Map<Resource, List<Wire>> resolution) {
    // Compute the new list of fragments
    Map<Bundle, Set<Resource>> newFragments = new HashMap<>();
    for (Bundle bundle : bundles) {
        newFragments.put(bundle, new HashSet<Resource>());
    }
    if (resolution != null) {
        for (Resource res : resolution.keySet()) {
            for (Wire wire : resolution.get(res)) {
                if (HOST_NAMESPACE.equals(wire.getCapability().getNamespace())) {
                    Bundle bundle = resources.get(wire.getProvider());
                    if (bundle != null) {
                        Bundle b = resources.get(wire.getRequirer());
                        Resource r = b != null ? b.adapt(BundleRevision.class) : wire.getRequirer();
                        newFragments.get(bundle).add(r);
                    }
                }
            }
        }
    }
    // Main loop
    int size;
    Map<Bundle, Resource> bndToRes = new HashMap<>();
    for (Map.Entry<Resource, Bundle> entry : resources.entrySet()) {
        bndToRes.put(entry.getValue(), entry.getKey());
    }
    do {
        size = toRefresh.size();
        main: for (Bundle bundle : bundles) {
            Resource resource = bndToRes.get(bundle);
            // This bundle is not managed
            if (resource == null) {
                continue;
            }
            // Continue if we already know about this bundle
            if (toRefresh.containsKey(bundle)) {
                continue;
            }
            // Ignore non resolved bundle
            BundleWiring wiring = bundle.adapt(BundleWiring.class);
            if (wiring == null) {
                continue;
            }
            // Ignore bundles that won't be wired
            List<Wire> newWires = resolution.get(resource);
            if (newWires == null) {
                continue;
            }
            // Check if this bundle is a host and its fragments changed
            Set<Resource> oldFragments = new HashSet<>();
            for (BundleWire wire : wiring.getProvidedWires(null)) {
                if (HOST_NAMESPACE.equals(wire.getCapability().getNamespace())) {
                    oldFragments.add(wire.getRequirer());
                }
            }
            if (!oldFragments.equals(newFragments.get(bundle))) {
                toRefresh.put(bundle, "Attached fragments changed: " + new ArrayList<>(newFragments.get(bundle)));
                break;
            }
            // Compare the old and new resolutions
            Set<Resource> wiredBundles = new HashSet<>();
            for (BundleWire wire : wiring.getRequiredWires(null)) {
                BundleRevision rev = wire.getProvider();
                Bundle provider = rev.getBundle();
                if (toRefresh.containsKey(provider)) {
                    // The bundle is wired to a bundle being refreshed,
                    // so we need to refresh it too
                    toRefresh.put(bundle, "Wired to " + provider.getSymbolicName() + "/" + provider.getVersion() + " which is being refreshed");
                    continue main;
                }
                Resource res = bndToRes.get(provider);
                wiredBundles.add(res != null ? res : rev);
            }
            Map<Resource, Requirement> wiredResources = new HashMap<>();
            for (Wire wire : newWires) {
                // Handle only packages, hosts, and required bundles
                String namespace = wire.getRequirement().getNamespace();
                if (!namespace.equals(BundleNamespace.BUNDLE_NAMESPACE) && !namespace.equals(PackageNamespace.PACKAGE_NAMESPACE) && !namespace.equals(HostNamespace.HOST_NAMESPACE)) {
                    continue;
                }
                // Ignore non-resolution time requirements
                String effective = wire.getRequirement().getDirectives().get(Namespace.CAPABILITY_EFFECTIVE_DIRECTIVE);
                if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) {
                    continue;
                }
                // Ignore non bundle resources
                if (!isBundle(wire.getProvider())) {
                    continue;
                }
                if (!wiredResources.containsKey(wire.getProvider())) {
                    wiredResources.put(wire.getProvider(), wire.getRequirement());
                }
            }
            if (!wiredBundles.containsAll(wiredResources.keySet())) {
                Map<Resource, Requirement> newResources = new HashMap<>(wiredResources);
                newResources.keySet().removeAll(wiredBundles);
                StringBuilder sb = new StringBuilder();
                sb.append("Should be wired to: ");
                boolean first = true;
                for (Map.Entry<Resource, Requirement> entry : newResources.entrySet()) {
                    if (!first) {
                        sb.append(", ");
                    } else {
                        first = false;
                    }
                    Resource res = entry.getKey();
                    Requirement req = entry.getValue();
                    sb.append(getSymbolicName(res)).append("/").append(getVersion(res));
                    sb.append(" (through ");
                    sb.append(req);
                    sb.append(")");
                }
                toRefresh.put(bundle, sb.toString());
            }
        }
    } while (toRefresh.size() > size);
}
Also used : MapUtils.addToMapSet(io.fabric8.agent.internal.MapUtils.addToMapSet) MapUtils.removeFromMapSet(io.fabric8.agent.internal.MapUtils.removeFromMapSet) Bundle(org.osgi.framework.Bundle) BundleWiring(org.osgi.framework.wiring.BundleWiring) Resource(org.osgi.resource.Resource) FeatureResource(io.fabric8.agent.resolver.FeatureResource) Wire(org.osgi.resource.Wire) BundleWire(org.osgi.framework.wiring.BundleWire) BundleWire(org.osgi.framework.wiring.BundleWire) Requirement(org.osgi.resource.Requirement) ZipEntry(java.util.zip.ZipEntry) BundleRevision(org.osgi.framework.wiring.BundleRevision)

Example 94 with BundleWiring

use of org.osgi.framework.wiring.BundleWiring in project fabric8 by jboss-fuse.

the class OsgiUtils method ensureAllClassesLoaded.

public static void ensureAllClassesLoaded(Bundle bundle) throws ClassNotFoundException {
    BundleWiring wiring = bundle.adapt(BundleWiring.class);
    if (wiring != null) {
        for (String path : wiring.listResources("/", "*.class", BundleWiring.LISTRESOURCES_RECURSE)) {
            String className = path.substring(0, path.length() - ".class".length());
            className = className.replace('/', '.');
            bundle.loadClass(className);
        }
    }
}
Also used : BundleWiring(org.osgi.framework.wiring.BundleWiring)

Example 95 with BundleWiring

use of org.osgi.framework.wiring.BundleWiring in project motech by motech.

the class MdsBundleHelper method unregisterBundleJDOClasses.

/**
 * Unregisters all entity classes registered to JDO that are accessible from bundle class loader. This method
 * should be called after bundle that registers MDS entities gets unresolved, so that they are removed from
 * JDO cache. Not doing this might produce hard to track exception when refreshing MDS Entities Bundle after
 * bundle removal.
 *
 * @param bundle the bundle for which entity classes are to be unregistered
 */
public static void unregisterBundleJDOClasses(Bundle bundle) {
    BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
    if (null == bundleWiring) {
        LOGGER.warn("Cannot unregister JDO entity classes: bundle wiring for {} bundle is unavailable.", bundle.getSymbolicName());
    } else {
        ClassLoader bundleClassLoader = bundleWiring.getClassLoader();
        getJDOImplHelper().unregisterClasses(bundleClassLoader);
        LOGGER.info("Unregistered JDO entity classes for bundle {}.", bundle.getSymbolicName());
    }
}
Also used : BundleWiring(org.osgi.framework.wiring.BundleWiring)

Aggregations

BundleWiring (org.osgi.framework.wiring.BundleWiring)110 Bundle (org.osgi.framework.Bundle)61 BundleWire (org.osgi.framework.wiring.BundleWire)39 ArrayList (java.util.ArrayList)23 BundleRevision (org.osgi.framework.wiring.BundleRevision)23 BundleCapability (org.osgi.framework.wiring.BundleCapability)19 Test (org.junit.Test)15 HashMap (java.util.HashMap)13 Hashtable (java.util.Hashtable)12 List (java.util.List)12 BundleContext (org.osgi.framework.BundleContext)12 URL (java.net.URL)10 Dictionary (java.util.Dictionary)10 HashSet (java.util.HashSet)9 LinkedHashMap (java.util.LinkedHashMap)8 Version (org.osgi.framework.Version)7 BundleRevisions (org.osgi.framework.wiring.BundleRevisions)7 AbstractIntegrationTest (org.apache.aries.jmx.AbstractIntegrationTest)6 IAnswer (org.easymock.IAnswer)6 ServiceReference (org.osgi.framework.ServiceReference)6