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