You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2019/03/13 09:40:44 UTC

[karaf-decanter] branch master updated: [KARAF-6161] Update the REST collector, including http code and message

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

jbonofre pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/karaf-decanter.git


The following commit(s) were added to refs/heads/master by this push:
     new 390e279  [KARAF-6161] Update the REST collector, including http code and message
     new db83ea6  Merge pull request #73 from jbonofre/KARAF-6161
390e279 is described below

commit 390e2794fbee11128f4a95e294abf61d99cc7e47
Author: Jean-Baptiste Onofré <jb...@apache.org>
AuthorDate: Tue Feb 26 07:59:23 2019 +0100

    [KARAF-6161] Update the REST collector, including http code and message
---
 collector/rest/pom.xml                             | 29 ++++++++
 .../decanter/collector/rest/RestCollector.java     | 71 +++++++++---------
 .../decanter/collector/rest/EventAdminMock.java    | 40 +++++++++++
 .../decanter/collector/rest/RestCollectorTest.java | 83 ++++++++++++++++++++++
 .../karaf/decanter/collector/rest/TestService.java | 38 ++++++++++
 5 files changed, 223 insertions(+), 38 deletions(-)

diff --git a/collector/rest/pom.xml b/collector/rest/pom.xml
index a4df551..5368be8 100644
--- a/collector/rest/pom.xml
+++ b/collector/rest/pom.xml
@@ -33,6 +33,10 @@
     <packaging>bundle</packaging>
     <name>Apache Karaf :: Decanter :: Collector :: REST</name>
 
+    <properties>
+        <cxf.version>3.2.6</cxf.version>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.karaf.decanter</groupId>
@@ -42,6 +46,31 @@
             <groupId>org.apache.karaf.decanter.collector</groupId>
             <artifactId>org.apache.karaf.decanter.collector.utils</artifactId>
         </dependency>
+
+        <!-- test -->
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http-jetty</artifactId>
+            <version>${cxf.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <version>${cxf.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.decanter.marshaller</groupId>
+            <artifactId>org.apache.karaf.decanter.marshaller.raw</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/collector/rest/src/main/java/org/apache/karaf/decanter/collector/rest/RestCollector.java b/collector/rest/src/main/java/org/apache/karaf/decanter/collector/rest/RestCollector.java
index ef78594..8b678ff 100644
--- a/collector/rest/src/main/java/org/apache/karaf/decanter/collector/rest/RestCollector.java
+++ b/collector/rest/src/main/java/org/apache/karaf/decanter/collector/rest/RestCollector.java
@@ -16,11 +16,12 @@
  */
 package org.apache.karaf.decanter.collector.rest;
 
+import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.net.URLConnection;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.karaf.decanter.api.marshaller.Unmarshaller;
@@ -58,24 +59,19 @@ public class RestCollector implements Runnable {
 
     private URL url;
     private String[] paths;
-    private String baseTopic;
-    private Dictionary<String, Object> properties;
+    private String topic;
+    private Dictionary<String, Object> config;
 
-    private boolean repeatedError;
-
-    @SuppressWarnings("unchecked")
     @Activate
-    public void activate(ComponentContext context) throws MalformedURLException {
-        Dictionary<String, Object> props = context.getProperties();
-        this.url = new URL(getProperty(props, "url", null));
-        getProperty(props, "username", null);
-        getProperty(props, "password", null);
-        this.paths = getProperty(props, "paths", "").split(",");
-        this.baseTopic = getProperty(props, "topic", "decanter/collect");
-        //props.remove("password");
-        //props.remove("username");
-        this.properties = props;
-        this.repeatedError = false;
+    public void activate(ComponentContext componentContext) throws Exception {
+        activate(componentContext.getProperties());
+    }
+
+    public void activate(Dictionary<String, Object> config) throws MalformedURLException {
+        this.config = config;
+        this.url = new URL(getProperty(config, "url", null));
+        this.paths = getProperty(config, "paths", "").split(",");
+        this.topic = getProperty(config, "topic", "decanter/collect");
     }
     
     private String getProperty(Dictionary<String, Object> properties, String key, String defaultValue) {
@@ -86,46 +82,45 @@ public class RestCollector implements Runnable {
     public void run() {
         LOGGER.debug("Karaf Decanter REST Collector starts harvesting from {} ...", url);
         for (String path : paths) {
-            URL complete;
+            URL urlWithPath;
             try {
-                complete = new URL(url, path);
+                urlWithPath = new URL(url, path);
             } catch (MalformedURLException e) {
                 LOGGER.warn("Invalid URL. Stopping collector", e);
                 throw new IllegalArgumentException(e);
             }
+            LOGGER.debug("\tpath {}", urlWithPath);
+            HttpURLConnection connection = null;
+            Map<String, Object> data = new HashMap<>();
             try {
-                URLConnection connection = complete.openConnection();
-                Map<String, Object> data = unmarshaller.unmarshal(connection.getInputStream());
+                connection = (HttpURLConnection) urlWithPath.openConnection();
+                data.putAll(unmarshaller.unmarshal(connection.getInputStream()));
+                data.put("http.response.code", connection.getResponseCode());
+                data.put("http.response.message", connection.getResponseMessage());
                 data.put("type", "rest");
-                data.put("remote.url", complete);
+                data.put("url", urlWithPath);
 
                 // custom fields
-                Enumeration<String> keys = properties.keys();
+                Enumeration<String> keys = config.keys();
                 while (keys.hasMoreElements()) {
                     String key = keys.nextElement();
-                    data.put(key, properties.get(key));
+                    data.put(key, config.get(key));
                 }
 
-                PropertiesPreparator.prepare(data, properties);
+                PropertiesPreparator.prepare(data, config);
 
-                data.put("hostName", url.getHost());
-                dispatcher.postEvent(new Event(toTopic(complete), data));
-                repeatedError = false;
+                data.put("service.hostName", url.getHost());
             } catch (Exception e) {
-                if (repeatedError) {
-                    LOGGER.warn("Error fetching " + complete, e);
-                    repeatedError = true;
-                } else {
-                    LOGGER.debug("Repeated Error fetching " + complete, e);
+                LOGGER.warn("Can't request REST service", e);
+                data.put("error", e.getClass().getName() + ": " + e.getMessage());
+            } finally {
+                if (connection != null) {
+                    connection.disconnect();
                 }
-                
             }
+            dispatcher.postEvent(new Event(topic, data));
         }
         LOGGER.debug("Karaf Decanter REST Collector harvesting done");
     }
 
-    private String toTopic(URL url) {
-        return baseTopic + "/" + url.getHost() + url.getPath();
-    }
-
 }
diff --git a/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/EventAdminMock.java b/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/EventAdminMock.java
new file mode 100644
index 0000000..bc7e15f
--- /dev/null
+++ b/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/EventAdminMock.java
@@ -0,0 +1,40 @@
+/*
+ * 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.karaf.decanter.collector.rest;
+
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EventAdminMock implements EventAdmin {
+
+    public List<Event> postedEvents = new ArrayList<>();
+    public List<Event> sentEvents = new ArrayList<>();
+
+    @Override
+    public void postEvent(Event event) {
+        postedEvents.add(event);
+    }
+
+    @Override
+    public void sendEvent(Event event) {
+        sentEvents.add(event);
+    }
+
+}
diff --git a/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/RestCollectorTest.java b/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/RestCollectorTest.java
new file mode 100644
index 0000000..69d5a3d
--- /dev/null
+++ b/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/RestCollectorTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.karaf.decanter.collector.rest;
+
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.karaf.decanter.marshaller.raw.RawUnmarshaller;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.service.event.Event;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+public class RestCollectorTest {
+
+    private Server cxfServer;
+
+    @Before
+    public void setup() throws Exception {
+        JAXRSServerFactoryBean jaxrsServerFactoryBean = new JAXRSServerFactoryBean();
+        TestService service = new TestService();
+        jaxrsServerFactoryBean.setAddress("http://localhost:9090/test");
+        jaxrsServerFactoryBean.setServiceBean(service);
+        cxfServer = jaxrsServerFactoryBean.create();
+        cxfServer.start();
+    }
+
+    @After
+    public void teardown() throws Exception {
+        cxfServer.stop();
+    }
+
+    @Test
+    public void testBadUrl() throws Exception {
+        EventAdminMock eventAdminMock = new EventAdminMock();
+        RestCollector collector = new RestCollector();
+        Dictionary<String, Object> config = new Hashtable<>();
+        config.put("url", "http://foo.bar/foo");
+        collector.unmarshaller = new RawUnmarshaller();
+        collector.dispatcher = eventAdminMock;
+        collector.activate(config);
+        collector.run();
+
+        Assert.assertEquals(1, eventAdminMock.postedEvents.size());
+        Event event = eventAdminMock.postedEvents.get(0);
+        Assert.assertEquals("java.net.UnknownHostException: foo.bar", event.getProperty("error"));
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        EventAdminMock eventAdminMock = new EventAdminMock();
+        RestCollector collector = new RestCollector();
+        Dictionary<String, Object> config = new Hashtable<>();
+        config.put("url", "http://localhost:9090/test/echo");
+        collector.unmarshaller = new RawUnmarshaller();
+        collector.dispatcher = eventAdminMock;
+        collector.activate(config);
+        collector.run();
+
+        Assert.assertEquals(1, eventAdminMock.postedEvents.size());
+        Event event = eventAdminMock.postedEvents.get(0);
+        Assert.assertEquals(200, event.getProperty("http.response.code"));
+        Assert.assertEquals("hello world\n", event.getProperty("payload"));
+    }
+
+}
diff --git a/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/TestService.java b/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/TestService.java
new file mode 100644
index 0000000..6e6cc3c
--- /dev/null
+++ b/collector/rest/src/test/java/org/apache/karaf/decanter/collector/rest/TestService.java
@@ -0,0 +1,38 @@
+/*
+ * 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.karaf.decanter.collector.rest;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+@Path("/")
+public class TestService {
+
+    @GET
+    @Path("/echo")
+    public String echo() {
+        return "hello world";
+    }
+
+    @POST
+    @Path("/submit")
+    public void submit(String foo) {
+        // nothing to do
+    }
+
+}