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 2021/01/28 12:41:58 UTC

[karaf-decanter] branch master updated: [KARAF-7003] Be able to catch and wrap exceptions in the REST collector

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 d057b93  [KARAF-7003] Be able to catch and wrap exceptions in the REST collector
     new c337d06  Merge pull request #228 from jbonofre/KARAF-7003
d057b93 is described below

commit d057b93e6a00d5c2a2702e9769e37c1c461db642
Author: jbonofre <jb...@apache.org>
AuthorDate: Thu Jan 28 10:48:00 2021 +0100

    [KARAF-7003] Be able to catch and wrap exceptions in the REST collector
---
 .../org.apache.karaf.decanter.collector.rest.cfg   |  4 ++++
 .../decanter/collector/rest/RestCollector.java     | 25 +++++++++++++++++++++-
 .../decanter/collector/rest/RestCollectorTest.java | 19 ++++++++++++++++
 .../src/main/asciidoc/user-guide/collectors.adoc   |  9 ++++++++
 4 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/collector/rest/src/main/cfg/org.apache.karaf.decanter.collector.rest.cfg b/collector/rest/src/main/cfg/org.apache.karaf.decanter.collector.rest.cfg
index f0e4c0f..8ecd088 100644
--- a/collector/rest/src/main/cfg/org.apache.karaf.decanter.collector.rest.cfg
+++ b/collector/rest/src/main/cfg/org.apache.karaf.decanter.collector.rest.cfg
@@ -31,5 +31,9 @@ paths=metrics
 #password=password (used for basic authentication)
 #topic=decanter/collector/rest (Decanter dispatcher topic name to use)
 
+# Possible to wrap exception as HTTP response, where you can define the HTTP response code
+# exception.as.http.response=true
+# exception.http.response.code=501
+
 # Unmarshaller to use
 unmarshaller.target=(dataFormat=json)
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 7c06825..57e674d 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
@@ -64,6 +64,8 @@ public class RestCollector implements Runnable {
     private String request;
     private String user;
     private String password;
+    private boolean exceptionAsHttpResponse;
+    private Integer exceptionHttpResponseCode = null;
     private Dictionary<String, Object> config;
 
     @Activate
@@ -80,6 +82,10 @@ public class RestCollector implements Runnable {
         this.user = getProperty(config, "user", null);
         this.password = getProperty(config, "password", null);
         this.request = getProperty(config, "request", null);
+        this.exceptionAsHttpResponse = Boolean.parseBoolean(getProperty(config, "exception.as.http.response", "false"));
+        if (config.get("exception.http.response.code") != null) {
+            this.exceptionHttpResponseCode = Integer.parseInt((String) config.get("exception.http.response.code"));
+        }
     }
     
     private String getProperty(Dictionary<String, Object> properties, String key, String defaultValue) {
@@ -134,7 +140,24 @@ public class RestCollector implements Runnable {
                 data.put("service.hostName", url.getHost());
             } catch (Exception e) {
                 LOGGER.warn("Can't request REST service", e);
-                data.put("error", e.getClass().getName() + ": " + e.getMessage());
+                if (exceptionAsHttpResponse) {
+                    if (exceptionHttpResponseCode != null) {
+                        data.put("http.response.code", exceptionHttpResponseCode);
+                    } else {
+                        try {
+                            data.put("http.response.code", connection.getResponseCode());
+                        } catch (Exception ie) {
+                            // no-op
+                        }
+                    }
+                    data.put("http.exception", e.getClass().getName() + ": " + e.getMessage());
+                    data.put("type", "rest");
+                    data.put("url", urlWithPath);
+                } else {
+                    data.put("type", "rest");
+                    data.put("url", urlWithPath);
+                    data.put("error", e.getClass().getName() + ": " + e.getMessage());
+                }
             } finally {
                 if (connection != null) {
                     connection.disconnect();
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
index 711ecc1..10dce60 100644
--- 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
@@ -64,6 +64,25 @@ public class RestCollectorTest {
     }
 
     @Test
+    public void testExceptionWrapping() throws Exception {
+        EventAdminMock eventAdminMock = new EventAdminMock();
+        RestCollector collector = new RestCollector();
+        Dictionary<String, Object> config = new Hashtable<>();
+        config.put("url", "http://foo.bar/foo");
+        config.put("exception.as.http.response", "true");
+        config.put("exception.http.response.code", "600");
+        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(600, event.getProperty("http.response.code"));
+        Assert.assertEquals("java.net.UnknownHostException: foo.bar", event.getProperty("http.exception"));
+    }
+
+    @Test
     public void testGet() throws Exception {
         EventAdminMock eventAdminMock = new EventAdminMock();
         RestCollector collector = new RestCollector();
diff --git a/manual/src/main/asciidoc/user-guide/collectors.adoc b/manual/src/main/asciidoc/user-guide/collectors.adoc
index 10d9831..c6f3c23 100644
--- a/manual/src/main/asciidoc/user-guide/collectors.adoc
+++ b/manual/src/main/asciidoc/user-guide/collectors.adoc
@@ -875,10 +875,19 @@ paths=metrics
 #password=password (used for basic authentication)
 #topic=decanter/collector/rest (Decanter dispatcher topic name to use)
 
+# Possible to wrap exception as HTTP response, where you can define the HTTP response code
+# exception.as.http.response=true
+# exception.http.response.code=501
+
 # Unmarshaller to use
 unmarshaller.target=(dataFormat=json)
 ----
 
+The `exception.as.http.response` property allows you to "wrap" any connection exception as a HTTP message.
+If `true`, any exception is catched and we send kind of HTTP message in the Decanter dispatcher.
+
+It's also possible to define a HTTP response code (thanks to `exception.http.response.code` property) when an exception is catched.
+
 ==== SOAP
 
 The Decanter SOAP collector periodically requests a SOAP service and returns the result (the SOAP Response, or error details if it failed).