You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2021/12/07 14:51:24 UTC

[sling-org-apache-sling-testing-osgi-mock] branch experimental/serviceFactory_scopePrototype created (now 93f9856)

This is an automated email from the ASF dual-hosted git repository.

sseifert pushed a change to branch experimental/serviceFactory_scopePrototype
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git.


      at 93f9856  WIP: start implementing support for service scope, and proper implementation of factory service support

This branch includes the following new commits:

     new 93f9856  WIP: start implementing support for service scope, and proper implementation of factory service support

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[sling-org-apache-sling-testing-osgi-mock] 01/01: WIP: start implementing support for service scope, and proper implementation of factory service support

Posted by ss...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sseifert pushed a commit to branch experimental/serviceFactory_scopePrototype
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git

commit 93f9856b29ce232dfa926b0e4368f7f2cae3217b
Author: Stefan Seifert <st...@users.noreply.github.com>
AuthorDate: Tue Dec 7 15:50:32 2021 +0100

    WIP: start implementing support for service scope, and proper implementation of factory service support
---
 .../sling/testing/mock/osgi/OsgiMetadataUtil.java  | 26 ++++++++++
 .../testing/mock/osgi/OsgiMetadataUtilTest.java    |  9 ++++
 .../testing/mock/osgi/OsgiServiceUtilTest.java     | 59 +++++++++++----------
 ...iceFactory1.java => ScopePrototypeService.java} | 15 +++++-
 .../ScopePrototypeServiceFactory.java              | 60 ++++++++++++++++++++++
 5 files changed, 140 insertions(+), 29 deletions(-)

diff --git a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
index e094d10..216e022 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -47,10 +48,12 @@ import org.apache.commons.collections4.BidiMap;
 import org.apache.commons.collections4.bidimap.TreeBidiMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.framework.FilterImpl;
+import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.annotations.ServiceScope;
 import org.reflections.Reflections;
 import org.reflections.scanners.Scanners;
 import org.slf4j.Logger;
@@ -287,6 +290,22 @@ final class OsgiMetadataUtil {
         return serviceInterfaces;
     }
 
+    @SuppressWarnings("null")
+    private static @NotNull ServiceScope getServiceScope(Class clazz, Document metadata) {
+        String query = getComponentXPathQuery(clazz) + "/service";
+        String scopeValue;
+        NodeList nodes = queryNodes(metadata, query);
+        if (nodes != null && nodes.getLength() > 0) {
+            scopeValue = getAttributeValue(nodes.item(0), "scope");
+        }
+        else {
+            scopeValue = null;
+        }
+        return Arrays.stream(ServiceScope.values())
+                .filter(serviceScope -> StringUtils.equals(scopeValue, serviceScope.toString()))
+                .findFirst().orElse(ServiceScope.DEFAULT);
+    }
+
     private static Map<String, Object> getProperties(Class clazz, Document metadata) {
         Map<String, Object> props = new HashMap<String, Object>();
         String query = getComponentXPathQuery(clazz) + "/property[@name!='' and @value!='']";
@@ -384,6 +403,7 @@ final class OsgiMetadataUtil {
         private final String name;
         private final String[] configurationPID;
         private final Set<String> serviceInterfaces;
+        private final ServiceScope serviceScope;
         private final Map<String, Object> properties;
         private final List<Reference> references;
         private final String activateMethodName;
@@ -395,6 +415,7 @@ final class OsgiMetadataUtil {
             this.name = OsgiMetadataUtil.getComponentName(clazz, metadataDocument);
             this.configurationPID = OsgiMetadataUtil.getConfigurationPID(clazz, metadataDocument);
             this.serviceInterfaces = OsgiMetadataUtil.getServiceInterfaces(clazz, metadataDocument);
+            this.serviceScope = OsgiMetadataUtil.getServiceScope(clazz, metadataDocument);
             this.properties = OsgiMetadataUtil.getProperties(clazz, metadataDocument);
             this.references = OsgiMetadataUtil.getReferences(clazz, metadataDocument);
             this.activateMethodName = OsgiMetadataUtil.getLifecycleMethodName(clazz, metadataDocument, "activate");
@@ -407,6 +428,7 @@ final class OsgiMetadataUtil {
             this.name = null;
             this.configurationPID = null;
             this.serviceInterfaces = null;
+            this.serviceScope = ServiceScope.DEFAULT;
             this.properties = null;
             this.references = null;
             this.activateMethodName = null;
@@ -438,6 +460,10 @@ final class OsgiMetadataUtil {
             return serviceInterfaces;
         }
 
+        public @NotNull ServiceScope getServiceScope() {
+            return serviceScope;
+        }
+
         public Map<String, Object> getProperties() {
             return properties;
         }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtilTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtilTest.java
index a1d64f7..913bf27 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtilTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtilTest.java
@@ -30,10 +30,12 @@ import java.util.Set;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.Reference;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.ReferenceCardinality;
+import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ScopePrototypeService;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface2;
 import org.junit.Test;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.ServiceScope;
 
 public class OsgiMetadataUtilTest {
 
@@ -46,6 +48,7 @@ public class OsgiMetadataUtilTest {
         Set<String> serviceInterfaces = metadata.getServiceInterfaces();
         assertEquals(1, serviceInterfaces.size());
         assertTrue(serviceInterfaces.contains("java.lang.Comparable"));
+        assertEquals(ServiceScope.DEFAULT, metadata.getServiceScope());
 
         Map<String, Object> props = metadata.getProperties();
         assertEquals(3, props.size());
@@ -81,6 +84,12 @@ public class OsgiMetadataUtilTest {
         assertEquals("activate", metadata.getActivateMethodName());
     }
 
+    @Test
+    public void testServiceScope() {
+        OsgiMetadata metadata = OsgiMetadataUtil.getMetadata(ScopePrototypeService.class);
+        assertEquals(ServiceScope.PROTOTYPE, metadata.getServiceScope());
+    }
+
     static class ServiceWithMetadata {
         // empty class
     }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
index 3e428ce..01208f5 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
@@ -21,6 +21,7 @@ package org.apache.sling.testing.mock.osgi;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
@@ -32,13 +33,15 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ScopePrototypeService;
+import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ScopePrototypeServiceFactory;
+import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ScopePrototypeServiceFactory.ScopePrototpyeInstance;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service1;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service2;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service4;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service5;
-import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceFactory1;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface2;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface3;
@@ -48,10 +51,8 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
-import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.ServiceReference;
 
 import com.google.common.collect.ImmutableMap;
 
@@ -210,34 +211,38 @@ public class OsgiServiceUtilTest {
     }
 
     @Test
-    public void testServiceFactoryViaScr() {
-        ServiceFactory1 serviceFactory1 = new ServiceFactory1();
+    public void testScopePrototypeService() {
+        MockOsgi.registerInjectActivateService(ScopePrototypeService.class, bundleContext);
 
-        MockOsgi.injectServices(serviceFactory1, bundleContext);
-        MockOsgi.activate(serviceFactory1, bundleContext, (Dictionary<String, Object>) null);
-        bundleContext.registerService(ServiceFactory1.class.getName(), serviceFactory1, null);
+        ServiceReference<ScopePrototypeService> ref = bundleContext.getServiceReference(ScopePrototypeService.class);
+        assertNotNull(ref);
 
-        assertSame(serviceFactory1, bundleContext.getService(
-                bundleContext.getServiceReference(ServiceFactory1.class.getName())));
+        ScopePrototypeService instance1 = bundleContext.getService(ref);
+        assertNotNull(instance1);
+
+        ScopePrototypeService instance2 = bundleContext.getService(ref);
+        assertNotNull(instance2);
+
+        assertNotSame(instance1, instance2);
+        assertTrue(instance2.getInstanceId() > instance1.getInstanceId());
     }
 
     @Test
-    public void testServiceFactoryViaManualRegistration() {
-        final ServiceFactory1 serviceFactory1 = new ServiceFactory1();
-
-        bundleContext.registerService(ServiceFactory1.class.getName(), new ServiceFactory() {
-            @Override
-            public Object getService(Bundle bundle, ServiceRegistration registration) {
-                return serviceFactory1;
-            }
-            @Override
-            public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
-                // nothing to do
-            }
-        }, null);
-
-        assertSame(serviceFactory1, bundleContext.getService(
-                bundleContext.getServiceReference(ServiceFactory1.class.getName())));
+    @SuppressWarnings("unchecked")
+    public void testScopePrototypeServiceFactory() {
+        MockOsgi.registerInjectActivateService(ScopePrototypeServiceFactory.class, bundleContext);
+
+        ServiceReference<ScopePrototpyeInstance> ref = (ServiceReference)bundleContext.getServiceReference(ScopePrototypeServiceFactory.class);
+        assertNotNull(ref);
+
+        ScopePrototpyeInstance instance1 = bundleContext.getService(ref);
+        assertNotNull(instance1);
+
+        ScopePrototpyeInstance instance2 = bundleContext.getService(ref);
+        assertNotNull(instance2);
+
+        assertNotSame(instance1, instance2);
+        assertTrue(instance2.getInstanceId() > instance1.getInstanceId());
     }
 
 }
diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ServiceFactory1.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ScopePrototypeService.java
similarity index 67%
rename from test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ServiceFactory1.java
rename to test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ScopePrototypeService.java
index 3fcbef7..199ed3a 100644
--- a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ServiceFactory1.java
+++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ScopePrototypeService.java
@@ -18,9 +18,20 @@
  */
 package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
 
+import java.util.concurrent.atomic.AtomicLong;
+
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ServiceScope;
+
+@Component(service = ScopePrototypeService.class, scope = ServiceScope.PROTOTYPE)
+public class ScopePrototypeService {
+
+    private static final AtomicLong INSTANCE_COUNTER = new AtomicLong();
+
+    private final long instanceId = INSTANCE_COUNTER.incrementAndGet();
 
-@Component(service = ServiceFactory1.class, servicefactory = true)
-public class ServiceFactory1 {
+    public long getInstanceId() {
+        return instanceId;
+    }
 
 }
diff --git a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ScopePrototypeServiceFactory.java b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ScopePrototypeServiceFactory.java
new file mode 100644
index 0000000..31744f1
--- /dev/null
+++ b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/ScopePrototypeServiceFactory.java
@@ -0,0 +1,60 @@
+/*
+ * 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.testsvc.osgiserviceutil;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ScopePrototypeServiceFactory.ScopePrototpyeInstance;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ServiceScope;
+
+@Component(service = ScopePrototypeServiceFactory.class, scope = ServiceScope.PROTOTYPE)
+public class ScopePrototypeServiceFactory implements ServiceFactory<ScopePrototpyeInstance> {
+
+    private static final AtomicLong INSTANCE_COUNTER = new AtomicLong();
+
+    @Override
+    public ScopePrototpyeInstance getService(Bundle bundle, ServiceRegistration<ScopePrototpyeInstance> registration) {
+        return new ScopePrototpyeInstance(INSTANCE_COUNTER.incrementAndGet());
+    }
+
+    @Override
+    public void ungetService(Bundle bundle, ServiceRegistration<ScopePrototpyeInstance> registration,
+            ScopePrototpyeInstance service) {
+        // nothing to do
+    }
+
+    public static class ScopePrototpyeInstance {
+
+        private final long instanceId;
+
+        private ScopePrototpyeInstance(long instanceId) {
+            this.instanceId = instanceId;
+        }
+
+        public long getInstanceId() {
+            return instanceId;
+        }
+
+    }
+
+}