You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2016/10/24 13:22:25 UTC

svn commit: r1766404 - in /sling/trunk/bundles/scripting/core: ./ src/main/java/org/apache/sling/scripting/core/impl/ src/test/java/org/apache/sling/scripting/core/impl/

Author: radu
Date: Mon Oct 24 13:22:24 2016
New Revision: 1766404

URL: http://svn.apache.org/viewvc?rev=1766404&view=rev
Log:
SLING-6165 - Expose a service for Sling Scripting that provides request-scoped Resource Resolvers for scripting dependencies

* made sure the resource resolver is removed from thread local when the request is destroyed
* added unit tests

Added:
    sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImplTest.java
    sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverTest.java
Modified:
    sling/trunk/bundles/scripting/core/pom.xml
    sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImpl.java

Modified: sling/trunk/bundles/scripting/core/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/pom.xml?rev=1766404&r1=1766403&r2=1766404&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/core/pom.xml (original)
+++ sling/trunk/bundles/scripting/core/pom.xml Mon Oct 24 13:22:24 2016
@@ -193,11 +193,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.jmock</groupId>
-            <artifactId>jmock-junit4</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-simple</artifactId>
             <scope>test</scope>
@@ -265,6 +260,13 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.9.5</version>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.eventadmin</artifactId>

Modified: sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImpl.java?rev=1766404&r1=1766403&r2=1766404&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImpl.java (original)
+++ sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImpl.java Mon Oct 24 13:22:24 2016
@@ -97,6 +97,7 @@ public class ScriptingResourceResolverFa
             ScriptingResourceResolver scriptingResourceResolver = perThreadResourceResolver.get();
             if (scriptingResourceResolver != null) {
                 scriptingResourceResolver._close();
+                perThreadResourceResolver.remove();
             }
             if (LOGGER.isDebugEnabled()) {
                 LOGGER.debug("Removing per thread resource resolver for thread {}.", Thread.currentThread().getName());

Added: sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImplTest.java?rev=1766404&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImplTest.java (added)
+++ sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverFactoryImplTest.java Mon Oct 24 13:22:24 2016
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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.scripting.core.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+
+import org.apache.sling.api.request.SlingRequestEvent;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.junit.Test;
+import org.mockito.internal.util.reflection.Whitebox;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.*;
+
+public class ScriptingResourceResolverFactoryImplTest {
+
+    private static final int MAX_CONCURRENT_RESOLVERS = 100;
+
+    @Test
+    public void testGetRequestScopedResourceResolver() throws Exception {
+        ResourceResolverFactory rrf = mock(ResourceResolverFactory.class);
+        ResourceResolver delegate = mock(ResourceResolver.class);
+        when(delegate.getUserID()).thenReturn("sling-scripting");
+        when(rrf.getServiceResourceResolver(null)).thenReturn(delegate);
+        ScriptingResourceResolverFactoryImpl scriptingResourceResolverFactory = new ScriptingResourceResolverFactoryImpl();
+        Whitebox.setInternalState(scriptingResourceResolverFactory, "rrf", rrf);
+        assertNull(scriptingResourceResolverFactory.getRequestScopedResourceResolver());
+        SlingRequestEvent sre1 = new SlingRequestEvent(mock(ServletContext.class), mock(ServletRequest.class), SlingRequestEvent.EventType
+                .EVENT_INIT);
+        scriptingResourceResolverFactory.onEvent(sre1);
+        ResourceResolver resourceResolver = scriptingResourceResolverFactory.getRequestScopedResourceResolver();
+        assertEquals("sling-scripting", resourceResolver.getUserID());
+        SlingRequestEvent sre2 = new SlingRequestEvent(mock(ServletContext.class), mock(ServletRequest.class), SlingRequestEvent.EventType
+                .EVENT_DESTROY);
+        scriptingResourceResolverFactory.onEvent(sre2);
+        assertNull(scriptingResourceResolverFactory.getRequestScopedResourceResolver());
+        verify(delegate).close();
+    }
+
+    @Test
+    public void testGetRequestScopedResourceResolverWithThreads() throws Exception {
+        ResourceResolverFactory rrf = mock(ResourceResolverFactory.class);
+        final Set<ResourceResolver> delegates = new HashSet<>();
+        when(rrf.getServiceResourceResolver(null)).thenAnswer(new Answer<ResourceResolver>() {
+            @Override
+            public ResourceResolver answer(InvocationOnMock invocation) throws Throwable {
+                ResourceResolver delegate = getMockedRR();
+                delegates.add(delegate);
+                return delegate;
+            }
+        });
+        final ScriptingResourceResolverFactoryImpl scriptingResourceResolverFactory = new ScriptingResourceResolverFactoryImpl();
+        Whitebox.setInternalState(scriptingResourceResolverFactory, "rrf", rrf);
+        Collection<Callable<ResourceResolver>> callables = new ArrayList<>(MAX_CONCURRENT_RESOLVERS);
+        for (int i = 0; i < MAX_CONCURRENT_RESOLVERS; i++) {
+            callables.add(createCallable(scriptingResourceResolverFactory));
+        }
+        ExecutorService executor = Executors.newFixedThreadPool(MAX_CONCURRENT_RESOLVERS);
+        List<Future<ResourceResolver>> futures = executor.invokeAll(callables);
+        Set<ResourceResolver> resolvers = new HashSet<>();
+        for (Future<ResourceResolver> future : futures) {
+            resolvers.add(future.get());
+        }
+        assertEquals(MAX_CONCURRENT_RESOLVERS, resolvers.size());
+        assertEquals(MAX_CONCURRENT_RESOLVERS, delegates.size());
+        for (ResourceResolver delegate : delegates) {
+            verify(delegate).close();
+        }
+
+    }
+
+    private Callable<ResourceResolver> createCallable(final ScriptingResourceResolverFactoryImpl scriptingResourceResolverFactory) {
+        return new Callable<ResourceResolver>() {
+            @Override
+            public ResourceResolver call() throws Exception {
+                try {
+                    scriptingResourceResolverFactory.onEvent(new SlingRequestEvent(mock(ServletContext.class), mock(ServletRequest.class),
+                            SlingRequestEvent.EventType.EVENT_INIT));
+                    return scriptingResourceResolverFactory.getRequestScopedResourceResolver();
+                } finally {
+                    scriptingResourceResolverFactory.onEvent(new SlingRequestEvent(mock(ServletContext.class), mock(ServletRequest.class),
+                            SlingRequestEvent.EventType.EVENT_DESTROY));
+                    assertNull(scriptingResourceResolverFactory.getRequestScopedResourceResolver());
+                }
+            }
+        };
+    }
+
+    private ResourceResolver getMockedRR() {
+        ResourceResolver resolver = mock(ResourceResolver.class);
+        when(resolver.getUserID()).thenReturn("sling-scripting");
+        return resolver;
+    }
+
+}

Added: sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverTest.java?rev=1766404&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverTest.java (added)
+++ sling/trunk/bundles/scripting/core/src/test/java/org/apache/sling/scripting/core/impl/ScriptingResourceResolverTest.java Mon Oct 24 13:22:24 2016
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * 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.scripting.core.impl;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.*;
+
+@SuppressWarnings({"unchecked", "deprecation"})
+public class ScriptingResourceResolverTest {
+
+    private static final String PATH = "path";
+    public static final String QUERY = "query";
+    public static final String LANGUAGE = "language";
+    private static ScriptingResourceResolver scriptingResourceResolver;
+    private static ResourceResolver delegate = mock(ResourceResolver.class);
+    private static ResourceResolver delegateClone = mock(ResourceResolver.class);
+    private static final String[] searchPaths = {"/apps", "/libs"};
+
+    @BeforeClass
+    public static void setUpTestSuite() throws LoginException {
+        when(delegate.clone(null)).thenReturn(delegateClone);
+        when(delegateClone.getSearchPath()).thenReturn(searchPaths);
+        scriptingResourceResolver = new ScriptingResourceResolver(false, delegate);
+    }
+
+    @Test
+    public void testResolve() throws Exception {
+        final HttpServletRequest request = mock(HttpServletRequest.class);
+        final Resource result = mock(Resource.class);
+        when(delegate.resolve(request, PATH)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.resolve(request, PATH));
+        verify(delegate).resolve(request, PATH);
+    }
+
+    @Test
+    public void testResolve1() throws Exception {
+        final HttpServletRequest request = mock(HttpServletRequest.class);
+        final Resource result = mock(Resource.class);
+        when(delegate.resolve(request)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.resolve(request));
+        verify(delegate).resolve(request);
+    }
+
+    @Test
+    public void testResolve2() throws Exception {
+        final Resource result = mock(Resource.class);
+        when(delegate.resolve(PATH)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.resolve(PATH));
+        verify(delegate).resolve(PATH);
+    }
+
+    @Test
+    public void testMap() throws Exception {
+        when(delegate.map(PATH)).thenReturn(PATH);
+        assertEquals(PATH, scriptingResourceResolver.map(PATH));
+        verify(delegate).map(PATH);
+    }
+
+    @Test
+    public void testMap1() throws Exception {
+        final HttpServletRequest request = mock(HttpServletRequest.class);
+        when(delegate.map(request, PATH)).thenReturn(PATH);
+        assertEquals(PATH, scriptingResourceResolver.map(request, PATH));
+        verify(delegate).map(request, PATH);
+    }
+
+    @Test
+    public void testGetResource() throws Exception {
+        final Resource result = mock(Resource.class);
+        when(delegate.getResource(PATH)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.getResource(PATH));
+        verify(delegate).getResource(PATH);
+    }
+
+    @Test
+    public void testGetResource1() throws Exception {
+        final Resource result = mock(Resource.class);
+        final Resource base = mock(Resource.class);
+        when(delegate.getResource(base, PATH)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.getResource(base, PATH));
+        verify(delegate).getResource(base, PATH);
+    }
+
+    @Test
+    public void testGetSearchPath() throws Exception {
+        when(delegate.getSearchPath()).thenReturn(searchPaths);
+        assertArrayEquals(searchPaths, scriptingResourceResolver.getSearchPath());
+        verify(delegate).getSearchPath();
+    }
+
+    @Test
+    public void testListChildren() throws Exception {
+        final Iterator<Resource> resourceIterator = mock(Iterator.class);
+        final Resource base = mock(Resource.class);
+        when(delegate.listChildren(base)).thenReturn(resourceIterator);
+        assertEquals(resourceIterator, scriptingResourceResolver.listChildren(base));
+        verify(delegate).listChildren(base);
+    }
+
+    @Test
+    public void testGetParent() throws Exception {
+        final Resource parent = mock(Resource.class);
+        final Resource base = mock(Resource.class);
+        when(delegate.getParent(base)).thenReturn(parent);
+        assertEquals(parent, scriptingResourceResolver.getParent(base));
+        verify(delegate).getParent(base);
+    }
+
+    @Test
+    public void testGetChildren() throws Exception {
+        final List<Resource> children = mock(List.class);
+        final Resource base = mock(Resource.class);
+        when(delegate.getChildren(base)).thenReturn(children);
+        assertEquals(children, scriptingResourceResolver.getChildren(base));
+        verify(delegate).getChildren(base);
+    }
+
+    @Test
+    public void testFindResources() throws Exception {
+        final Iterator<Resource> result = mock(Iterator.class);
+        when(delegate.findResources(QUERY, LANGUAGE)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.findResources(QUERY, LANGUAGE));
+        verify(delegate).findResources(QUERY, LANGUAGE);
+    }
+
+    @Test
+    public void testQueryResources() throws Exception {
+        final Iterator<Map<String, Object>> result = mock(Iterator.class);
+        when(delegate.queryResources(QUERY, LANGUAGE)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.queryResources(QUERY, LANGUAGE));
+        verify(delegate).queryResources(QUERY, LANGUAGE);
+    }
+
+    @Test
+    public void testHasChildren() throws Exception {
+        final Resource base = mock(Resource.class);
+        when(delegate.hasChildren(base)).thenReturn(true);
+        assertTrue(scriptingResourceResolver.hasChildren(base));
+        verify(delegate).hasChildren(base);
+    }
+
+    @Test
+    public void testClone() throws Exception {
+        final Map<String, Object> authenticationInfo = mock(Map.class);
+        final ResourceResolver result = scriptingResourceResolver.clone(authenticationInfo);
+        assertTrue(result instanceof ScriptingResourceResolver);
+        final ScriptingResourceResolver resultS = (ScriptingResourceResolver) result;
+        assertArrayEquals(searchPaths, resultS.getSearchPath());
+        verify(delegateClone).getSearchPath();
+    }
+
+    @Test
+    public void testIsLive() throws Exception {
+        when(delegate.isLive()).thenReturn(true);
+        assertTrue(scriptingResourceResolver.isLive());
+        verify(delegate).isLive();
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        scriptingResourceResolver.close();
+        verify(delegate, times(0)).close();
+    }
+
+    @Test
+    public void test_close() throws Exception {
+        scriptingResourceResolver._close();
+        verify(delegate).close();
+    }
+
+    @Test
+    public void testGetUserID() throws Exception {
+        when(delegate.getUserID()).thenReturn("sling-scripting");
+        assertEquals("sling-scripting", scriptingResourceResolver.getUserID());
+        verify(delegate).getUserID();
+    }
+
+    @Test
+    public void testGetAttributeNames() throws Exception {
+        final Iterator<String> result = mock(Iterator.class);
+        when(delegate.getAttributeNames()).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.getAttributeNames());
+        verify(delegate).getAttributeNames();
+    }
+
+    @Test
+    public void testGetAttribute() throws Exception {
+        final String attributeName = "attributeName";
+        final String attributeValue = "attributeValue";
+        when(delegate.getAttribute(attributeName)).thenReturn(attributeValue);
+        assertEquals(attributeValue, scriptingResourceResolver.getAttribute(attributeName));
+        verify(delegate).getAttribute(attributeName);
+    }
+
+    @Test
+    public void testDelete() throws Exception {
+        final Resource resource = mock(Resource.class);
+        scriptingResourceResolver.delete(resource);
+        verify(delegate).delete(resource);
+    }
+
+    @Test
+    public void testCreate() throws Exception {
+        final Resource parent = mock(Resource.class);
+        final Map<String, Object> properties = mock(Map.class);
+        final Resource result = mock(Resource.class);
+        when(delegate.create(parent, PATH, properties)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.create(parent, PATH, properties));
+        verify(delegate).create(parent, PATH, properties);
+    }
+
+    @Test
+    public void testRevert() throws Exception {
+        scriptingResourceResolver.revert();
+        verify(delegate).revert();
+    }
+
+    @Test
+    public void testCommit() throws Exception {
+        scriptingResourceResolver.commit();
+        verify(delegate).commit();
+    }
+
+    @Test
+    public void testHasChanges() throws Exception {
+        when(delegate.hasChanges()).thenReturn(true);
+        assertTrue(scriptingResourceResolver.hasChanges());
+        verify(delegate).hasChanges();
+    }
+
+    @Test
+    public void testGetParentResourceType() throws Exception {
+        final String resourceType = "a/b/c";
+        final Resource resource = mock(Resource.class);
+        when(delegate.getParentResourceType(resource)).thenReturn(resourceType);
+        assertEquals(resourceType, scriptingResourceResolver.getParentResourceType(resource));
+        verify(delegate).getParentResourceType(resource);
+    }
+
+    @Test
+    public void testGetParentResourceType1() throws Exception {
+        final String resourceType = "a/b/c";
+        when(delegate.getParentResourceType(PATH)).thenReturn(resourceType);
+        assertEquals(resourceType, scriptingResourceResolver.getParentResourceType(PATH));
+        verify(delegate).getParentResourceType(PATH);
+    }
+
+    @Test
+    public void testIsResourceType() throws Exception {
+        final Resource resource = mock(Resource.class);
+        final String resourceType = "a/b/c";
+        when(delegate.isResourceType(resource, resourceType)).thenReturn(true);
+        assertTrue(scriptingResourceResolver.isResourceType(resource, resourceType));
+        verify(delegate).isResourceType(resource, resourceType);
+    }
+
+    @Test
+    public void testRefresh() throws Exception {
+        scriptingResourceResolver.refresh();
+        verify(delegate).refresh();
+    }
+
+    @Test
+    public void testCopy() throws Exception {
+        final String source = "source";
+        final String destination = "destination";
+        final Resource result = mock(Resource.class);
+        when(delegate.copy(source, destination)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.copy(source, destination));
+        verify(delegate).copy(source, destination);
+    }
+
+    @Test
+    public void testMove() throws Exception {
+        final String source = "source";
+        final String destination = "destination";
+        final Resource result = mock(Resource.class);
+        when(delegate.move(source, destination)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.move(source, destination));
+        verify(delegate).move(source, destination);
+    }
+
+    @Test
+    public void testAdaptTo() throws Exception {
+        final String result = "result";
+        when(delegate.adaptTo(String.class)).thenReturn(result);
+        assertEquals(result, scriptingResourceResolver.adaptTo(String.class));
+        verify(delegate).adaptTo(String.class);
+    }
+}