You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by co...@apache.org on 2019/04/30 13:56:34 UTC
[camel] branch master updated: CAMEL-13471 - Adding support for
coap+tcp
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new 420e9cd CAMEL-13471 - Adding support for coap+tcp
420e9cd is described below
commit 420e9cd186c0aa773225dfd91e302baebc776f1c
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Apr 30 14:55:26 2019 +0100
CAMEL-13471 - Adding support for coap+tcp
---
components/camel-coap/pom.xml | 5 +
.../java/org/apache/camel/coap/CoAPComponent.java | 10 +-
.../java/org/apache/camel/coap/CoAPEndpoint.java | 6 +-
.../java/org/apache/camel/coap/CoAPProducer.java | 14 ++-
.../services/org/apache/camel/component/coaps | 18 ---
.../org/apache/camel/coap/CoAPComponentTest.java | 28 ++++-
.../camel/coap/CoAPRestComponentTCPTest.java | 131 +++++++++++++++++++++
.../springboot/CoAPComponentAutoConfiguration.java | 2 +-
8 files changed, 190 insertions(+), 24 deletions(-)
diff --git a/components/camel-coap/pom.xml b/components/camel-coap/pom.xml
index badedf1..4f064de 100644
--- a/components/camel-coap/pom.xml
+++ b/components/camel-coap/pom.xml
@@ -51,6 +51,11 @@
<artifactId>scandium</artifactId>
<version>${californium-version}</version>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.californium</groupId>
+ <artifactId>element-connector-tcp</artifactId>
+ <version>${californium-version}</version>
+ </dependency>
<!-- logging -->
<dependency>
diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java
index 6c213ef..c36317f 100644
--- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java
+++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java
@@ -37,6 +37,7 @@ import org.apache.camel.util.URISupport;
import org.eclipse.californium.core.CoapServer;
import org.eclipse.californium.core.network.CoapEndpoint;
import org.eclipse.californium.core.network.config.NetworkConfig;
+import org.eclipse.californium.elements.tcp.TcpServerConnector;
import org.eclipse.californium.scandium.DTLSConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,7 +45,7 @@ import org.slf4j.LoggerFactory;
/**
* Represents the component that manages {@link CoAPEndpoint}.
*/
-@Component("coap")
+@Component("coap,coaps,coap+tcp,coaps+tcp")
public class CoAPComponent extends DefaultComponent implements RestConsumerFactory {
static final int DEFAULT_PORT = 5684;
private static final Logger LOG = LoggerFactory.getLogger(CoAPComponent.class);
@@ -65,10 +66,15 @@ public class CoAPComponent extends DefaultComponent implements RestConsumerFacto
InetSocketAddress address = new InetSocketAddress(port);
coapBuilder.setNetworkConfig(config);
- // Configure TLS
+ // Configure TLS and / or TCP
if (CoAPEndpoint.enableTLS(endpoint.getUri())) {
DTLSConnector connector = endpoint.createDTLSConnector(address, false);
coapBuilder.setConnector(connector);
+ } else if (CoAPEndpoint.enableTCP(endpoint.getUri())) {
+ int tcpThreads = config.getInt(NetworkConfig.Keys.TCP_WORKER_THREADS);
+ int tcpIdleTimeout = config.getInt(NetworkConfig.Keys.TCP_CONNECTION_IDLE_TIMEOUT);
+ TcpServerConnector tcpConnector = new TcpServerConnector(address, tcpThreads, tcpIdleTimeout);
+ coapBuilder.setConnector(tcpConnector);
} else {
coapBuilder.setInetSocketAddress(address);
}
diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
index e169d8c..36954ca 100644
--- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
+++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
@@ -49,7 +49,7 @@ import org.eclipse.californium.scandium.dtls.rpkstore.TrustedRpkStore;
/**
* The coap component is used for sending and receiving messages from COAP capable devices.
*/
-@UriEndpoint(firstVersion = "2.16.0", scheme = "coap", title = "CoAP", syntax = "coap:uri", label = "iot")
+@UriEndpoint(firstVersion = "2.16.0", scheme = "coap,coaps,coap+tcp,coaps+tcp", title = "CoAP", syntax = "coap:uri", label = "iot")
public class CoAPEndpoint extends DefaultEndpoint {
@UriPath
private URI uri;
@@ -356,6 +356,10 @@ public class CoAPEndpoint extends DefaultEndpoint {
return "coaps".equals(uri.getScheme());
}
+ public static boolean enableTCP(URI uri) {
+ return uri.getScheme().endsWith("+tcp");
+ }
+
public DTLSConnector createDTLSConnector(InetSocketAddress address, boolean client) {
DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder();
diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java
index d82852a..a764857 100644
--- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java
+++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java
@@ -25,6 +25,8 @@ import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.californium.core.network.CoapEndpoint;
+import org.eclipse.californium.core.network.config.NetworkConfig;
+import org.eclipse.californium.elements.tcp.TcpClientConnector;
import org.eclipse.californium.scandium.DTLSConnector;
/**
@@ -94,13 +96,23 @@ public class CoAPProducer extends DefaultProducer {
}
client = new CoapClient(uri);
- // Configure TLS
+ // Configure TLS and / or TCP
if (CoAPEndpoint.enableTLS(uri)) {
DTLSConnector connector = endpoint.createDTLSConnector(null, true);
CoapEndpoint.Builder coapBuilder = new CoapEndpoint.Builder();
coapBuilder.setConnector(connector);
client.setEndpoint(coapBuilder.build());
+ } else if (CoAPEndpoint.enableTCP(endpoint.getUri())) {
+ NetworkConfig config = NetworkConfig.createStandardWithoutFile();
+ int tcpThreads = config.getInt(NetworkConfig.Keys.TCP_WORKER_THREADS);
+ int tcpConnectTimeout = config.getInt(NetworkConfig.Keys.TCP_CONNECT_TIMEOUT);
+ int tcpIdleTimeout = config.getInt(NetworkConfig.Keys.TCP_CONNECTION_IDLE_TIMEOUT);
+ TcpClientConnector tcpConnector = new TcpClientConnector(tcpThreads, tcpConnectTimeout, tcpIdleTimeout);
+ CoapEndpoint.Builder tcpBuilder = new CoapEndpoint.Builder();
+ tcpBuilder.setConnector(tcpConnector);
+
+ client.setEndpoint(tcpBuilder.build());
}
}
diff --git a/components/camel-coap/src/main/resources/META-INF/services/org/apache/camel/component/coaps b/components/camel-coap/src/main/resources/META-INF/services/org/apache/camel/component/coaps
deleted file mode 100644
index e0129bc..0000000
--- a/components/camel-coap/src/main/resources/META-INF/services/org/apache/camel/component/coaps
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-
-class=org.apache.camel.coap.CoAPComponent
diff --git a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTest.java b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTest.java
index d4c8f49..aaad659 100644
--- a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTest.java
+++ b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTest.java
@@ -21,6 +21,7 @@ import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.AvailablePortFinder;
import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.CoAP;
@@ -29,9 +30,14 @@ import org.junit.Test;
public class CoAPComponentTest extends CoAPTestSupport {
+ protected static final int TCP_PORT = AvailablePortFinder.getNextAvailable();
+
@Produce("direct:start")
protected ProducerTemplate sender;
-
+
+ @Produce("direct:starttcp")
+ protected ProducerTemplate tcpSender;
+
@Test
public void testCoAPComponent() throws Exception {
CoapClient client = createClient("/TestResource");
@@ -47,6 +53,17 @@ public class CoAPComponentTest extends CoAPTestSupport {
assertMockEndpointsSatisfied();
}
+ @Test
+ public void testCoAPComponentTLS() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedMinimumMessageCount(1);
+ mock.expectedBodiesReceived("Hello Camel CoAP");
+ mock.expectedHeaderReceived(Exchange.CONTENT_TYPE, MediaTypeRegistry.toString(MediaTypeRegistry.APPLICATION_OCTET_STREAM));
+ mock.expectedHeaderReceived(CoAPConstants.COAP_RESPONSE_CODE, CoAP.ResponseCode.CONTENT.toString());
+ tcpSender.sendBody("Camel CoAP");
+ assertMockEndpointsSatisfied();
+ }
+
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@@ -56,10 +73,19 @@ public class CoAPComponentTest extends CoAPTestSupport {
.convertBodyTo(String.class)
.transform(body().prepend("Hello "));
+ fromF("coap+tcp://localhost:%d/TestResource", TCP_PORT)
+ .convertBodyTo(String.class)
+ .transform(body().prepend("Hello "));
+
from("direct:start")
.toF("coap://localhost:%d/TestResource", PORT)
.to("mock:result");
+
+ from("direct:starttcp")
+ .toF("coap+tcp://localhost:%d/TestResource", TCP_PORT)
+ .to("mock:result");
}
};
}
+
}
diff --git a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPRestComponentTCPTest.java b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPRestComponentTCPTest.java
new file mode 100644
index 0000000..bd85eec
--- /dev/null
+++ b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPRestComponentTCPTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.camel.coap;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.AvailablePortFinder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.eclipse.californium.core.CoapClient;
+import org.eclipse.californium.core.CoapResponse;
+import org.eclipse.californium.core.coap.CoAP.ResponseCode;
+import org.eclipse.californium.core.coap.MediaTypeRegistry;
+import org.eclipse.californium.core.network.CoapEndpoint;
+import org.eclipse.californium.core.network.config.NetworkConfig;
+import org.eclipse.californium.elements.tcp.TcpClientConnector;
+import org.junit.Test;
+
+public class CoAPRestComponentTCPTest extends CamelTestSupport {
+ static int coapport = AvailablePortFinder.getNextAvailable();
+
+ @Test
+ public void testCoAP() throws Exception {
+ NetworkConfig.createStandardWithoutFile();
+ CoapClient client;
+ CoapResponse rsp;
+
+ client = new CoapClient("coap+tcp://localhost:" + coapport + "/TestResource/Ducky");
+ decorateWithTCP(client);
+ rsp = client.get();
+ assertEquals(ResponseCode.CONTENT, rsp.getCode());
+ assertEquals("Hello Ducky", rsp.getResponseText());
+ rsp = client.post("data", MediaTypeRegistry.TEXT_PLAIN);
+ assertEquals(ResponseCode.CONTENT, rsp.getCode());
+ assertEquals("Hello Ducky: data", rsp.getResponseText());
+
+ client = new CoapClient("coap+tcp://localhost:" + coapport + "/TestParams?id=Ducky");
+ decorateWithTCP(client);
+ client.setTimeout(1000000L);
+ rsp = client.get();
+ assertEquals(ResponseCode.CONTENT, rsp.getCode());
+ assertEquals("Hello Ducky", rsp.getResponseText());
+ rsp = client.post("data", MediaTypeRegistry.TEXT_PLAIN);
+ assertEquals(ResponseCode.CONTENT, rsp.getCode());
+ assertEquals("Hello Ducky: data", rsp.getResponseText());
+ assertEquals(MediaTypeRegistry.TEXT_PLAIN, rsp.getOptions().getContentFormat());
+ }
+
+ @Test
+ public void testCoAPMethodNotAllowedResponse() throws Exception {
+ NetworkConfig.createStandardWithoutFile();
+ CoapClient client = new CoapClient("coap+tcp://localhost:" + coapport + "/TestResource/Ducky");
+ decorateWithTCP(client);
+ client.setTimeout(1000000L);
+ CoapResponse rsp = client.delete();
+ assertEquals(ResponseCode.METHOD_NOT_ALLOWED, rsp.getCode());
+ }
+
+ @Test
+ public void testCoAPNotFoundResponse() throws Exception {
+ NetworkConfig.createStandardWithoutFile();
+ CoapClient client = new CoapClient("coap+tcp://localhost:" + coapport + "/foo/bar/cheese");
+ decorateWithTCP(client);
+ client.setTimeout(1000000L);
+ CoapResponse rsp = client.get();
+ assertEquals(ResponseCode.NOT_FOUND, rsp.getCode());
+ }
+
+ private void decorateWithTCP(CoapClient client) {
+ NetworkConfig config = NetworkConfig.createStandardWithoutFile();
+ int tcpThreads = config.getInt(NetworkConfig.Keys.TCP_WORKER_THREADS);
+ int tcpConnectTimeout = config.getInt(NetworkConfig.Keys.TCP_CONNECT_TIMEOUT);
+ int tcpIdleTimeout = config.getInt(NetworkConfig.Keys.TCP_CONNECTION_IDLE_TIMEOUT);
+ TcpClientConnector tcpConnector = new TcpClientConnector(tcpThreads, tcpConnectTimeout, tcpIdleTimeout);
+ CoapEndpoint.Builder tcpBuilder = new CoapEndpoint.Builder();
+ tcpBuilder.setConnector(tcpConnector);
+
+ client.setEndpoint(tcpBuilder.build());
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ restConfiguration("coap").scheme("coap+tcp").host("localhost").port(coapport);
+
+ rest("/TestParams")
+ .get().to("direct:get1")
+ .post().to("direct:post1");
+
+ rest("/TestResource")
+ .get("/{id}").to("direct:get1")
+ .post("/{id}").to("direct:post1");
+
+ from("direct:get1").process(new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ String id = exchange.getIn().getHeader("id", String.class);
+ exchange.getOut().setBody("Hello " + id);
+ }
+ });
+
+ from("direct:post1").process(new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ String id = exchange.getIn().getHeader("id", String.class);
+ String ct = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
+ if (!"text/plain".equals(ct)) {
+ throw new Exception("No content type");
+ }
+ exchange.getOut().setBody("Hello " + id + ": " + exchange.getIn().getBody(String.class));
+ exchange.getOut().setHeader(Exchange.CONTENT_TYPE, ct);
+ }
+ });
+ }
+ };
+ }
+}
diff --git a/platforms/spring-boot/components-starter/camel-coap-starter/src/main/java/org/apache/camel/coap/springboot/CoAPComponentAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-coap-starter/src/main/java/org/apache/camel/coap/springboot/CoAPComponentAutoConfiguration.java
index 028d594..dcfba25 100644
--- a/platforms/spring-boot/components-starter/camel-coap-starter/src/main/java/org/apache/camel/coap/springboot/CoAPComponentAutoConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-coap-starter/src/main/java/org/apache/camel/coap/springboot/CoAPComponentAutoConfiguration.java
@@ -75,7 +75,7 @@ public class CoAPComponentAutoConfiguration {
}
@Lazy
- @Bean(name = "coap-component")
+ @Bean({"coap-component", "coap+tcp-component", "coaps-component", "coaps+tcp-component"})
@ConditionalOnMissingBean(CoAPComponent.class)
public CoAPComponent configureCoAPComponent() throws Exception {
CoAPComponent component = new CoAPComponent();