[KARAF-7003] Be able to catch and wrap exceptions in the REST collector
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 @@
#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 @@
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 @@
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 @@
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 @@
}
@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 @@
#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).