You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:18:50 UTC
[sling-org-apache-sling-testing-osgi-mock] 04/10: SLING-4439 add
support for unregistering services and prepare dynamic service reference
handling
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.testing.osgi-mock-1.2.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit dc9866e557685680ee107ead6b7cb8b5665247e8
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu Feb 19 15:28:14 2015 +0000
SLING-4439 add support for unregistering services and prepare dynamic service reference handling
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/osgi-mock@1660911 13f79535-47bb-0310-9956-ffa450edef68
---
.../sling/testing/mock/osgi/MockBundleContext.java | 32 ++++++++++--
.../testing/mock/osgi/MockServiceRegistration.java | 34 +++++++++++--
.../sling/testing/mock/osgi/OsgiMetadataUtil.java | 19 ++++++--
.../sling/testing/mock/osgi/OsgiServiceUtil.java | 6 +--
.../mock/osgi/ReferenceViolationException.java | 31 ++++++++++++
.../testing/mock/osgi/MockBundleContextTest.java | 57 ++++++++++++++--------
6 files changed, 146 insertions(+), 33 deletions(-)
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
index cbaa13d..37e6fd6 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
+import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.lang3.StringUtils;
@@ -44,7 +45,7 @@ import org.osgi.framework.ServiceRegistration;
class MockBundleContext implements BundleContext {
private final MockBundle bundle;
- private final List<MockServiceRegistration> registeredServices = new ArrayList<MockServiceRegistration>();
+ private final SortedSet<MockServiceRegistration> registeredServices = new TreeSet<MockServiceRegistration>();
private final List<ServiceListener> serviceListeners = new ArrayList<ServiceListener>();
private final List<BundleListener> bundleListeners = new ArrayList<BundleListener>();
@@ -77,12 +78,37 @@ class MockBundleContext implements BundleContext {
@SuppressWarnings("unchecked")
@Override
public ServiceRegistration registerService(final String[] clazzes, final Object service, final Dictionary properties) {
- MockServiceRegistration registration = new MockServiceRegistration(this.bundle, clazzes, service, properties);
+ MockServiceRegistration registration = new MockServiceRegistration(this.bundle, clazzes, service, properties, this);
+ handleRefsUpdateOnRegister(registration);
this.registeredServices.add(registration);
notifyServiceListeners(ServiceEvent.REGISTERED, registration.getReference());
return registration;
}
-
+
+ /**
+ * Check for already registered services that may be affected by the service registration - either
+ * adding by additional optional references, or creating a conflict in the dependencies.
+ * @param registration
+ */
+ private void handleRefsUpdateOnRegister(MockServiceRegistration registration) {
+ // TODO: implement handling
+ }
+
+ void unregisterService(MockServiceRegistration registration) {
+ this.registeredServices.remove(registration);
+ handleRefsUpdateOnUnregister(registration);
+ notifyServiceListeners(ServiceEvent.UNREGISTERING, registration.getReference());
+ }
+
+ /**
+ * Check for already registered services that may be affected by the service unregistration - either
+ * adding by removing optional references, or creating a conflict in the dependencies.
+ * @param registration
+ */
+ private void handleRefsUpdateOnUnregister(MockServiceRegistration registration) {
+ // TODO: implement handling
+ }
+
@Override
public ServiceReference getServiceReference(final String clazz) {
ServiceReference[] serviceRefs = getServiceReferences(clazz, null);
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MockServiceRegistration.java b/src/main/java/org/apache/sling/testing/mock/osgi/MockServiceRegistration.java
index f212b49..c9c13dd 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/MockServiceRegistration.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockServiceRegistration.java
@@ -35,22 +35,26 @@ import com.google.common.collect.ImmutableList;
/**
* Mock {@link ServiceRegistration} implementation.
*/
-class MockServiceRegistration implements ServiceRegistration {
+class MockServiceRegistration implements ServiceRegistration, Comparable<MockServiceRegistration> {
private static volatile long serviceCounter;
+ private final Long serviceId;
private final Set<String> clazzes;
private final Object service;
private Dictionary<String, Object> properties;
private final ServiceReference serviceReference;
+ private final MockBundleContext bundleContext;
public MockServiceRegistration(final Bundle bundle, final String[] clazzes, final Object service,
- final Dictionary<String, Object> properties) {
+ final Dictionary<String, Object> properties, MockBundleContext bundleContext) {
+ this.serviceId = ++serviceCounter;
this.clazzes = new HashSet<String>(ImmutableList.copyOf(clazzes));
this.service = service;
this.properties = properties != null ? properties : new Hashtable<String,Object>();
- this.properties.put(Constants.SERVICE_ID, ++serviceCounter);
+ this.properties.put(Constants.SERVICE_ID, this.serviceId);
this.serviceReference = new MockServiceReference(bundle, this);
+ this.bundleContext = bundleContext;
readOsgiMetadata();
}
@@ -67,7 +71,7 @@ class MockServiceRegistration implements ServiceRegistration {
@Override
public void unregister() {
- // do nothing for now
+ bundleContext.unregisterService(this);
}
Dictionary<String, Object> getProperties() {
@@ -78,10 +82,32 @@ class MockServiceRegistration implements ServiceRegistration {
// ignore filter for now
return this.clazzes.contains(clazz);
}
+
+ Set<String> getClasses() {
+ return clazzes;
+ }
Object getService() {
return this.service;
}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof MockServiceRegistration)) {
+ return false;
+ }
+ return serviceId.equals(((MockServiceRegistration)obj).serviceId);
+ }
+
+ @Override
+ public int hashCode() {
+ return serviceId.hashCode();
+ }
+
+ @Override
+ public int compareTo(MockServiceRegistration obj) {
+ return serviceId.compareTo(obj.serviceId);
+ }
/**
* Try to read OSGI-metadata from /OSGI-INF and read all implemented
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
index 7cf7cfb..b64cd39 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
@@ -207,7 +207,7 @@ final class OsgiMetadataUtil {
if (nodes != null) {
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
- references.add(new Reference(node));
+ references.add(new Reference(clazz, node));
}
}
return references;
@@ -253,6 +253,7 @@ final class OsgiMetadataUtil {
static class OsgiMetadata {
+ private final Class<?> clazz;
private final Set<String> serviceInterfaces;
private final Map<String, Object> properties;
private final List<Reference> references;
@@ -260,7 +261,8 @@ final class OsgiMetadataUtil {
private final String deactivateMethodName;
private final String modifiedMethodName;
- private OsgiMetadata(Class clazz, Document metadataDocument) {
+ private OsgiMetadata(Class<?> clazz, Document metadataDocument) {
+ this.clazz = clazz;
this.serviceInterfaces = OsgiMetadataUtil.getServiceInterfaces(clazz, metadataDocument);
this.properties = OsgiMetadataUtil.getProperties(clazz, metadataDocument);
this.references = OsgiMetadataUtil.getReferences(clazz, metadataDocument);
@@ -270,6 +272,7 @@ final class OsgiMetadataUtil {
}
private OsgiMetadata() {
+ this.clazz = null;
this.serviceInterfaces = null;
this.properties = null;
this.references = null;
@@ -278,6 +281,10 @@ final class OsgiMetadataUtil {
this.modifiedMethodName = null;
}
+ public Class<?> getServiceClass() {
+ return clazz;
+ }
+
public Set<String> getServiceInterfaces() {
return serviceInterfaces;
}
@@ -306,13 +313,15 @@ final class OsgiMetadataUtil {
static class Reference {
+ private final Class<?> clazz;
private final String name;
private final String interfaceType;
private final ReferenceCardinality cardinality;
private final String bind;
private final String unbind;
- private Reference(Node node) {
+ private Reference(Class<?> clazz, Node node) {
+ this.clazz = clazz;
this.name = getAttributeValue(node, "name");
this.interfaceType = getAttributeValue(node, "interface");
this.cardinality = toCardinality(getAttributeValue(node, "cardinality"));
@@ -320,6 +329,10 @@ final class OsgiMetadataUtil {
this.unbind = getAttributeValue(node, "unbind");
}
+ public Class<?> getServiceClass() {
+ return clazz;
+ }
+
private ReferenceCardinality toCardinality(String value) {
for (ReferenceCardinality item : ReferenceCardinality.values()) {
if (StringUtils.equals(item.getCardinalityString(), value)) {
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
index b340b29..306a967 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
@@ -299,14 +299,14 @@ final class OsgiServiceUtil {
boolean isOptional = (reference.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || reference
.getCardinality() == ReferenceCardinality.OPTIONAL_MULTIPLE);
if (!isOptional) {
- throw new RuntimeException("Unable to inject mandatory reference '" + reference.getName() + "' for class " + targetClass.getName());
+ throw new ReferenceViolationException("Unable to inject mandatory reference '" + reference.getName() + "' for class " + targetClass.getName());
}
}
// multiple references found? check if reference is not multiple
if (matchingServices.size() > 1
&& (reference.getCardinality() == ReferenceCardinality.MANDATORY_UNARY || reference.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY)) {
- throw new RuntimeException("Multiple matches found for unary reference '" + reference.getName() + "' for class "+ targetClass.getName());
+ throw new ReferenceViolationException("Multiple matches found for unary reference '" + reference.getName() + "' for class "+ targetClass.getName());
}
// try to invoke bind method
@@ -350,7 +350,7 @@ final class OsgiServiceUtil {
throw new RuntimeException("Bind method with name " + bindMethodName + " not found "
+ "for reference '" + reference.getName() + "' for class {}" + targetClass.getName());
}
-
+
private static List<ServiceInfo> getMatchingServices(Class<?> type, BundleContext bundleContext) {
List<ServiceInfo> matchingServices = new ArrayList<ServiceInfo>();
try {
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/ReferenceViolationException.java b/src/main/java/org/apache/sling/testing/mock/osgi/ReferenceViolationException.java
new file mode 100644
index 0000000..4bfa0f2
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/ReferenceViolationException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.mock.osgi;
+
+/**
+ * Is thrown when a OSGi reference injection fails due to violated constraints.
+ */
+public final class ReferenceViolationException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public ReferenceViolationException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextTest.java
index 6eef138..a6a6258 100644
--- a/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextTest.java
@@ -21,6 +21,7 @@ package org.apache.sling.testing.mock.osgi;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
@@ -50,12 +51,12 @@ public class MockBundleContextTest {
@Before
public void setUp() {
- this.bundleContext = MockOsgi.newBundleContext();
+ bundleContext = MockOsgi.newBundleContext();
}
@Test
public void testBundle() {
- assertNotNull(this.bundleContext.getBundle());
+ assertNotNull(bundleContext.getBundle());
}
@Test
@@ -64,48 +65,64 @@ public class MockBundleContextTest {
String clazz1 = String.class.getName();
Object service1 = new Object();
Dictionary properties1 = getServiceProperties(null);
- ServiceRegistration reg1 = this.bundleContext.registerService(clazz1, service1, properties1);
+ ServiceRegistration reg1 = bundleContext.registerService(clazz1, service1, properties1);
String[] clazzes2 = new String[] { String.class.getName(), Integer.class.getName() };
Object service2 = new Object();
Dictionary properties2 = getServiceProperties(null);
- ServiceRegistration reg2 = this.bundleContext.registerService(clazzes2, service2, properties2);
+ ServiceRegistration reg2 = bundleContext.registerService(clazzes2, service2, properties2);
String clazz3 = Integer.class.getName();
Object service3 = new Object();
Dictionary properties3 = getServiceProperties(100L);
- ServiceRegistration reg3 = this.bundleContext.registerService(clazz3, service3, properties3);
+ ServiceRegistration reg3 = bundleContext.registerService(clazz3, service3, properties3);
// test get service references
- ServiceReference refString = this.bundleContext.getServiceReference(String.class.getName());
+ ServiceReference refString = bundleContext.getServiceReference(String.class.getName());
assertSame(reg1.getReference(), refString);
- ServiceReference refInteger = this.bundleContext.getServiceReference(Integer.class.getName());
+ ServiceReference refInteger = bundleContext.getServiceReference(Integer.class.getName());
assertSame(reg3.getReference(), refInteger);
- ServiceReference[] refsString = this.bundleContext.getServiceReferences(String.class.getName(), null);
+ ServiceReference[] refsString = bundleContext.getServiceReferences(String.class.getName(), null);
assertEquals(2, refsString.length);
assertSame(reg1.getReference(), refsString[0]);
assertSame(reg2.getReference(), refsString[1]);
- ServiceReference[] refsInteger = this.bundleContext.getServiceReferences(Integer.class.getName(), null);
+ ServiceReference[] refsInteger = bundleContext.getServiceReferences(Integer.class.getName(), null);
assertEquals(2, refsInteger.length);
assertSame(reg3.getReference(), refsInteger[0]);
assertSame(reg2.getReference(), refsInteger[1]);
- ServiceReference[] allRefsString = this.bundleContext.getAllServiceReferences(String.class.getName(), null);
+ ServiceReference[] allRefsString = bundleContext.getAllServiceReferences(String.class.getName(), null);
assertArrayEquals(refsString, allRefsString);
// test get services
- assertSame(service1, this.bundleContext.getService(refsString[0]));
- assertSame(service2, this.bundleContext.getService(refsString[1]));
- assertSame(service3, this.bundleContext.getService(refInteger));
+ assertSame(service1, bundleContext.getService(refsString[0]));
+ assertSame(service2, bundleContext.getService(refsString[1]));
+ assertSame(service3, bundleContext.getService(refInteger));
// unget does nothing
- this.bundleContext.ungetService(refsString[0]);
- this.bundleContext.ungetService(refsString[1]);
- this.bundleContext.ungetService(refInteger);
+ bundleContext.ungetService(refsString[0]);
+ bundleContext.ungetService(refsString[1]);
+ bundleContext.ungetService(refInteger);
}
+
+ @Test
+ public void testServiceUnregistration() {
+ // prepare test services
+ String clazz1 = String.class.getName();
+ Object service1 = new Object();
+ Dictionary properties1 = getServiceProperties(null);
+ ServiceRegistration reg1 = bundleContext.registerService(clazz1, service1, properties1);
+
+ assertNotNull(bundleContext.getServiceReference(clazz1));
+
+ reg1.unregister();
+
+ assertNull(bundleContext.getServiceReference(clazz1));
+ }
+
private Dictionary getServiceProperties(final Long serviceRanking) {
Dictionary<String, Object> props = new Hashtable<String, Object>();
@@ -117,7 +134,7 @@ public class MockBundleContextTest {
@Test
public void testGetBundles() throws Exception {
- assertEquals(0, this.bundleContext.getBundles().length);
+ assertEquals(0, bundleContext.getBundles().length);
}
@Test
@@ -128,7 +145,7 @@ public class MockBundleContextTest {
// prepare test services
String clazz1 = String.class.getName();
Object service1 = new Object();
- this.bundleContext.registerService(clazz1, service1, null);
+ bundleContext.registerService(clazz1, service1, null);
verify(serviceListener).serviceChanged(any(ServiceEvent.class));
@@ -152,8 +169,8 @@ public class MockBundleContextTest {
public void testFrameworkListener() throws Exception {
// ensure that listeners can be called (although they are not expected
// to to anything)
- this.bundleContext.addFrameworkListener(null);
- this.bundleContext.removeFrameworkListener(null);
+ bundleContext.addFrameworkListener(null);
+ bundleContext.removeFrameworkListener(null);
}
}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.