You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2021/04/01 21:56:49 UTC

[sling-whiteboard] branch master updated: Fixed the issue with unit tests.

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

andysch pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new b3f734e  Fixed the issue with unit tests.
b3f734e is described below

commit b3f734e8aa911bbf0e892cc57b80c30d9ab1d8c0
Author: Andreas Schaefer <sc...@me.com>
AuthorDate: Thu Apr 1 14:56:35 2021 -0700

    Fixed the issue with unit tests.
    
    Adjusted the filtering and revamped the listener handling.
---
 .../api/DeclarativeDynamicResourceProvider.java    |  3 +-
 .../DeclarativeDynamicResourceManagerService.java  | 58 +++++++------
 .../DeclarativeDynamicResourceProviderHandler.java | 34 ++++----
 .../main/java/org/apache/sling/ddr/core/Utils.java | 52 ++++++++++++
 ...clarativeDynamicResourceManagerService-ddr.json |  7 ++
 ...clarativeDynamicResourceManagerServiceTest.java | 94 +++++++++++++++-------
 ...larativeDynamicResourceProviderHandlerTest.java | 20 +++++
 .../resources/ddr-filter/ddr-apps-settings.json    |  6 ++
 .../resources/ddr-filter/ddr-conf-settings.json    | 28 +++++++
 .../resources/ddr-sources/ddr-apps-settings.json   |  6 ++
 10 files changed, 231 insertions(+), 77 deletions(-)

diff --git a/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java b/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java
index 7f427d8..281c397 100644
--- a/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java
+++ b/org.apache.sling.ddr/api/src/main/java/org/apache/sling/ddr/api/DeclarativeDynamicResourceProvider.java
@@ -19,6 +19,7 @@ package org.apache.sling.ddr.api;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.osgi.framework.Bundle;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -37,7 +38,7 @@ public interface DeclarativeDynamicResourceProvider {
      */
     long registerService(
         Bundle bundle, String targetRootPath, String providerRootPath, ResourceResolverFactory resourceResolverFactory,
-        Map<String, String> allowedDDRFilter, Map<String, String> prohibitedDDRFilter
+        Map<String, List<String>> allowedDDRFilter, Map<String, List<String>> prohibitedDDRFilter
     );
 
     /** Remove the Registration of this Service **/
diff --git a/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerService.java b/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerService.java
index 289ce7a..8f2dda3 100644
--- a/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerService.java
+++ b/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerService.java
@@ -44,17 +44,19 @@ import javax.jcr.observation.Event;
 import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.EventListener;
 import javax.jcr.query.Query;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import static org.apache.sling.ddr.api.Constants.CONFIGURATION_ROOT_PATH;
 import static org.apache.sling.ddr.api.Constants.DDR_NODE_TYPE;
 import static org.apache.sling.ddr.api.Constants.DDR_TARGET_PROPERTY_NAME;
 import static org.apache.sling.ddr.api.Constants.DYNAMIC_COMPONENTS_SERVICE_USER;
 import static org.apache.sling.ddr.api.Constants.EQUALS;
-import static org.apache.sling.ddr.api.Constants.JCR_PRIMARY_TYPE;
-import static org.apache.sling.ddr.api.Constants.REP_POLICY;
 
 @Component(
     service = { DeclarativeDynamicResourceManager.class, EventListener.class },
@@ -75,7 +77,7 @@ public class DeclarativeDynamicResourceManagerService
         @AttributeDefinition(
             name = "Prohibited DDR Filter",
             description="Prohibited Resources to become a DDR in a format of: <property name>=<property value>. Any matching entry is prohibited.")
-        String[] prohibited_ddr_filter() default { "sling:resourceType=nt:file", "sling:resourceType=nt:resource" };
+        String[] prohibited_ddr_filter();
     }
 
     public static final int EVENT_TYPES =
@@ -89,11 +91,9 @@ public class DeclarativeDynamicResourceManagerService
     public static final String[] NODE_TYPES = new String[] { DDR_NODE_TYPE };
 
     @Reference
-//    private ResourceResolverFactory resourceResolverFactory;
     ResourceResolverFactory resourceResolverFactory;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL)
-//    private DeclarativeDynamicResourceListener dynamicComponentFilterNotifier;
     DeclarativeDynamicResourceListener dynamicComponentFilterNotifier;
 
     // Make sure that the Service User Mapping is available before obtaining the Service Resource Resolver
@@ -107,8 +107,8 @@ public class DeclarativeDynamicResourceManagerService
     // Keep the Resource Resolver around otherwise the Event Listener will not work anymore
     private ResourceResolver resourceResolver;
 
-    private Map<String, String> allowedFilter = new HashMap<>();
-    private Map<String, String> prohibitedFilter = new HashMap<>();
+    private Map<String, List<String>> allowedFilter = new HashMap<>();
+    private Map<String, List<String>> prohibitedFilter = new HashMap<>();
 
     @Activate
     void activate(BundleContext bundleContext, Configuration configuration) {
@@ -155,14 +155,21 @@ public class DeclarativeDynamicResourceManagerService
         }
     }
 
-    private void handleDDRFilter(String[] filters, Map<String,String> filterMap) {
+    private void handleDDRFilter(String[] filters, Map<String, List<String>> filterMap) {
         if(filters != null && filters.length > 0) {
             for(String filter: filters) {
                 int index = filter.indexOf('=');
                 if(index > 0 && index < filter.length() - 1) {
                     String name = filter.substring(0, index);
                     String value = filter.substring(index + 1);
-                    filterMap.put(name, value);
+                    List<String> values = filterMap.get(name);
+                    if(values == null) {
+                        values = new ArrayList<>();
+                        filterMap.put(name, values);
+                    }
+                    if(!values.contains(value)) {
+                        values.add(value);
+                    }
                 }
             }
         }
@@ -184,23 +191,9 @@ public class DeclarativeDynamicResourceManagerService
                     );
                     log.info("After Registering Tenant RP: service: '{}', id: '{}'", service, id);
                     registeredServices.put(ddrTargetResource.getPath(), service);
-                    Iterator<Resource> i = ddrSourceResource.listChildren();
-                    while (i.hasNext()) {
-                        Resource provided = i.next();
-                        String componentName = provided.getName();
-                        if (componentName.equals(REP_POLICY)) {
-                            continue;
-                        }
-                        log.info("Provided Dynamic: '{}'", provided);
-                        ValueMap childProperties = provided.getValueMap();
-                        String primaryType = childProperties.get(JCR_PRIMARY_TYPE, String.class);
-                        log.info("Dynamic Child Source: '{}', Primary Type: '{}'", componentName, primaryType);
-                        if (componentName != null && !componentName.isEmpty() && dynamicComponentFilterNotifier != null) {
-                            dynamicComponentFilterNotifier.addDeclarativeDynamicResource(
-                                ddrTargetPath + '/' + componentName, provided
-                            );
-                        }
-                    }
+                    dynamicComponentFilterNotifier.addDeclarativeDynamicResource(
+                        ddrTargetPath, ddrSourceResource
+                    );
                 }
             }
         }
@@ -219,10 +212,11 @@ public class DeclarativeDynamicResourceManagerService
 
     @Deactivate
     private void deactivate() {
-        for(DeclarativeDynamicResourceProvider service: registeredServices.values()) {
-            log.info("Before UnRegistering Tenant RP, service: '{}'", service);
-            service.unregisterService();
-            log.info("After UnRegistering Tenant RP, service: '{}'", service);
+        for(Entry<String, DeclarativeDynamicResourceProvider> entry: registeredServices.entrySet()) {
+            log.info("Before UnRegistering Tenant RP, service: '{}'", entry.getValue());
+            entry.getValue().unregisterService();
+            dynamicComponentFilterNotifier.removeDynamicDeclarativeResource(entry.getKey());
+            log.info("After UnRegistering Tenant RP, service: '{}'", entry.getValue());
         }
         if(resourceResolver != null) {
             resourceResolver.close();
@@ -266,5 +260,9 @@ public class DeclarativeDynamicResourceManagerService
             log.error("Failed to Handle Events", e);
         }
     }
+
+    Map<String, DeclarativeDynamicResourceProvider> getRegisteredServices() {
+        return Collections.unmodifiableMap(registeredServices);
+    }
 }
 
diff --git a/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandler.java b/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandler.java
index e80d005..7b5c061 100644
--- a/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandler.java
+++ b/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandler.java
@@ -69,14 +69,14 @@ public class DeclarativeDynamicResourceProviderHandler
     private String providerRootPath;
     private boolean active;
     private ResourceResolverFactory resourceResolverFactory;
-    private Map<String, String> allowedDDRFilter;
-    private Map<String, String> prohibitedDDRFilter;
+    private Map<String, List<String>> allowedDDRFilter;
+    private Map<String, List<String>> prohibitedDDRFilter;
 
     //---------- Service Registration
 
     public long registerService(
         Bundle bundle, String targetRootPath, String providerRootPath, ResourceResolverFactory resourceResolverFactory,
-        Map<String, String> allowedDDRFilter, Map<String, String> prohibitedDDRFilter
+        Map<String, List<String>> allowedDDRFilter, Map<String, List<String>> prohibitedDDRFilter
     ) {
         this.targetRootPath = targetRootPath;
         this.providerRootPath = providerRootPath;
@@ -278,29 +278,25 @@ public class DeclarativeDynamicResourceProviderHandler
         super.stop();
     }
 
-    private boolean filterSource(Resource source) {
-        if(allowedDDRFilter.isEmpty() && prohibitedDDRFilter.isEmpty()) {
-            return true;
-        }
-        if(source == null) {
-            return false;
-        }
+    boolean filterSource(Resource source) {
+        if(allowedDDRFilter.isEmpty() && prohibitedDDRFilter.isEmpty()) { return true; }
+        if(source == null) { return false; }
         ValueMap properties = source.getValueMap();
         if(!allowedDDRFilter.isEmpty()) {
-            for(Entry<String,String> filter: allowedDDRFilter.entrySet()) {
+            for (Entry<String, List<String>> filter : allowedDDRFilter.entrySet()) {
                 String propertyValue = properties.get(filter.getKey(), String.class);
-                if(propertyValue != null) {
-                    if(!filter.getValue().equals(propertyValue)) {
+                if (propertyValue != null) {
+                    if (!filter.getValue().contains(propertyValue)) {
                         return false;
                     }
                 }
             }
-            for(Entry<String,String> filter: prohibitedDDRFilter.entrySet()) {
-                String propertyValue = properties.get(filter.getKey(), String.class);
-                if(propertyValue != null) {
-                    if(filter.getValue().equals(propertyValue)) {
-                        return false;
-                    }
+        }
+        for(Entry<String,List<String>> filter: prohibitedDDRFilter.entrySet()) {
+            String propertyValue = properties.get(filter.getKey(), String.class);
+            if(propertyValue != null) {
+                if(filter.getValue().contains(propertyValue)) {
+                    return false;
                 }
             }
         }
diff --git a/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/Utils.java b/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/Utils.java
new file mode 100644
index 0000000..33dbdd3
--- /dev/null
+++ b/org.apache.sling.ddr/core/src/main/java/org/apache/sling/ddr/core/Utils.java
@@ -0,0 +1,52 @@
+/*
+ * 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.ddr.core;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class Utils {
+
+//    public static boolean filterSource(Map<String, List<String>> allowedDDRFilter, Map<String, List<String>> prohibitedDDRFilter, Resource source) {
+//        if(allowedDDRFilter.isEmpty() && prohibitedDDRFilter.isEmpty()) { return true; }
+//        if(source == null) { return false; }
+//        ValueMap properties = source.getValueMap();
+//        if(!allowedDDRFilter.isEmpty()) {
+//            for (Entry<String, List<String>> filter : allowedDDRFilter.entrySet()) {
+//                String propertyValue = properties.get(filter.getKey(), String.class);
+//                if (propertyValue != null) {
+//                    if (!filter.getValue().contains(propertyValue)) {
+//                        return false;
+//                    }
+//                }
+//            }
+//        }
+//        for(Entry<String,List<String>> filter: prohibitedDDRFilter.entrySet()) {
+//            String propertyValue = properties.get(filter.getKey(), String.class);
+//            if(propertyValue != null) {
+//                if(filter.getValue().contains(propertyValue)) {
+//                    return false;
+//                }
+//            }
+//        }
+//        return true;
+//    }
+}
diff --git a/org.apache.sling.ddr/core/src/main/resources/SLING-CONTENT/apps/ddr/config/org.apache.sling.ddr.core.DeclarativeDynamicResourceManagerService-ddr.json b/org.apache.sling.ddr/core/src/main/resources/SLING-CONTENT/apps/ddr/config/org.apache.sling.ddr.core.DeclarativeDynamicResourceManagerService-ddr.json
new file mode 100644
index 0000000..b22b31a
--- /dev/null
+++ b/org.apache.sling.ddr/core/src/main/resources/SLING-CONTENT/apps/ddr/config/org.apache.sling.ddr.core.DeclarativeDynamicResourceManagerService-ddr.json
@@ -0,0 +1,7 @@
+{
+  "allowed.ddr.filter": [],
+  "prohibited.ddr.filter": [
+    "sling:resourceType=nt:file",
+    "sling:resourceType=nt:resource"
+  ]
+}
\ No newline at end of file
diff --git a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java
index c9b45c6..0845f85 100644
--- a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java
+++ b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceManagerServiceTest.java
@@ -40,6 +40,8 @@ import org.slf4j.LoggerFactory;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.query.Query;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -53,6 +55,7 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.Silent.class)
@@ -72,13 +75,16 @@ public class DeclarativeDynamicResourceManagerServiceTest {
 
     private ResourceResolver resourceResolver;
 
+    private final Map<String, Resource> ddrMap = new HashMap<>();
+
     @Before
     public void setup() throws LoginException, RepositoryException {
-        resourceResolver = context.resourceResolver();
+        resourceResolver = spy(context.resourceResolver());
         log.info("Adapt Context-RR: '{}' to Session: '{}'", resourceResolver, resourceResolver.adaptTo(Session.class));
         when(resourceResolverFactory.getServiceResourceResolver(any(Map.class)))
             .thenReturn(resourceResolver);
         declarativeDynamicResourceManagerService.resourceResolverFactory = resourceResolverFactory;
+        declarativeDynamicResourceManagerService.dynamicComponentFilterNotifier = declarativeDynamicResourceListener;
 
         try {
             NodeTypeDefinitionScanner.get().register(context.resourceResolver().adaptTo(Session.class),
@@ -100,46 +106,80 @@ public class DeclarativeDynamicResourceManagerServiceTest {
 
         log.info("Before Loading Test Resources");
         context.load().json("/ddr-sources/ddr-conf-settings.json", "/conf");
+        context.load().json("/ddr-sources/ddr-apps-settings.json", "/apps");
         log.info("After Loading Test Resources");
         Resource sourceRoot = resourceResolver.getResource("/conf/test/settings/dynamic");
         log.info("Dynamic Test Resource Root: '{}'", sourceRoot);
-        Iterator<Resource> i = resourceResolver.findResources(
-            "SELECT * FROM [" + DDR_NODE_TYPE + "]",
-            Query.JCR_SQL2
+        when(resourceResolver.findResources(anyString(), anyString())).thenReturn(
+            Arrays.asList(sourceRoot).iterator()
         );
-        log.info("(TEST) DDR Nodes by Type: '{}', has next: '{}'", i, i.hasNext());
 
         // Listen to newly created DDRs
-        final Map<String, Resource> ddrMap = new HashMap<>();
-        doAnswer(
-            new Answer<Object>() {
-                @Override
-                public Object answer(InvocationOnMock invocation) throws Throwable {
-                    String dynamicPath = invocation.getArgument(0);
-                    Resource source = invocation.getArgument(1);
-                    ddrMap.put(dynamicPath, source);
-                    return null;
-                }
-            }
-        ).when(declarativeDynamicResourceListener).addDeclarativeDynamicResource(anyString(), any(Resource.class));
+        doAnswer(new ListenerAnswer()).when(declarativeDynamicResourceListener).addDeclarativeDynamicResource(anyString(), any(Resource.class));
 
         // Test a basic, already installed configuration
-        final DeclarativeDynamicResourceManagerService.Configuration configuration = mock(DeclarativeDynamicResourceManagerService.Configuration.class);
-        when(configuration.allowed_ddr_filter()).thenReturn(new String[] {});
-        when(configuration.prohibited_ddr_filter()).thenReturn(new String[] {});
         log.info("DDR-Manager Service: '{}'", declarativeDynamicResourceManagerService);
-        declarativeDynamicResourceManagerService.activate(context.bundleContext(), configuration);
+        declarativeDynamicResourceManagerService.activate(context.bundleContext(), createConfiguration(null, null));
 
 // The Query for Node Type sling:DDR will not return even though a Resource is there
+        assertFalse("No DDR Registered", ddrMap.isEmpty());
+        assertEquals("More than one DDR Registered", 1, ddrMap.size());
+        Entry<String, Resource> entry = ddrMap.entrySet().iterator().next();
+        assertEquals("Wrong DDR Dynamic Path", dynamicResourceRoot, entry.getKey());
+        Resource source = entry.getValue();
+        assertEquals("Wrong DDR Source Path", confResourceRoot, source.getPath());
+    }
+
+//    @Test
+//    public void testFilters() throws Exception {
+//        String resourceName = "test1";
+//        String confResourceRoot = "/conf/testFilter/settings/dynamic";
+//        String dynamicResourceRoot = "/apps/dynamicFilter";
+////        final String testPropertyKey = "jcr:title";
+////        final String testPropertyValue = "Test-1";
+//
+//        log.info("Before Loading Test Resources");
+//        context.load().json("/ddr-filter/ddr-conf-settings.json", "/conf");
+//        context.load().json("/ddr-filter/ddr-apps-settings.json", "/apps");
+//        log.info("After Loading Test Resources");
+//        Resource sourceRoot = resourceResolver.getResource("/conf/testFilter/settings/dynamic");
+//        log.info("Dynamic Test Resource Root: '{}'", sourceRoot);
+//        when(resourceResolver.findResources(anyString(), anyString())).thenReturn(
+//            Arrays.asList(sourceRoot).iterator()
+//        );
+//
+//        // Listen to newly created DDRs
+//        doAnswer(new ListenerAnswer()).when(declarativeDynamicResourceListener).addDeclarativeDynamicResource(anyString(), any(Resource.class));
+//
+//        // Test a basic, already installed configuration
+//        log.info("DDR-Manager Service: '{}'", declarativeDynamicResourceManagerService);
+//        declarativeDynamicResourceManagerService.activate(context.bundleContext(), createConfiguration(
+//            null, new String[] {"sling:resourceType=nt:file", "sling:resourceType=nt:resource"}));
+//
+//// The Query for Node Type sling:DDR will not return even though a Resource is there
 //        assertFalse("No DDR Registered", ddrMap.isEmpty());
-//        assertEquals("More than one DDR Registered", 1, ddrMap.size());
+//        assertEquals("Only one DDR should be Registered", 1, ddrMap.size());
 //        Entry<String, Resource> entry = ddrMap.entrySet().iterator().next();
 //        assertEquals("Wrong DDR Dynamic Path", dynamicResourceRoot + "/" + resourceName, entry.getKey());
 //        Resource source = entry.getValue();
-//        assertEquals("Wrong DDR Source Path", confResourceRoot, source.getPath());
-//        ValueMap properties = source.getValueMap();
-//        String testProperty = properties.get(testPropertyKey, String.class);
-//        assertNotNull("Test Property not found", testProperty);
-//        assertEquals("Wrong Test Property Value", testPropertyValue, testProperty);
+//        assertEquals("Wrong DDR Source Path", confResourceRoot + "/" + resourceName, source.getPath());
+//    }
+
+    private DeclarativeDynamicResourceManagerService.Configuration createConfiguration(String[] allowed, String[] prohibited) {
+        final DeclarativeDynamicResourceManagerService.Configuration configuration = mock(DeclarativeDynamicResourceManagerService.Configuration.class);
+        when(configuration.allowed_ddr_filter()).thenReturn(allowed == null ? new String[] {}: allowed);
+        when(configuration.prohibited_ddr_filter()).thenReturn(prohibited == null ? new String[] {}: prohibited);
+        log.info("DDR-Manager Service: '{}'", declarativeDynamicResourceManagerService);
+        return configuration;
+    }
+
+    private class ListenerAnswer implements Answer {
+        @Override
+        public Object answer(InvocationOnMock invocation) throws Throwable {
+            String dynamicPath = invocation.getArgument(0);
+            Resource source = invocation.getArgument(1);
+            ddrMap.put(dynamicPath, source);
+            return null;
+        }
     }
 }
diff --git a/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandlerTest.java b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandlerTest.java
new file mode 100644
index 0000000..0c9a8ad
--- /dev/null
+++ b/org.apache.sling.ddr/core/src/test/java/org/apache/sling/ddr/core/DeclarativeDynamicResourceProviderHandlerTest.java
@@ -0,0 +1,20 @@
+/*
+ * 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.ddr.core;
+
+public class DeclarativeDynamicResourceProviderHandlerTest {
+}
diff --git a/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-apps-settings.json b/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-apps-settings.json
new file mode 100644
index 0000000..363671a
--- /dev/null
+++ b/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-apps-settings.json
@@ -0,0 +1,6 @@
+{
+  "sling:resourceType": "sling:Folder",
+  "dynamicFilter": {
+    "sling:resourceType": "sling:Folder"
+  }
+}
\ No newline at end of file
diff --git a/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-conf-settings.json b/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-conf-settings.json
new file mode 100644
index 0000000..26309ed
--- /dev/null
+++ b/org.apache.sling.ddr/core/src/test/resources/ddr-filter/ddr-conf-settings.json
@@ -0,0 +1,28 @@
+{
+  "sling:resourceType": "sling:Folder",
+  "testFilter": {
+    "sling:resourceType": "sling:Folder",
+    "settings": {
+      "sling:resourceType": "sling:Folder",
+      "dynamic": {
+        "sling:resourceType": "sling:DDR",
+        "sling:ddrTarget": "/apps/dynamicFilter",
+        "test1": {
+          "sling:resourceType": "test/conf",
+          "sling:resourceSuperType": "test/static",
+          "jcr:title": "Test-1"
+        },
+        "test2": {
+          "sling:resourceType": "nt:file",
+          "sling:resourceSuperType": "test/static",
+          "jcr:title": "Test-2"
+        },
+        "test3": {
+          "sling:resourceType": "nt:resource",
+          "sling:resourceSuperType": "test/static",
+          "jcr:title": "Test-3"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/org.apache.sling.ddr/core/src/test/resources/ddr-sources/ddr-apps-settings.json b/org.apache.sling.ddr/core/src/test/resources/ddr-sources/ddr-apps-settings.json
new file mode 100644
index 0000000..080f27f
--- /dev/null
+++ b/org.apache.sling.ddr/core/src/test/resources/ddr-sources/ddr-apps-settings.json
@@ -0,0 +1,6 @@
+{
+  "sling:resourceType": "sling:Folder",
+  "dynamic": {
+    "sling:resourceType": "sling:Folder"
+  }
+}
\ No newline at end of file