use of org.apache.karaf.features.FeatureEvent in project karaf by apache.
the class FeaturesServiceMBeanImpl method getFeaturesListener.
public FeaturesListener getFeaturesListener() {
return new FeaturesListener() {
public void featureEvent(FeatureEvent event) {
if (!event.isReplay()) {
Notification notification = new Notification(FEATURE_EVENT_TYPE, objectName, sequenceNumber++);
notification.setUserData(new JmxFeatureEvent(event).asCompositeData());
sendNotification(notification);
}
}
public void repositoryEvent(RepositoryEvent event) {
if (!event.isReplay()) {
Notification notification = new Notification(REPOSITORY_EVENT_TYPE, objectName, sequenceNumber++);
notification.setUserData(new JmxRepositoryEvent(event).asCompositeData());
sendNotification(notification);
}
}
};
}
use of org.apache.karaf.features.FeatureEvent in project karaf by apache.
the class DeployerTest method testUpdateSimpleFeature.
@Test
public void testUpdateSimpleFeature() throws Exception {
IMocksControl c = EasyMock.createControl();
final String dataDir = "data1";
TestDownloadManager manager = new TestDownloadManager(getClass(), dataDir);
RepositoryImpl repo = new RepositoryImpl(getClass().getResource(dataDir + "/features.xml").toURI());
repo.load(true);
Feature f100 = repo.getFeatures()[0];
Feature f101 = repo.getFeatures()[1];
Deployer.DeployCallback callback = c.createMock(Deployer.DeployCallback.class);
BundleInstallSupport installSupport = c.createMock(BundleInstallSupportImpl.class);
Deployer deployer = new Deployer(manager, resolver, installSupport, callback);
final TestBundle bundleA = createTestBundle(1L, Bundle.ACTIVE, dataDir, "a100");
callback.print(EasyMock.anyString(), EasyMock.anyBoolean());
EasyMock.expectLastCall().anyTimes();
callback.callListeners(DeploymentEvent.DEPLOYMENT_STARTED);
EasyMock.expectLastCall();
installSupport.stopBundle(EasyMock.eq(bundleA), anyInt());
EasyMock.expectLastCall().andStubAnswer(() -> {
bundleA.state = Bundle.RESOLVED;
return null;
});
installSupport.updateBundle(EasyMock.eq(bundleA), EasyMock.anyObject(), EasyMock.anyObject());
EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
URL loc = getClass().getResource(dataDir + "/" + "a101" + ".mf");
Manifest man = new Manifest(loc.openStream());
Hashtable<String, String> headers = new Hashtable<>();
for (Map.Entry<Object, Object> attr : man.getMainAttributes().entrySet()) {
headers.put(attr.getKey().toString(), attr.getValue().toString());
}
bundleA.update(headers);
return null;
}
});
installSupport.startBundle(EasyMock.eq(bundleA));
EasyMock.expectLastCall();
installSupport.replaceDigraph(EasyMock.anyObject(), EasyMock.anyObject());
EasyMock.expectLastCall();
callback.saveState(EasyMock.anyObject());
EasyMock.expectLastCall();
installSupport.installConfigs(f101);
EasyMock.expectLastCall();
installSupport.installLibraries(f101);
EasyMock.expectLastCall();
callback.callListeners(DeploymentEvent.BUNDLES_INSTALLED);
EasyMock.expectLastCall();
installSupport.resolveBundles(EasyMock.eq(Collections.singleton(bundleA)), EasyMock.anyObject(), EasyMock.anyObject());
EasyMock.expectLastCall();
callback.callListeners(DeploymentEvent.BUNDLES_RESOLVED);
EasyMock.expectLastCall();
installSupport.refreshPackages(EasyMock.eq(Collections.singleton(bundleA)));
EasyMock.expectLastCall();
callback.callListeners(FeatureEventMatcher.eq(new FeatureEvent(FeatureEvent.EventType.FeatureUninstalled, f100, FeaturesService.ROOT_REGION, false)));
EasyMock.expectLastCall();
callback.callListeners(FeatureEventMatcher.eq(new FeatureEvent(FeatureEvent.EventType.FeatureInstalled, f101, FeaturesService.ROOT_REGION, false)));
EasyMock.expectLastCall();
callback.callListeners(DeploymentEvent.DEPLOYMENT_FINISHED);
EasyMock.expectLastCall();
c.replay();
Deployer.DeploymentState dstate = new Deployer.DeploymentState();
dstate.state = new State();
addToMapSet(dstate.state.installedFeatures, ROOT_REGION, f100.getId());
addToMapSet(dstate.state.managedBundles, ROOT_REGION, 1L);
dstate.bundles = new HashMap<>();
dstate.bundles.put(1L, bundleA);
dstate.bundlesPerRegion = new HashMap<>();
addToMapSet(dstate.bundlesPerRegion, ROOT_REGION, 1L);
dstate.features = new HashMap<>();
dstate.features.put(f100.getId(), f100);
dstate.features.put(f101.getId(), f101);
dstate.filtersPerRegion = new HashMap<>();
dstate.filtersPerRegion.put(ROOT_REGION, new HashMap<>());
Deployer.DeploymentRequest request = new Deployer.DeploymentRequest();
request.bundleUpdateRange = DEFAULT_BUNDLE_UPDATE_RANGE;
request.featureResolutionRange = DEFAULT_FEATURE_RESOLUTION_RANGE;
request.globalRepository = null;
request.options = EnumSet.noneOf(Option.class);
request.overrides = Collections.emptySet();
request.stateChanges = Collections.emptyMap();
request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
request.requirements = new HashMap<>();
addToMapSet(request.requirements, ROOT_REGION, f101.getName() + "/" + new VersionRange(f101.getVersion(), true));
deployer.deploy(dstate, request);
c.verify();
}
use of org.apache.karaf.features.FeatureEvent in project karaf by apache.
the class Deployer method deploy.
/**
* Perform a deployment.
*
* @param dstate deployment state
* @param request deployment request
* @throws Exception in case of deployment failure.
*/
public void deploy(DeploymentState dstate, DeploymentRequest request) throws Exception {
boolean noRefreshUnmanaged = request.options.contains(FeaturesService.Option.NoAutoRefreshUnmanagedBundles);
boolean noRefreshManaged = request.options.contains(FeaturesService.Option.NoAutoRefreshManagedBundles);
boolean noRefresh = request.options.contains(FeaturesService.Option.NoAutoRefreshBundles);
boolean noStart = request.options.contains(FeaturesService.Option.NoAutoStartBundles);
boolean verbose = request.options.contains(FeaturesService.Option.Verbose);
boolean simulate = request.options.contains(FeaturesService.Option.Simulate);
boolean noManageBundles = request.options.contains(FeaturesService.Option.NoAutoManageBundles);
boolean showWiring = request.options.contains(FeaturesService.Option.DisplayFeaturesWiring) || request.options.contains(FeaturesService.Option.DisplayAllWiring);
boolean showFeaturesWiringOnly = request.options.contains(FeaturesService.Option.DisplayFeaturesWiring) && !request.options.contains(FeaturesService.Option.DisplayAllWiring);
// TODO: add an option to unmanage bundles instead of uninstalling those
Map<String, Set<Long>> managedBundles = copy(dstate.state.managedBundles);
Map<String, Set<Bundle>> unmanagedBundles = apply(diff(dstate.bundlesPerRegion, dstate.state.managedBundles), map(dstate.bundles));
// Resolve
SubsystemResolver resolver = new SubsystemResolver(this.resolver, manager);
resolver.prepare(dstate.features.values(), request.requirements, apply(unmanagedBundles, adapt(BundleRevision.class)));
Set<String> prereqs = resolver.collectPrerequisites();
if (!prereqs.isEmpty()) {
for (Iterator<String> iterator = prereqs.iterator(); iterator.hasNext(); ) {
String prereq = iterator.next();
String[] parts = prereq.split("/");
String name = parts[0];
String version = parts[1];
VersionRange range = getRange(version, request.featureResolutionRange);
boolean found = false;
for (Set<String> featureSet : dstate.state.installedFeatures.values()) {
for (String feature : featureSet) {
String[] p = feature.split("/");
found = name.equals(p[0]) && range.contains(VersionTable.getVersion(p[1]));
if (found) {
break;
}
}
if (found) {
break;
}
}
if (found) {
iterator.remove();
}
}
}
if (!prereqs.isEmpty()) {
if (request.requirements.get(ROOT_REGION).containsAll(prereqs)) {
throw new CircularPrerequisiteException(prereqs);
}
DeploymentRequest newRequest = new DeploymentRequest();
newRequest.bundleUpdateRange = request.bundleUpdateRange;
newRequest.featureResolutionRange = request.featureResolutionRange;
newRequest.serviceRequirements = request.serviceRequirements;
newRequest.globalRepository = request.globalRepository;
newRequest.options = request.options;
newRequest.overrides = request.overrides;
newRequest.requirements = copy(dstate.state.requirements);
for (String prereq : prereqs) {
addToMapSet(newRequest.requirements, ROOT_REGION, prereq);
}
newRequest.stateChanges = Collections.emptyMap();
newRequest.updateSnaphots = request.updateSnaphots;
deploy(dstate, newRequest);
throw new PartialDeploymentException(prereqs);
}
resolver.resolve(request.overrides, request.featureResolutionRange, request.serviceRequirements, request.globalRepository, request.outputFile);
Map<String, StreamProvider> providers = resolver.getProviders();
Map<String, Set<Resource>> featuresPerRegion = resolver.getFeaturesPerRegions();
Map<String, Set<String>> installedFeatures = apply(featuresPerRegion, featureId());
Map<String, Set<String>> newFeatures = diff(installedFeatures, dstate.state.installedFeatures);
Map<String, Set<String>> delFeatures = diff(dstate.state.installedFeatures, installedFeatures);
//
// Compute requested features state
//
Map<String, Map<String, String>> stateFeatures = copy(dstate.state.stateFeatures);
for (Map.Entry<String, Set<String>> entry : delFeatures.entrySet()) {
Map<String, String> map = stateFeatures.get(entry.getKey());
if (map != null) {
map.keySet().removeAll(entry.getValue());
if (map.isEmpty()) {
stateFeatures.remove(entry.getKey());
}
}
}
for (Map.Entry<String, Map<String, FeatureState>> entry1 : request.stateChanges.entrySet()) {
String region = entry1.getKey();
Map<String, String> regionStates = stateFeatures.get(region);
if (regionStates != null) {
for (Map.Entry<String, FeatureState> entry2 : entry1.getValue().entrySet()) {
String feature = entry2.getKey();
if (regionStates.containsKey(feature)) {
regionStates.put(feature, entry2.getValue().name());
}
}
}
}
for (Map.Entry<String, Set<String>> entry : newFeatures.entrySet()) {
for (String feature : entry.getValue()) {
Map<String, String> map = stateFeatures.computeIfAbsent(entry.getKey(), k -> new HashMap<>());
map.put(feature, noStart ? FeatureState.Installed.name() : FeatureState.Started.name());
}
}
// Compute information for each bundle
Map<String, Map<String, BundleInfo>> bundleInfos = resolver.getBundleInfos();
//
// Compute deployment
//
Deployer.Deployment deployment = computeDeployment(dstate, request, resolver);
//
// Compute the set of bundles to refresh
//
// sort is only used for display
Map<Bundle, String> toRefresh = new TreeMap<>(new BundleComparator());
for (Deployer.RegionDeployment regionDeployment : deployment.regions.values()) {
for (Bundle b : regionDeployment.toDelete) {
toRefresh.put(b, "Bundle will be uninstalled");
}
for (Bundle b : regionDeployment.toUpdate.keySet()) {
toRefresh.put(b, "Bundle will be updated");
}
}
if (!noRefreshManaged) {
computeBundlesToRefresh(toRefresh, dstate.bundles.values(), deployment.resToBnd, resolver.getWiring());
}
if (noRefreshUnmanaged) {
toRefresh.keySet().removeAll(flatten(unmanagedBundles));
}
// Automatically turn unmanaged bundles into managed bundles
// if they are required by a feature and no other unmanaged
// bundles have a requirement on it
// sort is only used for display
Set<Bundle> toManage = new TreeSet<>(new BundleComparator());
if (!noManageBundles) {
Set<Resource> features = resolver.getFeatures().keySet();
Set<? extends Resource> unmanaged = apply(flatten(unmanagedBundles), adapt(BundleRevision.class));
Set<Resource> requested = new HashSet<>();
// Gather bundles required by a feature
if (resolver != null && resolver.getWiring() != null) {
for (List<Wire> wires : resolver.getWiring().values()) {
for (Wire wire : wires) {
if (features.contains(wire.getRequirer()) && unmanaged.contains(wire.getProvider())) {
requested.add(wire.getProvider());
}
}
}
}
// Now, we know which bundles are completely unmanaged
unmanaged.removeAll(requested);
// Check if bundles have wires from really unmanaged bundles
if (resolver != null && resolver.getWiring() != null) {
for (List<Wire> wires : resolver.getWiring().values()) {
for (Wire wire : wires) {
if (requested.contains(wire.getProvider()) && unmanaged.contains(wire.getRequirer())) {
requested.remove(wire.getProvider());
}
}
}
}
if (!requested.isEmpty()) {
Map<Long, String> bundleToRegion = new HashMap<>();
for (Map.Entry<String, Set<Long>> entry : dstate.bundlesPerRegion.entrySet()) {
for (long id : entry.getValue()) {
bundleToRegion.put(id, entry.getKey());
}
}
for (Resource rev : requested) {
Bundle bundle = ((BundleRevision) rev).getBundle();
long id = bundle.getBundleId();
addToMapSet(managedBundles, bundleToRegion.get(id), id);
toManage.add(bundle);
}
}
}
Set<Bundle> toStart = new HashSet<>();
Set<Bundle> toResolve = new HashSet<>();
Set<Bundle> toStop = new HashSet<>();
//
// Compute bundle states
//
Map<Resource, FeatureState> states = new HashMap<>();
// Find all features state
Map<Resource, FeatureState> featuresState = new HashMap<>();
Map<Resource, Set<Resource>> conditionals = new HashMap<>();
for (Map.Entry<String, Set<Resource>> entry : resolver.getFeaturesPerRegions().entrySet()) {
String region = entry.getKey();
Map<String, String> fss = stateFeatures.get(region);
for (Resource feature : entry.getValue()) {
Set<Resource> conditions = new HashSet<>();
for (Wire wire : resolver.getWiring().get(feature)) {
if (IDENTITY_NAMESPACE.equals(wire.getRequirement().getNamespace()) && FeatureResource.CONDITIONAL_TRUE.equals(wire.getRequirement().getDirectives().get(FeatureResource.REQUIREMENT_CONDITIONAL_DIRECTIVE))) {
conditions.add(wire.getProvider());
}
}
if (conditions.isEmpty()) {
String fs = fss.get(getFeatureId(feature));
featuresState.put(feature, FeatureState.valueOf(fs));
} else {
conditionals.put(feature, conditions);
}
}
}
// Compute conditional features state
for (Resource feature : conditionals.keySet()) {
FeatureState state = null;
for (Resource cond : conditionals.get(feature)) {
FeatureState s = featuresState.get(cond);
if (state == null) {
state = s;
} else if (state == FeatureState.Started && s == FeatureState.Resolved) {
state = FeatureState.Resolved;
}
}
featuresState.put(feature, state);
}
// Propagate Resolved state
for (Resource feature : featuresState.keySet()) {
if (featuresState.get(feature) == FeatureState.Resolved) {
propagateState(states, feature, FeatureState.Resolved, resolver);
}
}
// Propagate Started state
for (Resource feature : featuresState.keySet()) {
if (featuresState.get(feature) == FeatureState.Started) {
propagateState(states, feature, FeatureState.Started, resolver);
}
}
// Put default Started state for other bundles if start attribute is true
for (Resource resource : resolver.getBundles().keySet()) {
BundleInfo bundleInfo = null;
for (Map.Entry<String, Map<String, BundleInfo>> bis : resolver.getBundleInfos().entrySet()) {
bundleInfo = bis.getValue().get(getUri(resource));
}
Bundle bundle = deployment.resToBnd.get(resource);
if (bundle == null) {
// we are using bundleInfo and start flag
if (bundleInfo != null && bundleInfo.isStart()) {
states.put(resource, FeatureState.Started);
} else {
states.put(resource, FeatureState.Resolved);
}
} else {
// if the bundle is already there, just ignore changing state by feature
states.remove(resource);
}
}
// Only keep bundles resources
states.keySet().retainAll(resolver.getBundles().keySet());
//
for (Map.Entry<Resource, FeatureState> entry : states.entrySet()) {
Bundle bundle = deployment.resToBnd.get(entry.getKey());
if (bundle != null) {
switch(entry.getValue()) {
case Started:
toResolve.add(bundle);
toStart.add(bundle);
break;
case Resolved:
toResolve.add(bundle);
toStop.add(bundle);
break;
}
}
}
//
// Compute bundle all start levels and start levels to update
//
Map<Resource, Integer> startLevels = new HashMap<>();
Map<Bundle, Integer> toUpdateStartLevel = new HashMap<>();
for (Map.Entry<String, Set<Resource>> entry : resolver.getBundlesPerRegions().entrySet()) {
String region = entry.getKey();
for (Resource resource : entry.getValue()) {
BundleInfo bi = bundleInfos.get(region).get(getUri(resource));
if (bi != null) {
int sl = bi.getStartLevel() > 0 ? bi.getStartLevel() : dstate.initialBundleStartLevel;
startLevels.put(resource, sl);
Bundle bundle = deployment.resToBnd.get(resource);
if (bundle != null) {
int curSl = bundle.adapt(BundleStartLevel.class).getStartLevel();
if (sl != curSl) {
toUpdateStartLevel.put(bundle, sl);
if (sl > dstate.currentStartLevel) {
toStop.add(bundle);
}
}
}
}
}
}
//
if (showWiring) {
logWiring(resolver.getWiring(), showFeaturesWiringOnly);
}
//
// Log deployment
//
logDeployment(deployment, verbose);
if (simulate) {
if (!noRefresh && !toRefresh.isEmpty()) {
print(" Bundles to refresh:", verbose);
for (Map.Entry<Bundle, String> entry : toRefresh.entrySet()) {
Bundle bundle = entry.getKey();
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion() + " (" + entry.getValue() + ")", verbose);
}
}
if (!toManage.isEmpty()) {
print(" Managing bundle:", verbose);
for (Bundle bundle : toManage) {
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion(), verbose);
}
}
return;
}
//
// Execute deployment
//
// #1: stop bundles that needs to be updated or uninstalled in order
// #2: uninstall needed bundles
// #3: update regions
// #4: update bundles
// #5: install bundles
// #6: save state
// #7: install configuration
// #8: refresh bundles
// #9: start bundles in order
// #10: send events
//
Bundle serviceBundle = dstate.serviceBundle;
//
// Handle updates on the FeaturesService bundle
//
Deployer.RegionDeployment rootRegionDeployment = deployment.regions.get(ROOT_REGION);
// We don't support uninstalling the bundle
if (rootRegionDeployment != null && rootRegionDeployment.toDelete.contains(serviceBundle)) {
throw new UnsupportedOperationException("Uninstalling the FeaturesService bundle is not supported");
}
// When restarting, the resolution will be attempted again
if (rootRegionDeployment != null && rootRegionDeployment.toUpdate.containsKey(serviceBundle)) {
callback.persistResolveRequest(request);
// save the new checksum persistently
if (deployment.bundleChecksums.containsKey(serviceBundle.getBundleId())) {
State state = dstate.state.copy();
state.bundleChecksums.put(serviceBundle.getBundleId(), deployment.bundleChecksums.get(serviceBundle.getBundleId()));
callback.saveState(state);
}
Resource resource = rootRegionDeployment.toUpdate.get(serviceBundle);
String uri = getUri(resource);
print("The FeaturesService bundle needs is being updated with " + uri, verbose);
toRefresh.clear();
toRefresh.put(serviceBundle, "FeaturesService bundle is being updated");
computeBundlesToRefresh(toRefresh, dstate.bundles.values(), Collections.emptyMap(), Collections.emptyMap());
installSupport.stopBundle(serviceBundle, STOP_TRANSIENT);
try (InputStream is = getBundleInputStream(resource, providers)) {
installSupport.updateBundle(serviceBundle, uri, is);
}
installSupport.refreshPackages(toRefresh.keySet());
installSupport.startBundle(serviceBundle);
return;
}
callback.callListeners(DeploymentEvent.DEPLOYMENT_STARTED);
//
for (Deployer.RegionDeployment regionDeployment : deployment.regions.values()) {
toStop.addAll(regionDeployment.toUpdate.keySet());
toStop.addAll(regionDeployment.toDelete);
}
removeFragmentsAndBundlesInState(toStop, UNINSTALLED | RESOLVED | STOPPING);
if (!toStop.isEmpty()) {
print("Stopping bundles:", verbose);
while (!toStop.isEmpty()) {
List<Bundle> bs = getBundlesToStop(toStop);
for (Bundle bundle : bs) {
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion(), verbose);
// If the bundle start level will be changed, stop it persistently to
// avoid a restart when the start level is actually changed
installSupport.stopBundle(bundle, toUpdateStartLevel.containsKey(bundle) ? 0 : STOP_TRANSIENT);
toStop.remove(bundle);
}
}
}
//
// Delete bundles
//
boolean hasToDelete = false;
for (Deployer.RegionDeployment regionDeployment : deployment.regions.values()) {
if (hasToDelete = !regionDeployment.toDelete.isEmpty()) {
break;
}
}
if (hasToDelete) {
print("Uninstalling bundles:", verbose);
for (Map.Entry<String, Deployer.RegionDeployment> entry : deployment.regions.entrySet()) {
String name = entry.getKey();
Deployer.RegionDeployment regionDeployment = entry.getValue();
for (Bundle bundle : regionDeployment.toDelete) {
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion(), verbose);
installSupport.uninstall(bundle);
removeFromMapSet(managedBundles, name, bundle.getBundleId());
}
}
}
//
// Update regions
//
{
// Add bundles
Map<String, Set<Long>> bundles = new HashMap<>();
add(bundles, apply(unmanagedBundles, bundleId()));
add(bundles, managedBundles);
// Compute policies
RegionDigraph computedDigraph = resolver.getFlatDigraph();
Map<String, Map<String, Map<String, Set<String>>>> policies = copy(dstate.filtersPerRegion);
// Only keep regions which still have bundles
policies.keySet().retainAll(bundles.keySet());
// Fix broken filters
for (String name : policies.keySet()) {
policies.get(name).keySet().retainAll(policies.keySet());
}
// Update managed regions
for (Region computedRegion : computedDigraph.getRegions()) {
String name = computedRegion.getName();
Map<String, Map<String, Set<String>>> policy = policies.computeIfAbsent(name, k -> new HashMap<>());
for (RegionDigraph.FilteredRegion fr : computedRegion.getEdges()) {
String r2 = fr.getRegion().getName();
Map<String, Set<String>> filters = new HashMap<>();
Map<String, Collection<String>> current = fr.getFilter().getSharingPolicy();
for (String ns : current.keySet()) {
for (String f : current.get(ns)) {
addToMapSet(filters, ns, f);
}
}
policy.put(r2, filters);
}
}
// Apply all changes
installSupport.replaceDigraph(policies, bundles);
}
//
// Update bundles
//
boolean hasToUpdate = false;
for (Deployer.RegionDeployment regionDeployment : deployment.regions.values()) {
if (hasToUpdate = !regionDeployment.toUpdate.isEmpty()) {
break;
}
}
if (hasToUpdate) {
print("Updating bundles:", verbose);
for (Map.Entry<String, Deployer.RegionDeployment> rde : deployment.regions.entrySet()) {
for (Map.Entry<Bundle, Resource> entry : rde.getValue().toUpdate.entrySet()) {
Bundle bundle = entry.getKey();
Resource resource = entry.getValue();
String uri = getUri(resource);
print(" " + uri, verbose);
try (InputStream is = getBundleInputStream(resource, providers)) {
installSupport.updateBundle(bundle, uri, is);
}
toStart.add(bundle);
}
}
}
//
for (Map.Entry<Bundle, Integer> entry : toUpdateStartLevel.entrySet()) {
Bundle bundle = entry.getKey();
int sl = entry.getValue();
bundle.adapt(BundleStartLevel.class).setStartLevel(sl);
}
//
// Install bundles
//
boolean hasToInstall = false;
for (Deployer.RegionDeployment regionDeployment : deployment.regions.values()) {
if (hasToInstall = !regionDeployment.toInstall.isEmpty()) {
break;
}
}
if (hasToInstall) {
print("Installing bundles:", verbose);
Map<Bundle, Integer> customStartLevels = new HashMap<>();
for (Map.Entry<String, Deployer.RegionDeployment> entry : deployment.regions.entrySet()) {
String name = entry.getKey();
Deployer.RegionDeployment regionDeployment = entry.getValue();
for (Resource resource : regionDeployment.toInstall) {
String uri = getUri(resource);
print(" " + uri, verbose);
Bundle bundle;
long crc;
try (ChecksumUtils.CRCInputStream is = new ChecksumUtils.CRCInputStream(getBundleInputStream(resource, providers))) {
bundle = installSupport.installBundle(name, uri, is);
crc = is.getCRC();
}
addToMapSet(managedBundles, name, bundle.getBundleId());
deployment.resToBnd.put(resource, bundle);
// save a checksum of installed snapshot bundle
if (UPDATE_SNAPSHOTS_CRC.equals(request.updateSnaphots) && isUpdateable(resource) && !deployment.bundleChecksums.containsKey(bundle.getBundleId())) {
deployment.bundleChecksums.put(bundle.getBundleId(), crc);
}
Integer startLevel = startLevels.get(resource);
if (startLevel != null && startLevel != dstate.initialBundleStartLevel) {
customStartLevels.put(bundle, startLevel);
}
FeatureState reqState = states.get(resource);
if (reqState == null) {
reqState = FeatureState.Started;
}
switch(reqState) {
case Started:
toResolve.add(bundle);
toStart.add(bundle);
break;
case Resolved:
toResolve.add(bundle);
break;
}
}
}
// Set start levels after install to avoid starting before all bundles are installed
for (Bundle bundle : customStartLevels.keySet()) {
int startLevel = customStartLevels.get(bundle);
bundle.adapt(BundleStartLevel.class).setStartLevel(startLevel);
}
}
//
// Update and save state
//
State newState = new State();
newState.bundleChecksums.putAll(deployment.bundleChecksums);
newState.requirements.putAll(request.requirements);
newState.installedFeatures.putAll(installedFeatures);
newState.stateFeatures.putAll(stateFeatures);
newState.managedBundles.putAll(managedBundles);
callback.saveState(newState);
//
if (!newFeatures.isEmpty()) {
Set<String> featureIds = flatten(newFeatures);
for (Feature feature : dstate.features.values()) {
if (featureIds.contains(feature.getId())) {
installSupport.installConfigs(feature);
installSupport.installLibraries(feature);
}
for (Conditional cond : feature.getConditional()) {
Feature condFeature = cond.asFeature();
if (featureIds.contains(condFeature.getId())) {
installSupport.installConfigs(condFeature);
installSupport.installLibraries(condFeature);
}
}
}
}
if (!noRefresh) {
if (toRefresh.containsKey(dstate.bundles.get(0l))) {
print("The system bundle needs to be refreshed, restarting Karaf...", verbose);
System.setProperty("karaf.restart", "true");
dstate.bundles.get(0l).stop();
return;
}
toStop = new HashSet<>();
toStop.addAll(toRefresh.keySet());
removeFragmentsAndBundlesInState(toStop, UNINSTALLED | RESOLVED | STOPPING);
if (!toStop.isEmpty()) {
print("Stopping bundles:", verbose);
while (!toStop.isEmpty()) {
List<Bundle> bs = getBundlesToStop(toStop);
for (Bundle bundle : bs) {
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion(), verbose);
installSupport.stopBundle(bundle, STOP_TRANSIENT);
toStop.remove(bundle);
toStart.add(bundle);
}
}
}
if (!toRefresh.isEmpty()) {
print("Refreshing bundles:", verbose);
for (Map.Entry<Bundle, String> entry : toRefresh.entrySet()) {
Bundle bundle = entry.getKey();
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion() + " (" + entry.getValue() + ")", verbose);
}
// Ensure all classes are loaded in case the bundle will be refreshed
if (serviceBundle != null && toRefresh.containsKey(serviceBundle)) {
ensureAllClassesLoaded(serviceBundle);
}
installSupport.refreshPackages(toRefresh.keySet());
}
}
// Resolve bundles
toResolve.addAll(toStart);
toResolve.addAll(toRefresh.keySet());
removeBundlesInState(toResolve, UNINSTALLED);
callback.callListeners(DeploymentEvent.BUNDLES_INSTALLED);
installSupport.resolveBundles(toResolve, resolver.getWiring(), deployment.resToBnd);
callback.callListeners(DeploymentEvent.BUNDLES_RESOLVED);
// Compute bundles to start
removeFragmentsAndBundlesInState(toStart, UNINSTALLED | ACTIVE);
if (!toStart.isEmpty()) {
// Compute correct start order
List<Exception> exceptions = new ArrayList<>();
print("Starting bundles:", verbose);
while (!toStart.isEmpty()) {
List<Bundle> bs = getBundlesToStart(toStart, serviceBundle);
for (Bundle bundle : bs) {
print(" " + bundle.getSymbolicName() + "/" + bundle.getVersion(), verbose);
try {
installSupport.startBundle(bundle);
} catch (BundleException e) {
exceptions.add(e);
}
toStart.remove(bundle);
}
}
if (!exceptions.isEmpty()) {
throw new MultiException("Error restarting bundles", exceptions);
}
}
// Call listeners
for (Map.Entry<String, Set<String>> entry : delFeatures.entrySet()) {
for (String name : entry.getValue()) {
Feature feature = dstate.features.get(name);
if (feature != null) {
callback.callListeners(new FeatureEvent(FeatureEvent.EventType.FeatureUninstalled, feature, entry.getKey(), false));
}
}
}
for (Map.Entry<String, Set<String>> entry : newFeatures.entrySet()) {
for (String name : entry.getValue()) {
Feature feature = dstate.features.get(name);
if (feature != null) {
callback.callListeners(new FeatureEvent(FeatureEvent.EventType.FeatureInstalled, feature, entry.getKey(), false));
}
}
}
callback.callListeners(DeploymentEvent.DEPLOYMENT_FINISHED);
print("Done.", verbose);
}
use of org.apache.karaf.features.FeatureEvent in project karaf by apache.
the class EventAdminListener method featureEvent.
public void featureEvent(FeatureEvent event) {
try {
EventAdmin eventAdmin = tracker.getService();
if (eventAdmin == null) {
return;
}
Dictionary<String, Object> props = new Hashtable<>();
props.put(EventConstants.TYPE, event.getType());
props.put(EventConstants.EVENT, event);
props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
props.put(EventConstants.FEATURE_NAME, event.getFeature().getName());
props.put(EventConstants.FEATURE_VERSION, event.getFeature().getVersion());
String topic;
switch(event.getType()) {
case FeatureInstalled:
topic = EventConstants.TOPIC_FEATURES_INSTALLED;
break;
case FeatureUninstalled:
topic = EventConstants.TOPIC_FEATURES_UNINSTALLED;
break;
default:
throw new IllegalStateException("Unknown features event type: " + event.getType());
}
eventAdmin.postEvent(new Event(topic, props));
} catch (IllegalStateException e) {
LOGGER.warn("Unable to post event to EventAdmin", e);
}
}
use of org.apache.karaf.features.FeatureEvent in project karaf by apache.
the class FeaturesServiceImpl method registerListener.
//
// Listeners support
//
@Override
public void registerListener(FeaturesListener listener) {
listeners.add(listener);
try {
Set<String> repositories = new TreeSet<>();
Map<String, Set<String>> installedFeatures = new TreeMap<>();
synchronized (lock) {
repositories.addAll(state.repositories);
installedFeatures.putAll(copy(state.installedFeatures));
}
for (String uri : repositories) {
Repository repository = new RepositoryImpl(URI.create(uri), cfg.blacklisted);
listener.repositoryEvent(new RepositoryEvent(repository, RepositoryEvent.EventType.RepositoryAdded, true));
}
for (Map.Entry<String, Set<String>> entry : installedFeatures.entrySet()) {
for (String id : entry.getValue()) {
Feature feature = org.apache.karaf.features.internal.model.Feature.valueOf(id);
listener.featureEvent(new FeatureEvent(FeatureEvent.EventType.FeatureInstalled, feature, entry.getKey(), true));
}
}
} catch (Exception e) {
LOGGER.error("Error notifying listener about the current state", e);
}
}
Aggregations