This is an automated email from the ASF dual-hosted git repository. jsedding pushed a commit to branch fix/SLING-12157-late-bind-unbind-for-DS-components in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit ab8371a6be3a47d3f15acfe8a2d053cf775623f6 Author: Julian Sedding <[email protected]> AuthorDate: Wed Nov 15 18:04:59 2023 +0100 SLING-12157 [osgi-mock] late binding does not work for non-service DS components - OsgiServiceUtilBindUnbindTest seems to have worked around this issue, hence the change - factored out "registerDSComponent" in order to reduce code duplication - with this fix, a non-service DS component is stored in MockBundleContext#registeredServices but its MockServiceRegistration#clazzes field is an empty set and thus cannot be retrieved via BundleContext#getServiceReference --- .../apache/sling/testing/mock/osgi/MockOsgi.java | 28 ++++++++++++---------- .../mock/osgi/OsgiServiceUtilBindUnbindTest.java | 3 +-- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java b/core/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java index ac51aef..c847c92 100644 --- a/core/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java +++ b/core/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.util.Dictionary; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata; import org.jetbrains.annotations.NotNull; @@ -228,12 +229,7 @@ public final class MockOsgi { MockOsgi.injectServices(component, bundleContext, mergedProperties); ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties); OsgiServiceUtil.activateDeactivate(component, (MockComponentContext)componentContext, true); - OsgiMetadata metadata = OsgiMetadataUtil.getMetadata(component.getClass()); - if (!metadata.getServiceInterfaces().isEmpty()) { - // convert component properties to service properties (http://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-service.properties) - Dictionary<String, Object> serviceProperties = mergedProperties.entrySet().stream().filter(e -> e.getKey() != null && !e.getKey().startsWith(".")).collect(new DictionaryCollector<String, Object>(Entry::getKey, Entry::getValue)); - bundleContext.registerService(metadata.getServiceInterfaces().toArray(new String[0]), component, serviceProperties); - } + registerDSComponent(component, bundleContext, mergedProperties); } /** @@ -270,15 +266,23 @@ public final class MockOsgi { Map<String, Object> mergedProperties = propertiesMergeWithOsgiMetadata(dsComponentClass, getConfigAdmin(bundleContext), properties); ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties); T component = OsgiServiceUtil.activateInjectServices(dsComponentClass, (MockComponentContext)componentContext); - OsgiMetadata metadata = OsgiMetadataUtil.getMetadata(dsComponentClass); - if (!metadata.getServiceInterfaces().isEmpty()) { - // convert component properties to service properties (http://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-service.properties) - Dictionary<String, Object> serviceProperties = mergedProperties.entrySet().stream().filter(e -> e.getKey() != null && !e.getKey().startsWith(".")).collect(new DictionaryCollector<String, Object>(Entry::getKey, Entry::getValue)); - bundleContext.registerService(metadata.getServiceInterfaces().toArray(new String[0]), component, serviceProperties); - } + registerDSComponent(component, bundleContext, mergedProperties); return component; } + private static <T> void registerDSComponent(@NotNull T component, @NotNull BundleContext bundleContext, Map<String, Object> mergedProperties) { + OsgiMetadata metadata = Objects.requireNonNull(OsgiMetadataUtil.getMetadata(component.getClass()), + "No metadata found for " + component.getClass()); + + // convert component properties to service properties (http://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-service.properties) + Dictionary<String, Object> serviceProperties = mergedProperties.entrySet().stream() + .filter(e -> e.getKey() != null && !e.getKey().startsWith(".")) + .collect(new DictionaryCollector<>(Entry::getKey, Entry::getValue)); + + // we also register DS Components that aren't services in order for bind/unbind to work - they are registered with no service interfaces + bundleContext.registerService(metadata.getServiceInterfaces().toArray(new String[0]), component, serviceProperties); + } + /** * Injects dependencies, activates and registers a DS component in the mocked OSGi environment. * @param <T> DS component type diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java index 4bce611..9e6f834 100644 --- a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java +++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilBindUnbindTest.java @@ -141,8 +141,7 @@ public class OsgiServiceUtilBindUnbindTest { @SuppressWarnings({ "null", "unchecked" }) private <T> T registerInjectService(T service) { - MockOsgi.injectServices(service, bundleContext); - bundleContext.registerService((Class<T>)service.getClass(), service, (Dictionary)null); + MockOsgi.registerInjectActivateService(service, bundleContext); return service; }
