package org.infinispan.osgi; import java.io.InputStream; import java.net.URL; import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Map; import java.util.Set; import org.infinispan.commons.util.FileLookupFactory; import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedServiceFactory; public class InfinispanEmbeddedServiceFactory implements ManagedServiceFactory { /** * Configuration property used to indicate the cache configuration to use. */ private static final String PROP_CONFIG = "config"; /** * Configuration property used to identify the service created (e.g. for service filters). */ private static final String PROP_INSTANCE_ID = "instanceId"; private BundleContext bundleContext; private Map<String, DefaultCacheManager> cacheManagers = new HashMap<String, DefaultCacheManager>(); private Map<String, ServiceRegistration<EmbeddedCacheManager>> managedRegistrations = new HashMap<String, ServiceRegistration<EmbeddedCacheManager>>(); @Override public String getName() { return "Infinispan Embedded Managed Service Factory"; } @Override public synchronized void updated(String pid, @SuppressWarnings("rawtypes") Dictionary properties) throws ConfigurationException { String config = (String) properties.get(PROP_CONFIG); if (config == null) { throw new ConfigurationException(PROP_CONFIG, "Property must be set"); } String instanceId = (String) properties.get(PROP_INSTANCE_ID); if (instanceId == null) { throw new ConfigurationException(PROP_INSTANCE_ID, "Property must be set"); } try { URL configURL = FileLookupFactory.newInstance().lookupFileLocation(config, Thread.currentThread().getContextClassLoader()); if (configURL == null) { throw new ConfigurationException(PROP_CONFIG, String.format("Failed to find the specified config '%s'.", config)); } /* Unregister and destroy the old object. */ deleted(pid); InputStream configStream = configURL.openStream(); DefaultCacheManager cacheManager = new DefaultCacheManager(configStream); cacheManager.start(); Hashtable<String, String> ht = new Hashtable<String, String>(); ht.put(PROP_INSTANCE_ID, instanceId); ht.put(PROP_CONFIG, config); ServiceRegistration<EmbeddedCacheManager> serviceRegistration = bundleContext.registerService(EmbeddedCacheManager.class, cacheManager, ht); managedRegistrations.put(pid, serviceRegistration); cacheManagers.put(pid, cacheManager); } catch (Exception e) { throw new ConfigurationException(null, "Cannot start the CacheManager", e); } } @Override public synchronized void deleted(String pid) { ServiceRegistration<EmbeddedCacheManager> serviceRegistration = managedRegistrations.remove(pid); if (serviceRegistration != null) { try { serviceRegistration.unregister(); } catch (Exception e) { } } DefaultCacheManager cacheManager = cacheManagers.remove(pid); if (cacheManager != null) { try { cacheManager.stop(); } catch (Exception e) { } } } public synchronized void destroy() { /* Create a copy of the keyset before iterating over it to avoid ConcurrentModificationExceptions. */ Set<String> keys = new HashSet<String>(cacheManagers.keySet()); for (String cacheManager: keys) { deleted(cacheManager); } } public BundleContext getBundleContext() { return bundleContext; } public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } }