From commits-return-35821-archive-asf-public=cust-asf.ponee.io@karaf.apache.org Tue Feb 26 08:16:56 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 4F10218062C for ; Tue, 26 Feb 2019 09:16:55 +0100 (CET) Received: (qmail 6461 invoked by uid 500); 26 Feb 2019 08:16:54 -0000 Mailing-List: contact commits-help@karaf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@karaf.apache.org Delivered-To: mailing list commits@karaf.apache.org Received: (qmail 6452 invoked by uid 99); 26 Feb 2019 08:16:53 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Feb 2019 08:16:53 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 52F2382E8A; Tue, 26 Feb 2019 08:16:53 +0000 (UTC) Date: Tue, 26 Feb 2019 08:16:53 +0000 To: "commits@karaf.apache.org" Subject: [karaf-decanter] branch master updated: [KARAF-6118] Add SOAP collector MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <155116901326.30334.1057309934194590558@gitbox.apache.org> From: jbonofre@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: karaf-decanter X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: b9b8516649494af8878649a854bf21483973953d X-Git-Newrev: ff11e9b04b0a61cbf49fc39b8a7f965d878efdd4 X-Git-Rev: ff11e9b04b0a61cbf49fc39b8a7f965d878efdd4 X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated 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 ff11e9b [KARAF-6118] Add SOAP collector new f0146f0 Merge pull request #72 from jbonofre/KARAF-6118 ff11e9b is described below commit ff11e9b04b0a61cbf49fc39b8a7f965d878efdd4 Author: Jean-Baptiste Onofré AuthorDate: Sun Feb 17 22:05:47 2019 +0100 [KARAF-6118] Add SOAP collector --- assembly/src/main/feature/feature.xml | 11 ++ collector/pom.xml | 1 + collector/soap/pom.xml | 114 +++++++++++++++++ .../org.apache.karaf.decanter.collector.soap.cfg | 27 ++++ .../decanter/collector/soap/SoapCollector.java | 141 +++++++++++++++++++++ .../decanter/collector/soap/EventAdminMock.java | 40 ++++++ .../decanter/collector/soap/SoapCollectorTest.java | 130 +++++++++++++++++++ .../karaf/decanter/collector/soap/TestService.java | 26 ++++ .../decanter/collector/soap/TestServiceImpl.java | 29 +++++ .../src/main/asciidoc/user-guide/collectors.adoc | 27 ++++ 10 files changed, 546 insertions(+) diff --git a/assembly/src/main/feature/feature.xml b/assembly/src/main/feature/feature.xml index af953e6..fd4969d 100644 --- a/assembly/src/main/feature/feature.xml +++ b/assembly/src/main/feature/feature.xml @@ -107,6 +107,17 @@ mvn:org.apache.karaf.decanter.collector/org.apache.karaf.decanter.collector.rest/${project.version}/cfg + + decanter-common + scheduler + mvn:org.apache.karaf.decanter.collector/org.apache.karaf.decanter.collector.soap/${project.version} + + + + decanter-collector-soap-core + mvn:org.apache.karaf.decanter.collector/org.apache.karaf.decanter.collector.soap/${project.version}/cfg + + decanter-common scheduler diff --git a/collector/pom.xml b/collector/pom.xml index 9841651..fe92393 100644 --- a/collector/pom.xml +++ b/collector/pom.xml @@ -48,6 +48,7 @@ process rest rest-servlet + soap system socket jdbc diff --git a/collector/soap/pom.xml b/collector/soap/pom.xml new file mode 100644 index 0000000..a02f369 --- /dev/null +++ b/collector/soap/pom.xml @@ -0,0 +1,114 @@ + + + + + + 4.0.0 + + + org.apache.karaf.decanter + collector + 2.2.0-SNAPSHOT + ../pom.xml + + + org.apache.karaf.decanter.collector + org.apache.karaf.decanter.collector.soap + bundle + Apache Karaf :: Decanter :: Collector :: SOAP + + + 3.2.6 + + + + + org.apache.karaf.decanter + org.apache.karaf.decanter.api + + + org.apache.karaf.decanter.collector + org.apache.karaf.decanter.collector.utils + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf.version} + test + + + org.apache.cxf + cxf-rt-transports-http-jetty + ${cxf.version} + test + + + org.slf4j + slf4j-simple + test + + + + + + + org.apache.felix + maven-bundle-plugin + true + true + + NONE + + ${project.artifactId} + !* + * + + org.apache.karaf.decanter.collector.soap, + org.apache.karaf.decanter.collector.utils + + <_dsannotations>* + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + package + + attach-artifact + + + + + src/main/cfg/org.apache.karaf.decanter.collector.soap.cfg + cfg + + + + + + + + + + \ No newline at end of file diff --git a/collector/soap/src/main/cfg/org.apache.karaf.decanter.collector.soap.cfg b/collector/soap/src/main/cfg/org.apache.karaf.decanter.collector.soap.cfg new file mode 100644 index 0000000..81d226d --- /dev/null +++ b/collector/soap/src/main/cfg/org.apache.karaf.decanter.collector.soap.cfg @@ -0,0 +1,27 @@ +################################################################################ +# +# 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. +# +################################################################################ + +# +# Decanter SOAP collector +# + +url=http://localhost:8080/cxf/service +soap.request= +#topic=decanter/collect/soap + diff --git a/collector/soap/src/main/java/org/apache/karaf/decanter/collector/soap/SoapCollector.java b/collector/soap/src/main/java/org/apache/karaf/decanter/collector/soap/SoapCollector.java new file mode 100644 index 0000000..738b978 --- /dev/null +++ b/collector/soap/src/main/java/org/apache/karaf/decanter/collector/soap/SoapCollector.java @@ -0,0 +1,141 @@ +/* + * 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.soap; + +import org.apache.karaf.decanter.collector.utils.PropertiesPreparator; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventAdmin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +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; + +@Component( + service = Runnable.class, + name = "org.apache.karaf.decanter.collector.soap", + immediate = true, + property = { + "decanter.collector.name=soap", + "scheduler.period:Long=60", + "scheduler.concurrent:Boolean=false", + "scheduler.name=decanter-collector-soap" + } +) +public class SoapCollector implements Runnable { + + @Reference + public EventAdmin dispatcher; + + private final static Logger LOGGER = LoggerFactory.getLogger(SoapCollector.class); + + private URL url; + private String soapRequest; + private String topic; + private Dictionary config; + + @Activate + public void activate(ComponentContext componentContext) throws Exception { + activate(componentContext.getProperties()); + } + + public void activate(Dictionary config) throws MalformedURLException { + this.config = config; + if (config.get("url") == null) { + throw new IllegalArgumentException("url property is mandatory"); + } + this.topic = "decanter/collect/soap"; + if (config.get("topic") != null) { + this.topic = (String) config.get("topic"); + } + url = new URL((String) config.get("url")); + if (config.get("soap.request") == null) { + throw new IllegalStateException("soap.request property is mandatory"); + } + soapRequest = (String) config.get("soap.request"); + } + + @Override + public void run() { + Map data = new HashMap<>(); + data.put("soap.request", soapRequest); + data.put("url", url); + data.put("type", "soap"); + + // custom fields + Enumeration keys = config.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + data.put(key, config.get(key)); + } + + try { + PropertiesPreparator.prepare(data, config); + } catch (Exception e) { + LOGGER.warn("Can't prepare properties", e); + } + + HttpURLConnection connection = null; + try { + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + connection.setDoInput(true); + connection.setRequestProperty("Content-Type", "text/xml"); + connection.setRequestProperty("Accept", "text/xml"); + try (OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) { + writer.write(soapRequest); + writer.flush(); + data.put("http.response.code", connection.getResponseCode()); + data.put("http.response.message", connection.getResponseMessage()); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + StringBuffer buffer = new StringBuffer(); + String line; + while ((line = reader.readLine()) != null) { + buffer.append(line).append("\n"); + } + data.put("soap.response", buffer.toString()); + } + } + } catch (Exception e) { + LOGGER.warn("Can't request SOAP service", e); + data.put("error", e.getClass().getName() + ": " + e.getMessage()); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + + dispatcher.postEvent(new Event(topic, data)); + } + +} diff --git a/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/EventAdminMock.java b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/EventAdminMock.java new file mode 100644 index 0000000..8b9476d --- /dev/null +++ b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/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.soap; + +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 postedEvents = new ArrayList<>(); + public List 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/soap/src/test/java/org/apache/karaf/decanter/collector/soap/SoapCollectorTest.java b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/SoapCollectorTest.java new file mode 100644 index 0000000..b4267f0 --- /dev/null +++ b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/SoapCollectorTest.java @@ -0,0 +1,130 @@ +/* + * 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.soap; + +import org.apache.cxf.endpoint.Server; +import org.apache.cxf.feature.LoggingFeature; +import org.apache.cxf.jaxws.JaxWsServerFactoryBean; +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 SoapCollectorTest { + + private Server cxfServer; + + @Before + public void setup() throws Exception { + JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); + + LoggingFeature loggingFeature = new LoggingFeature(); + loggingFeature.setPrettyLogging(true); + factory.getFeatures().add(loggingFeature); + + TestServiceImpl testService = new TestServiceImpl(); + factory.setServiceBean(testService); + factory.setAddress("http://localhost:9090/test"); + cxfServer = factory.create(); + cxfServer.start(); + } + + @After + public void teardown() throws Exception { + cxfServer.stop(); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadConfiguration() throws Exception { + SoapCollector collector = new SoapCollector(); + Dictionary config = new Hashtable<>(); + collector.activate(config); + } + + @Test + public void testWithInvalidRequest() throws Exception { + EventAdminMock eventAdminMock = new EventAdminMock(); + + SoapCollector collector = new SoapCollector(); + Dictionary config = new Hashtable<>(); + config.put("soap.request", "test"); + config.put("url", "http://localhost:9090/test"); + collector.dispatcher = eventAdminMock; + collector.activate(config); + collector.run(); + + Assert.assertEquals(1, eventAdminMock.postedEvents.size()); + + Event event = eventAdminMock.postedEvents.get(0); + + Assert.assertEquals(500, event.getProperty("http.response.code")); + Assert.assertTrue(((String) event.getProperty("error")).contains("java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:9090/test")); + } + + @Test + public void testWithBadUrl() throws Exception { + EventAdminMock eventAdminMock = new EventAdminMock(); + + SoapCollector collector = new SoapCollector(); + Dictionary config = new Hashtable<>(); + config.put("soap.request", "test"); + config.put("url", "http://foo.bar/foo"); + 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 testWithValidRequest() throws Exception { + EventAdminMock eventAdminMock = new EventAdminMock(); + + SoapCollector collector = new SoapCollector(); + Dictionary config = new Hashtable<>(); + config.put("url", "http://localhost:9090/test"); + config.put("soap.request", "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " This is a test\n" + + " \n" + + " \n" + + ""); + collector.dispatcher = eventAdminMock; + collector.activate(config); + collector.run(); + + Assert.assertEquals(1, eventAdminMock.postedEvents.size()); + + Event event = eventAdminMock.postedEvents.get(0); + Assert.assertNull(event.getProperty("error")); + Assert.assertEquals(200, event.getProperty("http.response.code")); + Assert.assertEquals("OK", event.getProperty("http.response.message")); + Assert.assertTrue(((String) event.getProperty("soap.response")).contains("hello This is a test")); + } + +} diff --git a/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/TestService.java b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/TestService.java new file mode 100644 index 0000000..94b880a --- /dev/null +++ b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/TestService.java @@ -0,0 +1,26 @@ +/* + * 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.soap; + +import javax.jws.WebService; + +@WebService +public interface TestService { + + String echo(String message); + +} diff --git a/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/TestServiceImpl.java b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/TestServiceImpl.java new file mode 100644 index 0000000..5f14b5b --- /dev/null +++ b/collector/soap/src/test/java/org/apache/karaf/decanter/collector/soap/TestServiceImpl.java @@ -0,0 +1,29 @@ +/* + * 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.soap; + +import javax.jws.WebService; + +@WebService(endpointInterface = "org.apache.karaf.decanter.collector.soap.TestService", serviceName = "TestService") +public class TestServiceImpl implements TestService { + + @Override + public String echo(String message) { + return "hello " + message; + } + +} diff --git a/manual/src/main/asciidoc/user-guide/collectors.adoc b/manual/src/main/asciidoc/user-guide/collectors.adoc index f1bbbe7..f10b6a9 100644 --- a/manual/src/main/asciidoc/user-guide/collectors.adoc +++ b/manual/src/main/asciidoc/user-guide/collectors.adoc @@ -779,6 +779,33 @@ The `decanter-collector-rest-servlet` feature installs the collector: karaf@root()> feature:install decanter-collector-rest-servlet ---- +==== SOAP + +The Decanter SOAP collector periodically requests a SOAP service and returns the result (the SOAP Response, or error details if it failed). + +The `decanter-collector-soap` feature installs the collector: + +---- +karaf@root()> feature:install decanter-collector-soap +---- + +This feature also installs `etc/org.apache.karaf.decanter.collector.soap.cfg` configuration file where you can setup the URL of the service and the SOAP request to use: + +---- +# +# Decanter SOAP collector +# + +url=http://localhost:8080/cxf/service +soap.request= +---- + +The collector send several collected properties to the dispatcher, especially: + +* `soap.response` property contains the actual SOAP response +* `error` is only populated when the service request failed, containing the error detail +* `http.response.code` contains the HTTP status code of the service request + ==== Dropwizard Metrics The Decanter Dropwizard Metrics collector get a `MetricSet` OSGi service and periodically get the metrics in the set.