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

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

commit 6fcdce023922b81869a1ff72a84f077e41a351cf
Author: Bertrand Delacretaz <[email protected]>
AuthorDate: Thu Jul 4 11:59:23 2019 +0200

    Using SlingRequestProcessor
---
 graalvm/README.md                                  |  11 +-
 graalvm/pom.xml                                    |  34 +++-
 .../engine/impl/SlingRequestProcessorWrapper.java  |  18 ++
 .../apache/sling/graalvm/http/SlingResource.java   |  55 ++++++
 .../apache/sling/graalvm/osgi/SlingContext.java    |  35 ++++
 .../sling/graalvm/sling/MockErrorHandler.java      |  23 +++
 .../sling/graalvm/sling/MockFilterManager.java     |  12 ++
 .../apache/sling/graalvm/sling/MockResource.java   |  54 ++++++
 .../sling/graalvm/sling/MockResourceProvider.java  |  27 +++
 .../sling/graalvm/sling/MockResourceResolver.java  | 184 +++++++++++++++++++++
 .../sling/graalvm/sling/MockServletResolver.java   |  41 +++++
 .../sling/graalvm/http/NativeSlingResourceIT.java  |   8 +
 .../sling/graalvm/http/SlingResourceTest.java      |  30 ++++
 13 files changed, 526 insertions(+), 6 deletions(-)

diff --git a/graalvm/README.md b/graalvm/README.md
index e9bf7ff..d71ea46 100644
--- a/graalvm/README.md
+++ b/graalvm/README.md
@@ -22,4 +22,13 @@ At which point the `/hello` path works:
     curl http://localhost:8080/hello
     Hello, at Mon Jul 01 17:38:00 CEST 2019
 
-To run as a Docker container see `src/main/docker/Dockerfile.native`
\ No newline at end of file
+To run as a Docker container see `src/main/docker/Dockerfile.native`
+
+## TODO
+Running in **quarkus:dev mode fails so far** ("no SCR metadata found"), even 
if 
+using 
+
+    mvn clean compile bnd:bnd-process quarkus:dev
+
+The **native startup time** is about 5 seconds on my box, but just a few
+milliseconds when runnning in a Docker image.
\ No newline at end of file
diff --git a/graalvm/pom.xml b/graalvm/pom.xml
index 23f1270..89fee09 100644
--- a/graalvm/pom.xml
+++ b/graalvm/pom.xml
@@ -32,6 +32,10 @@
     </dependency>
     <dependency>
       <groupId>io.quarkus</groupId>
+      <artifactId>quarkus-resteasy-jsonb</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.quarkus</groupId>
       <artifactId>quarkus-junit5</artifactId>
       <scope>test</scope>
     </dependency>
@@ -41,11 +45,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.sling</groupId>
-      <artifactId>org.apache.sling.testing.osgi-mock.junit5</artifactId>
-      <version>2.4.8</version>
-    </dependency>
-    <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
       <version>6.0.0</version>
@@ -60,6 +59,31 @@
       <artifactId>org.osgi.service.component.annotations</artifactId>
       <version>1.3.0</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.testing.osgi-mock.junit5</artifactId>
+      <version>2.4.8</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.api</artifactId>
+      <version>2.20.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.engine</artifactId>
+      <version>2.6.20</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-fileupload</groupId>
+      <artifactId>commons-fileupload</artifactId>
+      <version>1.4</version>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.10.19</version>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
diff --git 
a/graalvm/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorWrapper.java
 
b/graalvm/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorWrapper.java
new file mode 100644
index 0000000..0f2d901
--- /dev/null
+++ 
b/graalvm/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorWrapper.java
@@ -0,0 +1,18 @@
+package org.apache.sling.engine.impl;
+
+import org.apache.sling.engine.SlingRequestProcessor;
+import org.apache.sling.engine.impl.SlingRequestProcessorImpl;
+import org.apache.sling.graalvm.sling.MockErrorHandler;
+import org.apache.sling.graalvm.sling.MockFilterManager;
+import org.apache.sling.graalvm.sling.MockServletResolver;
+import org.osgi.service.component.annotations.Component;
+
+/** TODO hack: using the engine.impl package to access package private 
methods... */
+@Component(service=SlingRequestProcessor.class)
+public class SlingRequestProcessorWrapper extends SlingRequestProcessorImpl {
+    public SlingRequestProcessorWrapper() {
+        this.setServletResolver(new MockServletResolver());
+        this.setErrorHandler(new MockErrorHandler());
+        this.setFilterManager(new MockFilterManager());
+    }
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/http/SlingResource.java 
b/graalvm/src/main/java/org/apache/sling/graalvm/http/SlingResource.java
new file mode 100644
index 0000000..566d8f8
--- /dev/null
+++ b/graalvm/src/main/java/org/apache/sling/graalvm/http/SlingResource.java
@@ -0,0 +1,55 @@
+package org.apache.sling.graalvm.http;
+
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doReturn;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.sling.graalvm.osgi.SlingContext;
+import org.apache.sling.graalvm.sling.MockServletResolver;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.mockito.Mockito;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.engine.SlingRequestProcessor;
+
+@Path("/sling/{resourcePath: [^/][a-zA-Z/_0-9\\.]*}")
+@Produces(MediaType.APPLICATION_JSON)
+public class SlingResource {
+
+    @Context
+    private HttpServletRequest request;
+
+    @GET
+    public Response sling(@PathParam("resourcePath") String resourcePath) 
throws IOException {
+        final SlingRequestProcessor p = 
SlingContext.get().getService(SlingRequestProcessor.class);
+        assert (p != null);
+        final ResourceResolver resolver = 
SlingContext.get().getService(ResourceResolver.class);
+        assert (resolver != null);
+
+        final StringWriter sw = new StringWriter();
+        final HttpServletResponse resp = 
Mockito.mock(HttpServletResponse.class);
+        when(resp.getWriter()).thenReturn(new PrintWriter(sw));
+        
+        try {
+            p.processRequest(request, resp, resolver);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        final Resource r = 
(Resource)request.getAttribute(MockServletResolver.RESOURCE_ATTR);
+        return Response.ok(r).build();
+    }
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/osgi/SlingContext.java 
b/graalvm/src/main/java/org/apache/sling/graalvm/osgi/SlingContext.java
new file mode 100644
index 0000000..bf9e27b
--- /dev/null
+++ b/graalvm/src/main/java/org/apache/sling/graalvm/osgi/SlingContext.java
@@ -0,0 +1,35 @@
+package org.apache.sling.graalvm.osgi;
+
+import org.apache.sling.engine.impl.SlingRequestProcessorWrapper;
+import org.apache.sling.graalvm.sling.MockResourceProvider;
+import org.apache.sling.graalvm.sling.MockResourceResolver;
+import org.apache.sling.testing.mock.osgi.junit5.OsgiContext;
+
+public class SlingContext {
+    private static OsgiContext context;
+    
+    public static OsgiContext get() {
+        if(context != null) {
+            return context;
+        }
+
+        synchronized(SlingContext.class) {
+            context = initialize();
+        }
+
+        return context;
+    }
+
+    /** This is where we wire the system, like the OSGi framework
+     *  would do. As it seems hard to run that framework in a GraalVM
+     *  environment for now, we wire things statically.
+     */
+    private static OsgiContext initialize() {
+        final OsgiContext result = new OsgiContext();
+        final MockResourceProvider mrp = new MockResourceProvider();
+        result.registerInjectActivateService(new MockResourceResolver(mrp));
+        result.registerInjectActivateService(mrp);
+        result.registerInjectActivateService(new 
SlingRequestProcessorWrapper());
+        return result;
+    }
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockErrorHandler.java 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockErrorHandler.java
new file mode 100644
index 0000000..e933d09
--- /dev/null
+++ b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockErrorHandler.java
@@ -0,0 +1,23 @@
+package org.apache.sling.graalvm.sling;
+
+import java.io.IOException;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.engine.servlets.ErrorHandler;
+
+public class MockErrorHandler implements ErrorHandler {
+
+    @Override
+    public void handleError(int status, String message, 
SlingHttpServletRequest request,
+            SlingHttpServletResponse response) throws IOException {
+        response.getWriter().write(getClass().getSimpleName() + ':' + status + 
':' + message);
+    }
+
+    @Override
+    public void handleError(Throwable throwable, SlingHttpServletRequest 
request, SlingHttpServletResponse response)
+            throws IOException {
+        response.getWriter().write(getClass().getSimpleName() + ':' + 
throwable.toString());
+    }
+    
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockFilterManager.java 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockFilterManager.java
new file mode 100644
index 0000000..ee07726
--- /dev/null
+++ 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockFilterManager.java
@@ -0,0 +1,12 @@
+package org.apache.sling.graalvm.sling;
+
+import org.apache.sling.engine.impl.filter.ServletFilterManager;
+import org.apache.sling.engine.impl.helper.SlingServletContext;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+
+public class MockFilterManager extends ServletFilterManager {
+    public MockFilterManager() {
+        super(Mockito.mock(BundleContext.class), 
Mockito.mock(SlingServletContext.class));
+    }
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResource.java 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResource.java
new file mode 100644
index 0000000..b5c73cb
--- /dev/null
+++ b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResource.java
@@ -0,0 +1,54 @@
+package org.apache.sling.graalvm.sling;
+
+import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class MockResource extends AbstractResource {
+
+    private final String path;
+    private final ResourceResolver resolver;
+    private final ResourceMetadata metadata;
+
+    public MockResource(ResourceResolver resolver, String path) {
+        this.resolver = resolver;
+        this.path = path;
+        this.metadata = new ResourceMetadata();
+        metadata.put(ResourceMetadata.RESOLUTION_PATH, path);
+        metadata.put(ResourceMetadata.RESOLUTION_PATH_INFO, path);
+    }
+
+    @Override
+    public String getPath() {
+        return path;
+    }
+
+    @Override
+    public String getResourceType() {
+        return "mock/resource";
+    }
+
+    @Override
+    public String getResourceSuperType() {
+        return null;
+    }
+
+    @Override
+    public ResourceMetadata getResourceMetadata() {
+        return metadata;
+    }
+
+    @Override
+    public ResourceResolver getResourceResolver() {
+        return resolver;
+    }
+
+    @Override
+    public Resource getParent() {
+        return null;
+    }
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResourceProvider.java
 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResourceProvider.java
new file mode 100644
index 0000000..555ad85
--- /dev/null
+++ 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResourceProvider.java
@@ -0,0 +1,27 @@
+package org.apache.sling.graalvm.sling;
+
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.osgi.service.component.annotations.Component;
+
+@Component(service=ResourceProvider.class)
+public class MockResourceProvider extends ResourceProvider<MockResource> {
+
+    private static final String MAGIC = "chouc";
+
+    @Override
+    public Resource getResource(ResolveContext<MockResource> ctx, String path, 
ResourceContext resourceContext,
+            Resource parent) {
+        return path.contains(MAGIC) ? new MockResource(null, path) : null;
+    }
+
+    @Override
+    public Iterator<Resource> listChildren(ResolveContext<MockResource> ctx, 
Resource parent) {
+        return null;
+    }
+   
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResourceResolver.java
 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResourceResolver.java
new file mode 100644
index 0000000..2ac4af7
--- /dev/null
+++ 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockResourceResolver.java
@@ -0,0 +1,184 @@
+package org.apache.sling.graalvm.sling;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.osgi.service.component.annotations.Component;
+
+@Component(service=ResourceResolver.class)
+public class MockResourceResolver implements ResourceResolver {
+
+    private final ResourceProvider<?> provider;
+
+    public MockResourceResolver(MockResourceProvider provider) {
+        this.provider = provider;
+    }
+
+    @Override
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        return null;
+    }
+
+    @Override
+    public Resource resolve(HttpServletRequest request, String absPath) {
+        return provider.getResource(null, absPath, null, null);
+    }
+
+    @Override
+    public Resource resolve(String absPath) {
+        return null;
+    }
+
+    @Override
+    public Resource resolve(HttpServletRequest request) {
+        return null;
+    }
+
+    @Override
+    public String map(String resourcePath) {
+        return null;
+    }
+
+    @Override
+    public String map(HttpServletRequest request, String resourcePath) {
+        return null;
+    }
+
+    @Override
+    public Resource getResource(String path) {
+        return null;
+    }
+
+    @Override
+    public Resource getResource(Resource base, String path) {
+        return null;
+    }
+
+    @Override
+    public String[] getSearchPath() {
+        return null;
+    }
+
+    @Override
+    public Iterator<Resource> listChildren(Resource parent) {
+        return null;
+    }
+
+    @Override
+    public Resource getParent(Resource child) {
+        return null;
+    }
+
+    @Override
+    public Iterable<Resource> getChildren(Resource parent) {
+        return null;
+    }
+
+    @Override
+    public Iterator<Resource> findResources(String query, String language) {
+        return null;
+    }
+
+    @Override
+    public Iterator<Map<String, Object>> queryResources(String query, String 
language) {
+        return null;
+    }
+
+    @Override
+    public boolean hasChildren(Resource resource) {
+        return false;
+    }
+
+    @Override
+    public ResourceResolver clone(Map<String, Object> authenticationInfo) 
throws LoginException {
+        return null;
+    }
+
+    @Override
+    public boolean isLive() {
+        return false;
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public String getUserID() {
+        return null;
+    }
+
+    @Override
+    public Iterator<String> getAttributeNames() {
+        return null;
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+        return null;
+    }
+
+    @Override
+    public void delete(Resource resource) throws PersistenceException {
+
+    }
+
+    @Override
+    public Resource create(Resource parent, String name, Map<String, Object> 
properties) throws PersistenceException {
+        return null;
+    }
+
+    @Override
+    public void revert() {
+
+    }
+
+    @Override
+    public void commit() throws PersistenceException {
+
+    }
+
+    @Override
+    public boolean hasChanges() {
+        return false;
+    }
+
+    @Override
+    public String getParentResourceType(Resource resource) {
+        return null;
+    }
+
+    @Override
+    public String getParentResourceType(String resourceType) {
+        return null;
+    }
+
+    @Override
+    public boolean isResourceType(Resource resource, String resourceType) {
+        return false;
+    }
+
+    @Override
+    public void refresh() {
+
+    }
+
+    @Override
+    public Resource copy(String srcAbsPath, String destAbsPath) throws 
PersistenceException {
+        return null;
+    }
+
+    @Override
+    public Resource move(String srcAbsPath, String destAbsPath) throws 
PersistenceException {
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git 
a/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockServletResolver.java 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockServletResolver.java
new file mode 100644
index 0000000..f0bf437
--- /dev/null
+++ 
b/graalvm/src/main/java/org/apache/sling/graalvm/sling/MockServletResolver.java
@@ -0,0 +1,41 @@
+package org.apache.sling.graalvm.sling;
+
+import java.io.IOException;
+
+import javax.servlet.Servlet;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.servlets.ServletResolver;
+import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+
+public class MockServletResolver implements ServletResolver {
+
+    public static final String RESOURCE_ATTR = 
MockServletResolver.class.getName();
+
+    static class DummyServlet extends SlingSafeMethodsServlet {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doGet(SlingHttpServletRequest request, 
SlingHttpServletResponse response) throws IOException {
+            request.setAttribute(RESOURCE_ATTR, request.getResource());
+        }
+    }
+
+    @Override
+    public Servlet resolveServlet(SlingHttpServletRequest request) {
+        return new DummyServlet();
+    }
+
+    @Override
+    public Servlet resolveServlet(Resource resource, String scriptName) {
+        return new DummyServlet();
+    }
+
+    @Override
+    public Servlet resolveServlet(ResourceResolver resolver, String 
scriptName) {
+        return new DummyServlet();
+    }
+}
\ No newline at end of file
diff --git 
a/graalvm/src/test/java/org/apache/sling/graalvm/http/NativeSlingResourceIT.java
 
b/graalvm/src/test/java/org/apache/sling/graalvm/http/NativeSlingResourceIT.java
new file mode 100644
index 0000000..9e7bcca
--- /dev/null
+++ 
b/graalvm/src/test/java/org/apache/sling/graalvm/http/NativeSlingResourceIT.java
@@ -0,0 +1,8 @@
+package org.apache.sling.graalvm.http;
+
+import io.quarkus.test.junit.SubstrateTest;
+
+@SubstrateTest
+public class NativeSlingResourceIT extends SlingResourceTest {
+    // Execute the same tests but in native mode.
+}
\ No newline at end of file
diff --git 
a/graalvm/src/test/java/org/apache/sling/graalvm/http/SlingResourceTest.java 
b/graalvm/src/test/java/org/apache/sling/graalvm/http/SlingResourceTest.java
new file mode 100644
index 0000000..d401d16
--- /dev/null
+++ b/graalvm/src/test/java/org/apache/sling/graalvm/http/SlingResourceTest.java
@@ -0,0 +1,30 @@
+package org.apache.sling.graalvm.http;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.equalTo;
+
+import javax.ws.rs.core.MediaType;
+
+@QuarkusTest
+public class SlingResourceTest {
+
+    @Test
+    public void testSlingResourceEndpoint() {
+        final String prefix = "/sling/";
+        final String path = "chouc/route";
+        final String resourceType = "mock/resource";
+
+        given()
+          .when().get(prefix + path)
+          .then()
+             .statusCode(200)
+             .contentType(MediaType.APPLICATION_JSON)
+             .body("path", equalTo(prefix + path))
+             .body("resourceType", equalTo(resourceType));
+    }
+
+}
\ No newline at end of file

Reply via email to