SLING-6031 Teleporter.getService() should wait for required services
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1759492 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java b/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java
index 2d17f6f..055cbc3 100644
--- a/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java
+++ b/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java
@@ -31,6 +31,8 @@
private final List<ServiceReference> toUnget = new ArrayList<ServiceReference>();
private final BundleContext bundleContext;
+ private static final int WAITFOR_SERVICE_TIMEOUT_DEFAULT_SECONDS = 10;
+
ServerSideTeleporter() {
bundleContext = Activator.getBundleContext();
if(bundleContext == null) {
@@ -48,9 +50,41 @@
}
}
+ /**
+ * Get OSGi service - if it is not available (yet?) try again and again until the configured timeout is reached.
+ */
public <T> T getService (Class<T> serviceClass, String ldapFilter) {
+ String configuredTimeout = (String)bundleContext.getBundle().getHeaders().get("Sling-Test-WaitForService-Timeout");
+ if (configuredTimeout == null) {
+ configuredTimeout = Integer.toString(WAITFOR_SERVICE_TIMEOUT_DEFAULT_SECONDS);
+ }
+ final long timeout = System.currentTimeMillis() + Integer.parseInt(configuredTimeout) * 1000;
+
+ while (System.currentTimeMillis() < timeout) {
+ try {
+ T service = getServiceInternal(serviceClass, ldapFilter);
+ if (service != null) {
+ return service;
+ }
+ }
+ catch (IllegalStateException ex) {
+ // ignore, try again
+ }
+ try {
+ Thread.sleep(50L);
+ }
+ catch (InterruptedException ex) {
+ // ignore
+ }
+ }
+ throw new IllegalStateException(
+ "unable to get a service reference, class=" + serviceClass.getName() + ", filter='" + ldapFilter + "'");
+ }
+
+ private <T> T getServiceInternal (Class<T> serviceClass, String ldapFilter) {
final ServiceGetter sg = new ServiceGetter(bundleContext, serviceClass, ldapFilter);
toUnget.add(sg.serviceReference);
return serviceClass.cast(sg.service);
}
+
}