public void pull()

in bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java [118:220]


    public void pull(Group group) {
        if (group != null) {
            String groupName = group.getName();
            LOGGER.debug("CELLAR BUNDLE: pulling bundles from cluster group {}", groupName);
            Map<String, BundleState> clusterBundles = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);

            ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();

            try {
                // get the bundles on the cluster to update local bundles
                Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

                List<String> bundleToStart = new ArrayList<String>();
                for (Map.Entry<String, BundleState> entry : clusterBundles.entrySet()) {
                    String id = entry.getKey();
                    BundleState state = entry.getValue();

                    String[] tokens = id.split("/");
                    if (tokens.length == 2) {
                        String symbolicName = tokens[0];
                        String version = tokens[1];
                        if (state != null) {
                            String bundleLocation = state.getLocation();
                            if (isAllowed(group, Constants.CATEGORY, bundleLocation, EventType.INBOUND)) {
                                try {
                                    if (state.getStatus() == Bundle.INSTALLED) {
                                        if (!isInstalled(state.getLocation())) {
                                            LOGGER.debug("CELLAR BUNDLE: installing bundle located {} on node", state.getLocation());
                                            installBundleFromLocation(state.getLocation(), state.getStartLevel());
                                        } else {
                                            LOGGER.debug("CELLAR BUNDLE: bundle located {} already installed on node", state.getLocation());
                                        }
                                    } else if (state.getStatus() == Bundle.ACTIVE) {
                                        if (!isInstalled(state.getLocation())) {
                                            LOGGER.debug("CELLAR BUNDLE: installing bundle located {} on node", state.getLocation());
                                            installBundleFromLocation(state.getLocation(), state.getStartLevel());
                                        }
                                        if (!isStarted(state.getLocation())) {
                                            // Store the id in a list so we can install all bundles before trying to start them,
                                            // this way if a bundle depend on another one that is not install yet but is part of the same update, the start won't fail.
                                            bundleToStart.add(id);
                                        } else {
                                            LOGGER.debug("CELLAR BUNDLE: bundle located {} already started on node", state.getLocation());
                                        }
                                    } else if (state.getStatus() == Bundle.RESOLVED) {
                                        if (!isInstalled(state.getLocation())) {
                                            LOGGER.debug("CELLAR BUNDLE: installing bundle located {} on node", state.getLocation());
                                            installBundleFromLocation(state.getLocation(), state.getStartLevel());
                                        }
                                        Bundle b = findBundle(state.getLocation());
                                        if (b != null) {
                                            if (b.getState() == Bundle.ACTIVE) {
                                                LOGGER.debug("CELLAR BUNDLE: stopping bundle {}/{} on node", symbolicName, version);
                                                stopBundle(symbolicName, version);
                                            } else if (b.getState() == Bundle.INSTALLED) {
                                                LOGGER.debug("CELLAR BUNDLE: resolving bundle {}/{} on node", symbolicName, version);
                                                getBundleContext().getBundle(0).adapt(FrameworkWiring.class).resolveBundles(Collections.singleton(b));
                                            }
                                        } else {
                                            LOGGER.warn("CELLAR BUNDLE: unable to find bundle located {} on node", state.getLocation());
                                        }
                                    }
                                } catch (BundleException e) {
                                    resolveBundleException(id, e);
                                }
                            } else LOGGER.trace("CELLAR BUNDLE: bundle {} is marked BLOCKED INBOUND for cluster group {}", bundleLocation, groupName);
                        }
                    }
                }

                for (String id : bundleToStart) {
                    String[] tokens = id.split("/");
                    String symbolicName = tokens[0];
                    String version = tokens[1];

                    try {
                        LOGGER.debug("CELLAR BUNDLE: starting bundle {}/{} on node", symbolicName, version);
                        startBundle(symbolicName, version);
                    } catch (BundleException e) {
                        resolveBundleException(id, e);
                    }
                }

                // cleanup the local bundles not present on the cluster if the node is not the first one in the cluster group
                if (CellarUtils.doCleanupResourcesNotPresentInCluster(configurationAdmin) && getSynchronizerMap().containsKey(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName)) {
                    for (Bundle bundle : bundleContext.getBundles()) {
                        String id = getId(bundle);
                        if (!clusterBundles.containsKey(id) && isAllowed(group, Constants.CATEGORY, bundle.getLocation(), EventType.INBOUND)) {
                            // the bundle is not present on the cluster, so it has to be uninstalled locally
                            try {
                                LOGGER.debug("CELLAR BUNDLE: uninstalling local bundle {} which is not present in cluster", id);
                                bundle.uninstall();
                            } catch (Exception e) {
                                LOGGER.warn("Can't uninstall {}", id, e);
                            }
                        }
                    }
                }
            } finally {
                Thread.currentThread().setContextClassLoader(originalClassLoader);
            }
        }
    }