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));
}
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;
}
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);
}
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);
}
}
}
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());
}
}
Aggregations