You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by js...@apache.org on 2016/11/28 17:30:09 UTC
svn commit: r1771777 - in
/sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules:
ServerSideTeleporter.java Service.java ServiceGetter.java
Author: jsedding
Date: Mon Nov 28 17:30:09 2016
New Revision: 1771777
URL: http://svn.apache.org/viewvc?rev=1771777&view=rev
Log:
SLING-6335 - Server-Side Tests: Use ServiceTracker to wait for services rather than polling
Modified:
sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java
sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/Service.java
sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServiceGetter.java
Modified: sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java?rev=1771777&r1=1771776&r2=1771777&view=diff
==============================================================================
--- sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java (original)
+++ sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServerSideTeleporter.java Mon Nov 28 17:30:09 2016
@@ -23,25 +23,25 @@ import org.apache.sling.junit.Activator;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.InvalidSyntaxException;
/** Server-side variant of the TeleporterRule, which provides
* access to OSGi services for convenience, but does not do
* much more.
*/
class ServerSideTeleporter extends TeleporterRule {
- private final List<ServiceReference> toUnget = new ArrayList<ServiceReference>();
+ private final List<ServiceGetter<?>> serviceGettersToClose = new ArrayList<ServiceGetter<?>>();
private final BundleContext bundleContext;
private final Bundle bundleUnderTest;
-
+
private static final int WAITFOR_SERVICE_TIMEOUT_DEFAULT_SECONDS = 10;
-
+
ServerSideTeleporter(Class<?> classUnderTest) {
bundleContext = Activator.getBundleContext();
if (bundleContext == null) {
throw new IllegalStateException("Null BundleContext, should not happen when this class is used");
}
-
+
Bundle bundle = FrameworkUtil.getBundle(classUnderTest);
if (bundle == null) {
bundle = bundleContext.getBundle();
@@ -52,9 +52,9 @@ class ServerSideTeleporter extends Telep
@Override
protected void after() {
super.after();
- for(ServiceReference r : toUnget) {
- if(r != null) {
- bundleContext.ungetService(r);
+ for(ServiceGetter<?> serviceGetter : serviceGettersToClose) {
+ if(serviceGetter != null) {
+ serviceGetter.close();
}
}
}
@@ -68,32 +68,25 @@ class ServerSideTeleporter extends Telep
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
+ try {
+ T service = getServiceInternal(serviceClass, ldapFilter, timeout);
+ if (service != null) {
+ return service;
}
+ } catch (InterruptedException e) {
+ throw new IllegalStateException(
+ "unable to get a service reference before timeout, class=" + serviceClass.getName() + ", filter='" + ldapFilter + "'", e);
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Invalid syntax for argument ldapFilter", e);
}
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);
+ private <T> T getServiceInternal (Class<T> serviceClass, String ldapFilter, long timeoutMs)
+ throws InterruptedException, InvalidSyntaxException {
+ ServiceGetter<T> serviceGetter = ServiceGetter.create(bundleContext, serviceClass, ldapFilter);
+ serviceGettersToClose.add(serviceGetter);
+ return serviceGetter.getService(timeoutMs);
}
-
}
Modified: sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/Service.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/Service.java?rev=1771777&r1=1771776&r2=1771777&view=diff
==============================================================================
--- sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/Service.java (original)
+++ sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/Service.java Mon Nov 28 17:30:09 2016
@@ -34,7 +34,7 @@ public class Service implements TestRule
private final Class<?> serviceClass;
- private Object service;
+ private ServiceGetter<?> serviceGetter;
public Service(Class<?> serviceClass) {
this.serviceClass = serviceClass;
@@ -54,17 +54,12 @@ public class Service implements TestRule
base.evaluate();
return;
}
-
- final ServiceGetter sg = new ServiceGetter(bundleContext, serviceClass, null);
- Service.this.service = serviceClass.cast(sg.service);
+ serviceGetter = ServiceGetter.create(bundleContext, serviceClass, null);
try {
base.evaluate();
} finally {
- Service.this.service = null;
- if(sg.serviceReference != null) {
- bundleContext.ungetService(sg.serviceReference);
- }
+ serviceGetter.close();
}
}
@@ -79,7 +74,7 @@ public class Service implements TestRule
* @return The service object.
*/
public <T> T getService(Class<T> serviceClass) {
- return serviceClass.cast(service);
+ return serviceClass.cast(serviceGetter.getService());
}
}
Modified: sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServiceGetter.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServiceGetter.java?rev=1771777&r1=1771776&r2=1771777&view=diff
==============================================================================
--- sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServiceGetter.java (original)
+++ sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/rules/ServiceGetter.java Mon Nov 28 17:30:09 2016
@@ -17,61 +17,71 @@
package org.apache.sling.junit.rules;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.io.Closeable;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
/** Implements the logic used to get a service */
-class ServiceGetter {
- final ServiceReference serviceReference;
- final Object service;
+class ServiceGetter<T> implements Closeable {
+
+ private final ServiceTracker tracker;
+ private final BundleContext bundleContext;
+
+ public static <T> ServiceGetter<T> create(BundleContext bundleContext, Class<T> serviceClass, String ldapFilter) {
+ return new ServiceGetter<T>(bundleContext, serviceClass, ldapFilter);
+ }
@SuppressWarnings("unchecked")
- ServiceGetter(BundleContext bundleContext, Class<?> serviceClass, String ldapFilter) {
- Object s;
-
+ private ServiceGetter(BundleContext bundleContext, Class<T> serviceClass, String ldapFilter) {
if (serviceClass.equals(BundleContext.class)) {
// Special case to provide the BundleContext to tests
- s = serviceClass.cast(bundleContext);
- serviceReference = null;
+ this.bundleContext = bundleContext;
+ this.tracker = null;
} else {
- if(ldapFilter != null && !ldapFilter.isEmpty()) {
- try {
- final ServiceReference [] services = bundleContext.getServiceReferences(serviceClass.getName(), ldapFilter);
- if(services == null) {
- serviceReference = null;
- } else {
- // Prefer services which have a higher ranking
- final List<ServiceReference> sorted = Arrays.asList(services);
- Collections.sort(sorted);
- serviceReference = sorted.get(sorted.size() - 1);
- }
- } catch (InvalidSyntaxException e) {
- throw new IllegalStateException("Invalid filter syntax:" + ldapFilter, e);
- }
+ this.bundleContext = null;
+ final String classFilter = String.format("(%s=%s)", Constants.OBJECTCLASS, serviceClass.getName());
+ final String combinedFilter;
+ if (ldapFilter == null || ldapFilter.trim().length() == 0) {
+ combinedFilter = classFilter;
} else {
- serviceReference = bundleContext.getServiceReference(serviceClass.getName());
+ combinedFilter = String.format("(&%s%s)", classFilter, ldapFilter);
}
-
- if (serviceReference == null) {
- throw new IllegalStateException(
- "unable to get a service reference, class=" + serviceClass.getName() + ", filter='" + ldapFilter + "'");
+ final Filter filter;
+ try {
+ filter = FrameworkUtil.createFilter(combinedFilter);
+ tracker = new ServiceTracker(bundleContext, filter, null);
+ tracker.open();
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalArgumentException("Syntax of argument ldapFilter is invalid", e);
}
+ }
+ }
- final Object service = bundleContext.getService(serviceReference);
+ public T getService() {
+ if (tracker == null) {
+ return (T)bundleContext;
+ } else {
+ return (T)tracker.getService();
+ }
+ }
- if (service == null) {
- throw new IllegalStateException(
- "unable to get an instance of the service");
- }
+ public T getService(long timeout) throws InterruptedException {
+ if (tracker == null) {
+ return (T)bundleContext;
+ } else {
+ return (T)tracker.waitForService(timeout);
+ }
+ }
- s = serviceClass.cast(service);
+ @Override
+ public void close() {
+ if (tracker != null) {
+ tracker.close();
}
-
- service = s;
}
}
\ No newline at end of file