public void pull()

in features/src/main/java/org/apache/karaf/cellar/features/FeaturesSynchronizer.java [116:209]


    public void pull(Group group) {
        if (group != null) {
            String groupName = group.getName();
            LOGGER.debug("CELLAR FEATURE: pulling features repositories and features from cluster group {}", groupName);
            ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
            try {
                Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

                Map<String, String> clusterRepositories = clusterManager.getMap(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + groupName);
                Map<String, FeatureState> clusterFeatures = clusterManager.getMap(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName);
                Map<String, Boolean> synchronizers = getSynchronizerMap();

                if (clusterRepositories != null && !clusterRepositories.isEmpty()) {
                    // get the features repositories from the cluster to update locally
                    for (String url : clusterRepositories.keySet()) {
                        try {
                            if (!isRepositoryRegisteredLocally(url)) {
                                LOGGER.debug("CELLAR FEATURE: adding repository {}", url);
                                featuresService.addRepository(new URI(url));
                            }
                        } catch (MalformedURLException e) {
                            LOGGER.error("CELLAR FEATURE: failed to add repository URL {} (malformed)", url, e);
                        } catch (Exception e) {
                            LOGGER.error("CELLAR FEATURE: failed to add repository URL {}", url, e);
                        }
                    }
                    // cleanup the local features repositories not present on the cluster if the node is not the first one in the cluster group

                    if (synchronizers.containsKey(Constants.REPOSITORIES_MAP + Configurations.SEPARATOR + groupName)) {
                        try {
                            for (Repository repository : featuresService.listRepositories()) {
                                URI uri = repository.getURI();
                                boolean found = false;
                                for (String clusterRepository : clusterRepositories.keySet()) {
                                    if (clusterRepository.equals(uri.toString())) {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found) {
                                    LOGGER.debug("CELLAR FEATURE: removing repository {}", uri);
                                    featuresService.removeRepository(uri);
                                }
                            }
                        } catch (Exception e) {
                            LOGGER.warn("Can't get local features repositories", e);
                        }
                    }
                }

                if (clusterFeatures != null && !clusterFeatures.isEmpty()) {
                    boolean doUninstallFeaturesNotPresentInCluster = CellarUtils.doCleanupResourcesNotPresentInCluster(configurationAdmin) && synchronizers.containsKey(Constants.FEATURES_MAP + Configurations.SEPARATOR + groupName);
                    // get the features from the cluster group and update locally
                    for (FeatureState state : clusterFeatures.values()) {
                        String name = state.getName();
                        // check if feature is blocked
                        if (isAllowed(group, Constants.CATEGORY, name, EventType.INBOUND)) {
                            Boolean clusterInstalled = state.getInstalled();
                            Boolean locallyInstalled = isFeatureInstalledLocally(state.getName(), state.getVersion());

                            // prevent NPE
                            if (clusterInstalled == null) {
                                clusterInstalled = false;
                            }
                            if (locallyInstalled == null) {
                                locallyInstalled = false;
                            }

                            // if feature has to be installed locally
                            if (clusterInstalled && !locallyInstalled) {
                                try {
                                    LOGGER.debug("CELLAR FEATURE: installing feature {}/{}", state.getName(), state.getVersion());
                                    featuresService.installFeature(state.getName(), state.getVersion());
                                } catch (Exception e) {
                                    LOGGER.error("CELLAR FEATURE: failed to install feature {}/{} ", new Object[]{state.getName(), state.getVersion()}, e);
                                }
                            }
                            // if feature has to be uninstalled locally (and node is not the first one in the cluster group)
                            if (doUninstallFeaturesNotPresentInCluster && !clusterInstalled && locallyInstalled) {
                                try {
                                    LOGGER.debug("CELLAR FEATURE: uninstalling feature {}/{}", state.getName(), state.getVersion());
                                    featuresService.uninstallFeature(state.getName(), state.getVersion());
                                } catch (Exception e) {
                                    LOGGER.error("CELLAR FEATURE: failed to uninstall feature {}/{}", new Object[]{state.getName(), state.getVersion()}, e);
                                }
                            }
                        } else LOGGER.trace("CELLAR FEATURE: feature {} is marked BLOCKED INBOUND for cluster group {}", name, groupName);
                    }
                }
            } finally {
                Thread.currentThread().setContextClassLoader(originalClassLoader);
            }
        }
    }