package org.bundlebee.weaver; import org.bundlebee.registry.Registry; import org.bundlebee.remoteservicecall.BundleLifecycleClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.osgi.framework.Bundle; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * Strategy for finding Manager URIs following a round robin approach. * * @author Hendrik Schreiber */ public class RoundRobinDispatchStrategy implements ServiceCallDispatchStrategy { private static Logger LOG = LoggerFactory.getLogger(RoundRobinDispatchStrategy.class); private Registry registry; private List managerList = new ArrayList(); private int index; private final BundleLifecycleClient bundleLifecycleClient = new BundleLifecycleClient(); public RoundRobinDispatchStrategy() { LOG.info("Initializing RoundRobinDispatchStrategy"); } public void setRegistry(final Registry registry) { this.registry = registry; } public void setServiceCallStats(final ServiceCallStats serviceCallStats) { } public synchronized URI getManagerURI(final String bundleSymbolicNameVersion, final Object service, final String methodname, final Class[] parameterTypes) { try { updateManagerList(); if (managerList.isEmpty()) return null; index = index % managerList.size(); final URL url = managerList.get(index); index++; // make sure bundle is installed and started on remote node final URL url2 = installAndStartBundle(bundleSymbolicNameVersion, url); // found an active one if (url2 == null) return null; return url2.toURI(); } catch (URISyntaxException e) { LOG.error(e.toString(), e); } return null; } private URL installAndStartBundle(final String bundleSymbolicNameVersion, final URL url) { final List urls = new ArrayList(); urls.add(url); if (registry.getGrid().getManagers(bundleSymbolicNameVersion, Bundle.INSTALLED).contains(url) || registry.getGrid().getManagers(bundleSymbolicNameVersion, Bundle.RESOLVED).contains(url)) { // still have to start it urls.retainAll(bundleLifecycleClient.startBundle(urls, bundleSymbolicNameVersion)); } else if (registry.getGrid().getManagers(bundleSymbolicNameVersion, Bundle.UNINSTALLED).contains(url)) { // still have to install and start it urls.retainAll(bundleLifecycleClient.installAndStartBundle(urls, bundleSymbolicNameVersion)); } else { // still have to deploy, install and start it urls.retainAll(bundleLifecycleClient.installAndStartBundle(urls, bundleSymbolicNameVersion)); } if (urls.isEmpty()) return null; return urls.iterator().next(); } private void updateManagerList() { final Set currentManagerURLs = registry.getGrid().getManagers(); managerList.retainAll(currentManagerURLs); for (final URL url:currentManagerURLs) { if (!managerList.contains(url)) managerList.add(url); } } }