You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ol...@apache.org on 2019/08/17 07:49:16 UTC

[sling-org-apache-sling-clam] 10/12: SLING-8258 Provide HTTP API for Sling Clam

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

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

commit ffa206ad66f9f2e67729492af3be748284178079
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Fri Aug 16 18:31:36 2019 +0200

    SLING-8258 Provide HTTP API for Sling Clam
    
    * Add integration tests for ClamEventsServlet
---
 pom.xml                                            |  19 +++
 .../sling/clam/it/tests/ClamEventsServletIT.java   | 181 +++++++++++++++++++++
 2 files changed, 200 insertions(+)

diff --git a/pom.xml b/pom.xml
index f2584bc..f381ad1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -120,6 +120,25 @@
       <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
+    <!-- ok io/http -->
+    <dependency>
+      <groupId>org.apache.servicemix.bundles</groupId>
+      <artifactId>org.apache.servicemix.bundles.okio</artifactId>
+      <version>1.15.0_1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicemix.bundles</groupId>
+      <artifactId>org.apache.servicemix.bundles.okhttp</artifactId>
+      <version>3.11.0_1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.launchdarkly</groupId>
+      <artifactId>okhttp-eventsource</artifactId>
+      <version>1.10.0</version>
+      <scope>test</scope>
+    </dependency>
     <!-- OSGi -->
     <dependency>
       <groupId>org.osgi</groupId>
diff --git a/src/test/java/org/apache/sling/clam/it/tests/ClamEventsServletIT.java b/src/test/java/org/apache/sling/clam/it/tests/ClamEventsServletIT.java
new file mode 100644
index 0000000..20f85eb
--- /dev/null
+++ b/src/test/java/org/apache/sling/clam/it/tests/ClamEventsServletIT.java
@@ -0,0 +1,181 @@
+/*
+ * 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.clam.it.tests;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import com.launchdarkly.eventsource.EventHandler;
+import com.launchdarkly.eventsource.EventSource;
+import com.launchdarkly.eventsource.MessageEvent;
+import okhttp3.Credentials;
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.apache.sling.clam.jcr.NodeDescendingJcrPropertyDigger;
+import org.apache.sling.clam.result.JcrPropertyScanResultHandler;
+import org.apache.sling.resource.presence.ResourcePresence;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.exam.util.Filter;
+
+import static io.restassured.RestAssured.given;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.sling.testing.paxexam.SlingOptions.slingResourcePresence;
+import static org.apache.sling.testing.paxexam.SlingOptions.slingStarterContent;
+import static org.awaitility.Awaitility.with;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class ClamEventsServletIT extends ClamTestSupport {
+
+    @Inject
+    @Filter(value = "(path=/content/starter)")
+    private ResourcePresence resourcePresence;
+
+    @Inject
+    @Filter(value = "(service.description=Apache Sling Clam Events Servlet)")
+    private JcrPropertyScanResultHandler jcrPropertyScanResultHandler;
+
+    @Inject
+    private NodeDescendingJcrPropertyDigger nodeDescendingJcrPropertyDigger;
+
+    private static final String URL_TEMPLATE = "http://localhost:%s/system/clam-events";
+
+    @Configuration
+    public Option[] configuration() {
+        return options(
+            baseConfiguration(),
+            clamdConfiguration(),
+            slingResourcePresence(),
+            factoryConfiguration("org.apache.sling.resource.presence.internal.ResourcePresenter")
+                .put("path", "/content/starter")
+                .asOption(),
+            slingStarterContent(),
+            // ok io/http/eventsource
+            mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.okio").versionAsInProject(),
+            mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.okhttp").versionAsInProject(),
+            wrappedBundle(mavenBundle().groupId("com.launchdarkly").artifactId("okhttp-eventsource").versionAsInProject())
+        );
+    }
+
+    @Test
+    public void testAuthentication() throws Exception {
+        final String url = String.format(URL_TEMPLATE, httpPort());
+        given()
+            .when()
+            .get(url)
+            .then().statusCode(401);
+    }
+
+    @Test
+    public void testEvents() throws Exception {
+        final RecordingEventHandler recordingEventHandler = new RecordingEventHandler();
+
+        final String url = String.format(URL_TEMPLATE, httpPort());
+        final OkHttpClient client = new OkHttpClient.Builder()
+            .addInterceptor(new BasicAuthInterceptor("admin", "admin"))
+            .build();
+        final EventSource eventSource = new EventSource.Builder(recordingEventHandler, URI.create(url))
+            .client(client)
+            .maxReconnectTimeMs(0)
+            .reconnectTimeMs(0)
+            .build();
+        eventSource.start();
+
+        digBinaries(nodeDescendingJcrPropertyDigger, "/content/starter");
+        with().
+            pollInterval(10, SECONDS).
+            then().
+            await().
+            alias("counting results").
+            atMost(1, MINUTES).
+            until(() -> recordingEventHandler.countEvents() == 12);
+    }
+
+    class BasicAuthInterceptor implements Interceptor {
+
+        private String credentials;
+
+        BasicAuthInterceptor(final String user, final String password) {
+            this.credentials = Credentials.basic(user, password);
+        }
+
+        @Override
+        public Response intercept(final Chain chain) throws IOException {
+            final Request request = chain.request()
+                .newBuilder()
+                .header("Authorization", credentials)
+                .build();
+            return chain.proceed(request);
+        }
+
+    }
+
+    class RecordingEventHandler implements EventHandler {
+
+        private final List<String> events = new ArrayList<>();
+
+        List<String> getEvents() {
+            return events;
+        }
+
+        int countEvents() {
+            return events.size();
+        }
+
+        @Override
+        public void onOpen() throws Exception {
+        }
+
+        @Override
+        public void onClosed() throws Exception {
+        }
+
+        @Override
+        public void onMessage(final String event, final MessageEvent messageEvent) throws Exception {
+            events.add(messageEvent.getData());
+        }
+
+        @Override
+        public void onComment(final String comment) throws Exception {
+        }
+
+        @Override
+        public void onError(final Throwable throwable) {
+        }
+
+    }
+
+}