* Return null if deployment is not possible.
*
*/
private Component deploy(OBRManager context) {
Resolver resolver = manager.getResolver(context);
/*
* Try to perform requirement resolution and deployment. This may need to be retried several times
* as other installations can be ongoing in parallel, and the resource requirement resolution must
* be recalculated in the new resource context.
*/
boolean deployed = false;
boolean retrying = true;
do {
/*
* calculate the transitive dependencies to satisfy requirements of the resource being deployed
*/
resolver.add(this.resource);
resolver.resolve();
/*
* If we can not resolve the resource requirements, just give up
*/
if (resolver.getUnsatisfiedRequirements().length > 0) {
retrying = false;
deployed = false;
continue;
}
/*
* Perform the actual installation,
*/
try {
resolver.deploy(Resolver.START+Resolver.NO_OPTIONAL_RESOURCES);
retrying = false;
deployed = true;
/*
* Verify that all required resources were actually installed. A resource may not be installed if a
* concurrent deployment has installed a conflicting version.
*
* In this case there is not much we can do, we just give up the deployment
*/
List<Resource> deployedResources = new ArrayList<Resource>();
deployedResources.addAll(Arrays.asList(resolver.getAddedResources()));
deployedResources.addAll(Arrays.asList(resolver.getRequiredResources()));
for (Resource deployedResource : deployedResources) {
if (getBundle(deployedResource) == null)
deployed = false;
}
}
/*
* Concurrent bundle deployment may interfere with installation and change the state of the local repository,
* which produces an IllegalStateException of the resolver.
*
* We can recover by trying again the resolution and installation process, using the new local bundles.
*
*/
catch (IllegalStateException e) {
logger.debug("OBR changed state. Resolving again " + this.resource.getSymbolicName());
retrying = true;
deployed = false;
}
/*
* If we can not recover from the error, just give up
*
*/
catch (Exception e) {
logger.error ("Deployment of " + component + " from "+resource+" failed.",e) ;
retrying = false;
deployed = false;
}
} while (retrying);
/*
* Log deployment result
*/
logger.debug("Component: " + component+ (deployed ? " successfully " : " not ") + "deployed");
logger.debug(" repository: " + repository);
List<Resource> deployedResources = new ArrayList<Resource>();
deployedResources.addAll(Arrays.asList(resolver.getAddedResources()));
deployedResources.addAll(Arrays.asList(resolver.getRequiredResources()));
for (Resource deployedResource : deployedResources) {
logger.debug(" required resource: " + deployedResource+(getBundle(deployedResource) != null ? " (installed) ":" (not installed) "));
logger.debug(" location: " + deployedResource.getURI());
Reason[] reasons = resolver.getReason(deployedResource);
for(Reason reason : reasons != null ? reasons : new Reason[0]) {
logger.debug(" satisfies requirement: " + reason.getRequirement()+" of "+reason.getResource());
}
}
for (Reason missingRequirement : resolver.getUnsatisfiedRequirements()) {
logger.error(" unsatisfied requirement: " + missingRequirement.getRequirement());
}
return deployed ? CST.componentBroker.getWaitComponent(component.getName(), 10*1000 /* milliseconds*/) : null;
}