blob: e99c45412dd2bd738e3c94b8381020849dc38c3b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.testing.clients.osgi;
import org.apache.sling.testing.clients.ClientException;
import org.apache.sling.testing.clients.util.poller.AbstractPoller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* Utility for installing and starting additional bundles for testing
*/
public class BundlesInstaller {
private final Logger log = LoggerFactory.getLogger(getClass());
private final OsgiConsoleClient osgiConsoleClient;
public static final String ACTIVE_STATE = "active";
public BundlesInstaller(OsgiConsoleClient cc) {
osgiConsoleClient = cc;
}
/**
* Checks if a bundle is installed or not. Does not retry.
* @param bundleFile
* @return
* @throws ClientException
* @throws IOException
* @throws InterruptedException
*/
public boolean isInstalled(File bundleFile) throws ClientException, InterruptedException, IOException {
final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(bundleFile);
log.debug("Checking if installed: " + bundleSymbolicName);
boolean installed = osgiConsoleClient.checkBundleInstalled(bundleSymbolicName, 1000, 1);
// if this succeeds, then there's no need to install again
if (installed) {
log.debug("Already installed: " + bundleSymbolicName);
return true;
} else {
log.debug("Not yet installed: " + bundleSymbolicName);
return false;
}
}
/**
* Check if the installed version matches the one of the bundle (file)
* @param bundleFile
* @return
* @throws Exception
*/
public boolean isInstalledWithSameVersion(File bundleFile) throws ClientException, IOException {
final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(bundleFile);
final String versionOnServer = osgiConsoleClient.getBundleVersion(bundleSymbolicName);
final String versionInBundle = OsgiConsoleClient.getBundleVersionFromFile(bundleFile);
if (versionOnServer.equals(versionInBundle)) {
return true;
} else {
log.warn("Installed bundle doesn't match: {}, versionOnServer={}, versionInBundle={}",
bundleSymbolicName, versionOnServer, versionInBundle);
return false;
}
}
/**
* Install a list of bundles supplied as Files
* @param toInstall
* @param startBundles
* @throws Exception
*/
public void installBundles(List<File> toInstall, boolean startBundles) throws ClientException, IOException, InterruptedException {
for(File f : toInstall) {
final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(f);
if (isInstalled(f)) {
if (f.getName().contains("SNAPSHOT")) {
log.info("Reinstalling (due to SNAPSHOT version): {}", bundleSymbolicName);
osgiConsoleClient.uninstallBundle(bundleSymbolicName);
} else if (!isInstalledWithSameVersion(f)) {
log.info("Reinstalling (due to version mismatch): {}", bundleSymbolicName);
osgiConsoleClient.uninstallBundle(bundleSymbolicName);
} else {
log.info("Not reinstalling: {}", bundleSymbolicName);
continue;
}
}
osgiConsoleClient.installBundle(f, startBundles);
log.info("Installed: {}", bundleSymbolicName);
}
// ensure that bundles are re-wired esp. if an existing bundle was updated
osgiConsoleClient.refreshPackages();
log.info("{} additional bundles installed", toInstall.size());
}
/**
* Uninstall a list of bundles supplied as Files
* @param toUninstall
* @throws ClientException
* @throws IOException
* @throws InterruptedException
*/
public void uninstallBundles(List<File> toUninstall) throws ClientException, IOException, InterruptedException {
for(File f : toUninstall) {
final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(f);
if (isInstalled(f)) {
log.info("Uninstalling bundle: {}", bundleSymbolicName);
osgiConsoleClient.uninstallBundle(bundleSymbolicName);
} else {
log.info("Could not uninstall: {} as it never was installed", bundleSymbolicName);
}
}
// ensure that bundles are re-wired esp. if an existing bundle was updated
osgiConsoleClient.refreshPackages();
log.info("{} additional bundles uninstalled", toUninstall.size());
}
/**
* Wait for all bundles specified in symbolicNames list to be installed in the OSGi web console.
* @param symbolicNames the list of names for the bundles
* @param timeoutSeconds how many seconds to wait
* @return
* @throws Exception
*/
public boolean waitForBundlesInstalled(List<String> symbolicNames, int timeoutSeconds) throws ClientException, InterruptedException {
log.info("Checking that the following bundles are installed (timeout {} seconds): {}", timeoutSeconds, symbolicNames);
for (String symbolicName : symbolicNames) {
boolean started = osgiConsoleClient.checkBundleInstalled(symbolicName, 500, 2 * timeoutSeconds);
if (!started) return false;
}
return true;
}
/**
* Start all the bundles in a {{List}}
* @param symbolicNames the list of bundles to start
* @param timeoutSeconds number of seconds until it times out
* @throws ClientException
* @throws InterruptedException
*/
public void startAllBundles(final List<String> symbolicNames, int timeoutSeconds) throws ClientException, InterruptedException {
log.info("Starting bundles (timeout {} seconds): {}", timeoutSeconds, symbolicNames);
class StartAllBundlesPoller extends AbstractPoller {
private ClientException exception;
public StartAllBundlesPoller(List<String> symbolicNames, long waitInterval, long waitCount) {
super(waitInterval, waitCount);
}
@Override
public boolean call() {
for (String bundle : symbolicNames) {
final String state;
try {
state = osgiConsoleClient.getBundleState(bundle);
if (!state.equalsIgnoreCase(ACTIVE_STATE)) {
osgiConsoleClient.startBundle(bundle);
}
} catch (ClientException e) {
this.exception = e;
return false;
}
}
return true;
}
@Override
public boolean condition() {
for (String bundle : symbolicNames) {
final String state;
try {
state = osgiConsoleClient.getBundleState(bundle);
if (!state.equalsIgnoreCase(ACTIVE_STATE)) {
return false;
}
} catch (ClientException e) {
this.exception = e;
return false;
}
}
return true;
}
public ClientException getException() {
return exception;
}
}
StartAllBundlesPoller poller = new StartAllBundlesPoller(symbolicNames, 1000, timeoutSeconds);
if (!poller.callUntilCondition()) {
throw new ClientException("Some bundles did not start or timed out", poller.getException());
}
}
}