in src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java [115:237]
public void execute(InstallContext context) throws PackageException {
VaultPackage vaultPackage = context.getPackage();
PackageProperties packageProperties = vaultPackage.getProperties();
String installPathRegex = packageProperties.getProperty(PACKAGE_PROP_INSTALL_PATH_REGEX);
ServiceReference<OsgiInstaller> osgiInstallerServiceRef = null;
ServiceReference<SlingSettingsService> slingSettingsServiceRef = null;
ServiceRegistration<InstallationListener> hookInstallationListenerServiceRegistration = null;
ServiceReference<InfoProvider> infoProviderServiceRef = null;
try {
switch (context.getPhase()) {
case PREPARE:
if (StringUtils.isBlank(installPathRegex)) {
throw new IllegalArgumentException(
"When using OSGi installer install hook for synchronous installation, the package property "
+ PACKAGE_PROP_INSTALL_PATH_REGEX + " has to be provided.");
}
break;
case INSTALLED:
ImportOptions options = context.getOptions();
logger.setOptions(options);
logger.log(getClass().getSimpleName() + " is active in " + vaultPackage.getId());
List<BundleInPackage> bundleResources = new ArrayList<>();
List<String> configResourcePaths = new ArrayList<>();
Archive archive = vaultPackage.getArchive();
infoProviderServiceRef = getBundleContext().getServiceReference(InfoProvider.class);
InfoProvider infoProvider = (InfoProvider) getBundleContext().getService(infoProviderServiceRef);
InstallationState installationState = infoProvider.getInstallationState();
slingSettingsServiceRef = getBundleContext().getServiceReference(SlingSettingsService.class);
SlingSettingsService slingSettingsService = (SlingSettingsService) getBundleContext().getService(slingSettingsServiceRef);
Set<String> runModes = slingSettingsService.getRunModes();
collectResources(archive, archive.getRoot(), "", bundleResources, configResourcePaths, installPathRegex,
runModes);
logger.log("Bundles in package " + bundleResources);
Session session = context.getSession();
Map<String, InstallableResource> bundlesToInstallByUrl = getBundlesToInstall(bundleResources, session, installationState,
packageProperties);
Map<String, InstallableResource> configsToInstallByUrl = getConfigsToInstall(configResourcePaths, session,
installationState, packageProperties);
if (bundlesToInstallByUrl.isEmpty() && configsToInstallByUrl.isEmpty()) {
logger.log("No installable resources that are not installed yet found.");
return;
}
logger.log("Installing " + bundlesToInstallByUrl.size() + " bundles and "
+ configsToInstallByUrl.size() + " configs");
osgiInstallerServiceRef = getBundleContext().getServiceReference(OsgiInstaller.class);
OsgiInstaller osgiInstaller = getBundleContext().getService(osgiInstallerServiceRef);
OsgiInstallerListener hookInstallationListener = new OsgiInstallerListener(bundlesToInstallByUrl.keySet(),
configsToInstallByUrl.keySet());
hookInstallationListenerServiceRegistration = getBundleContext()
.registerService(InstallationListener.class, hookInstallationListener, null);
List<InstallableResource> resourcesToUpdate = new ArrayList<>();
resourcesToUpdate.addAll(bundlesToInstallByUrl.values());
resourcesToUpdate.addAll(configsToInstallByUrl.values());
logger.log("Updating resources " + resourcesToUpdate);
osgiInstaller.updateResources(URL_SCHEME, resourcesToUpdate.toArray(new InstallableResource[resourcesToUpdate.size()]),
null);
int maxWaitForOsgiInstallerInSec = getNumericPackageProperty(packageProperties, PACKAGE_PROPERTY_MAX_WAIT_IN_SEC,
DEFAULT_MAX_WAIT_IN_SEC);
long startTime = System.currentTimeMillis();
int bundlesLeftToInstall = 0;
int configsLeftToInstall = 0;
while ((bundlesLeftToInstall = hookInstallationListener.bundlesLeftToInstall()) > 0
|| (configsLeftToInstall = hookInstallationListener.configsLeftToInstall()) > 0) {
if ((System.currentTimeMillis() - startTime) > maxWaitForOsgiInstallerInSec * 1000) {
logger.log("Installable resources " + resourcesToUpdate
+ " could not be installed even after waiting " + maxWaitForOsgiInstallerInSec + "sec");
break;
}
logger.log("Waiting for " + bundlesLeftToInstall + " bundles / " + configsLeftToInstall + " configs to be installed");
Thread.sleep(1000);
// the events are not always reliably received, also update listener explicitly with current installation state
hookInstallationListener.updateWith(infoProvider.getInstallationState().getInstalledResources());
}
if (bundlesLeftToInstall == 0 && configsLeftToInstall == 0) {
logger.log("All " + bundlesToInstallByUrl.size() + " bundles / " + configsToInstallByUrl.size()
+ " configs have been successfully installed in " + (System.currentTimeMillis() - startTime) + "ms");
}
int waitForOsgiEventsQuietInSec = getNumericPackageProperty(packageProperties,
PACKAGE_PROPERTY_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC, DEFAULT_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC);
waitForServiceChanges(waitForOsgiEventsQuietInSec);
break;
default:
break;
}
} catch (Exception e) {
throw new PackageException("Could not execute install hook to for synchronous installation: " + e, e);
} finally {
if (osgiInstallerServiceRef != null) {
getBundleContext().ungetService(osgiInstallerServiceRef);
}
if (slingSettingsServiceRef != null) {
getBundleContext().ungetService(slingSettingsServiceRef);
}
if (infoProviderServiceRef != null) {
getBundleContext().ungetService(infoProviderServiceRef);
}
if (hookInstallationListenerServiceRegistration != null) {
hookInstallationListenerServiceRegistration.unregister();
}
}
}