diff --git a/client/client-multi/client-java-core/pom.xml b/client/client-multi/client-java-core/pom.xml index 0855f9ebbe..5eac3b8935 100644 --- a/client/client-multi/client-java-core/pom.xml +++ b/client/client-multi/client-java-core/pom.xml @@ -90,6 +90,16 @@ org.apache.avro avro + + org.eclipse.californium + californium-core + 2.0.0-M2 + + + org.eclipse.californium + element-connector + 2.0.0-M2 + diff --git a/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java index 2b683c3230..00db66904b 100644 --- a/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java +++ b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java @@ -33,6 +33,13 @@ public class TransportProtocolIdConstants { private static final int TCP_TRANSPORT_PROTOCOL_VERSION = 1; public static final TransportProtocolId TCP_TRANSPORT_ID = new TransportProtocolId( TCP_TRANSPORT_PROTOCOL_ID, TCP_TRANSPORT_PROTOCOL_VERSION); + private static final int COAP_TRANSPORT_PROTOCOL_ID = 0x0b5d1174; + private static final int COAP_TRANSPORT_PROTOCOL_VERSION = 1; + public static final TransportProtocolId COAP_TRANSPORT_ID = new TransportProtocolId( + COAP_TRANSPORT_PROTOCOL_ID, COAP_TRANSPORT_PROTOCOL_VERSION); + + + private TransportProtocolIdConstants() { } diff --git a/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/impl/channels/CoapChannel.java b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/impl/channels/CoapChannel.java new file mode 100644 index 0000000000..beae9e6665 --- /dev/null +++ b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/impl/channels/CoapChannel.java @@ -0,0 +1,244 @@ +/* + * + * Licensed 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.kaaproject.kaa.client.channel.impl.channels; + +import org.eclipse.californium.core.CoapClient; +import org.eclipse.californium.core.CoapResponse; +import org.eclipse.californium.core.Utils; +import org.eclipse.californium.core.coap.MediaTypeRegistry; +import org.kaaproject.kaa.client.channel.ChannelDirection; +import org.kaaproject.kaa.client.channel.IpTransportInfo; +import org.kaaproject.kaa.client.channel.KaaDataChannel; +import org.kaaproject.kaa.client.channel.KaaDataDemultiplexer; +import org.kaaproject.kaa.client.channel.KaaDataMultiplexer; +import org.kaaproject.kaa.client.channel.ServerType; +import org.kaaproject.kaa.client.channel.TransportConnectionInfo; +import org.kaaproject.kaa.client.channel.TransportProtocolId; +import org.kaaproject.kaa.client.channel.TransportProtocolIdConstants; + +import org.kaaproject.kaa.client.channel.connectivity.ConnectivityChecker; +import org.kaaproject.kaa.common.TransportType; +import org.kaaproject.kaa.common.endpoint.security.MessageEncoderDecoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + + +public class CoapChannel implements KaaDataChannel { + + public static final Logger LOG = LoggerFactory // NOSONAR + .getLogger(CoapChannel.class); + + private static final Map SUPPORTED_TYPES = new HashMap(); + + static { + SUPPORTED_TYPES.put(TransportType.PROFILE, ChannelDirection.BIDIRECTIONAL); + SUPPORTED_TYPES.put(TransportType.CONFIGURATION, ChannelDirection.BIDIRECTIONAL); + SUPPORTED_TYPES.put(TransportType.NOTIFICATION, ChannelDirection.BIDIRECTIONAL); + } + + private static final String CHANNEL_ID = "default_coap_channel"; + private KaaDataDemultiplexer demultiplexer; + private KaaDataMultiplexer multiplexer; + private IpTransportInfo currentServer; + + @Override + public void sync(TransportType type) { + sync(Collections.singleton(type)); + } + + @Override + public void sync(Set types) { + + if (multiplexer == null) { + LOG.warn("Can't sync. Channel {} multiplexer is not set", getId()); + return; + } + if (demultiplexer == null) { + LOG.warn("Can't sync. Channel {} demultiplexer is not set", getId()); + return; + } + + Map typeMap = new HashMap<>(getSupportedTransportTypes().size()); + for (TransportType type : types) { + LOG.info("Processing sync {} for channel [{}]", type, getId()); + ChannelDirection direction = getSupportedTransportTypes().get(type); + if (direction != null) { + typeMap.put(type, direction); + } else { + LOG.error("Unsupported type {} for channel [{}]", type, getId()); + } + for (Map.Entry typeIt : getSupportedTransportTypes().entrySet()) { + if (!typeIt.getKey().equals(type)) { + typeMap.put(typeIt.getKey(), ChannelDirection.DOWN); + } + } + } + + } + + @Override + public void syncAll() { + } + + @Override + public void syncAck(TransportType type) { + LOG.info("Adding sync acknowledgement for type {} as a regular sync for channel [{}]", type, getId()); + syncAck(Collections.singleton(type)); + } + + @Override + public void syncAck(Set type) { + } + + @Override + public String getId() { + return CHANNEL_ID; + } + + @Override + public TransportProtocolId getTransportProtocolId() { + return TransportProtocolIdConstants.COAP_TRANSPORT_ID; + } + + @Override + public ServerType getServerType() { + return ServerType.OPERATIONS; + } + + @Override + public void setDemultiplexer(KaaDataDemultiplexer demultiplexer) { + if (demultiplexer != null) { + this.demultiplexer = demultiplexer; + } + } + + @Override + public void setMultiplexer(KaaDataMultiplexer multiplexer) { + if (multiplexer != null) { + this.multiplexer = multiplexer; + } + } + + @Override + public void setServer(TransportConnectionInfo server) { + + LOG.info("Setting server [{}] for channel [{}]", server, getId()); + if (server == null) { + LOG.warn("Server is null for Channel [{}].", getId()); + return; + } + + IpTransportInfo oldServer = currentServer; + this.currentServer = new IpTransportInfo(server); + + } + + @Override + public TransportConnectionInfo getServer() { + return currentServer; + + } + + @Override + public void setConnectivityChecker(ConnectivityChecker checker) { + } + + @Override + public Map getSupportedTransportTypes() { + return SUPPORTED_TYPES; + } + + @Override + public void shutdown() { + } + + @Override + public void pause() { + } + + @Override + public void resume() { + } + + /** + * + * @param myUri uri of source + * @param method CoAP method like POST,GET,... + * @param payload Message Payload + * @param msgType Confirmable or Non confirmable + * @return server response + */ + public CoapResponse sendData(String myUri, String method, String payload, String msgType) { + LOG.info("this is SendData function!"); + URI uri = null; + + if (myUri != null) { + // input URI from command line arguments + try { + uri = new URI(myUri); + } catch (URISyntaxException exception) { + LOG.info("Invalid URI: " + exception.getMessage()); + } + + CoapClient client = new CoapClient(uri); + LOG.info(" new coap client is registerd"); + + CoapResponse response; + + if (msgType == "NON") { + client.useNONs(); + } else { + client.useCONs(); + } + + if (method == "post") { + response = client.post(payload, MediaTypeRegistry.TEXT_PLAIN); + } else { + response = client.get(); + } + + if (response != null) { + + LOG.info(String.valueOf(response.getCode())); + LOG.info(String.valueOf(response.getOptions())); + LOG.info(response.getResponseText()); + + LOG.info("\nADVANCED\n"); + // access advanced API with access to more details through .advanced() + LOG.info(Utils.prettyPrint(response)); + + } else { + LOG.info("No response received."); + } + + return response; + } else { + // display help + LOG.info("Californium Client"); + String simpleName = CoapChannel.class.getSimpleName(); + LOG.info("Usage: " + simpleName + " URI"); + LOG.info("URI: The CoAP URI of the remote resource to GET"); + return null; + } + } +} diff --git a/pom.xml b/pom.xml index a99bcca2e9..6ee5943bed 100644 --- a/pom.xml +++ b/pom.xml @@ -1439,5 +1439,10 @@ Copyright 2014-2016 CyberVision, Inc. repository.kaaproject.snapshots http://repository.kaaproject.org/repository/snapshots/ + + repo.eclipse.org + Californium Repository + https://repo.eclipse.org/content/repositories/californium/ + diff --git a/server/node/pom.xml b/server/node/pom.xml index c8862fbbd0..aa6ee86c22 100644 --- a/server/node/pom.xml +++ b/server/node/pom.xml @@ -101,6 +101,20 @@ config tcp + + + org.kaaproject.kaa.server.transports.coap + transport + 0.11.0-SNAPSHOT + coap + + + org.kaaproject.kaa.server.transports.coap + config + 0.11.0-SNAPSHOT + coap + + org.kaaproject.kaa.server.common log-shared diff --git a/server/transports/coap/config/pom.xml b/server/transports/coap/config/pom.xml new file mode 100644 index 0000000000..ea0ec310f6 --- /dev/null +++ b/server/transports/coap/config/pom.xml @@ -0,0 +1,97 @@ + + + + 4.0.0 + + org.kaaproject.kaa.server.transports + 0.11.0-SNAPSHOT + coap + + org.kaaproject.kaa.server.transports.coap + config + jar + + Kaa HTTP Transport Config + http://kaaproject.org + + + UTF-8 + ${basedir}/../../../.. + + + + + org.kaaproject.kaa.server.common + transport-shared + + + org.kaaproject.kaa.server.common + utils + + + org.slf4j + slf4j-api + + + org.slf4j + log4j-over-slf4j + + + ch.qos.logback + logback-core + + + ch.qos.logback + logback-classic + + + + + + + org.apache.avro + avro-maven-plugin + ${avro.version} + + + generate-sources + + schema + + + String + ${project.basedir}/src/main/avro/ + ${project.basedir}/src/main/java/ + PRIVATE + + *.avsc + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + coap + + + + + \ No newline at end of file diff --git a/server/transports/coap/config/src/main/avro/coap.avsc b/server/transports/coap/config/src/main/avro/coap.avsc new file mode 100644 index 0000000000..8cad291a6b --- /dev/null +++ b/server/transports/coap/config/src/main/avro/coap.avsc @@ -0,0 +1,12 @@ +{ + "namespace": "org.kaaproject.kaa.server.transport.coap.config.gen", + "type": "record", + "name": "AvroCoapConfig", + "fields": [ + {"name": "bindInterface", "type": "string"}, + {"name": "bindPort", "type": "int"}, + {"name": "publicInterface", "type": "string"}, + {"name": "publicPort", "type": "int"}, + {"name": "maxBodySize", "type": "int"} + ] +} \ No newline at end of file diff --git a/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/CoapTransportConfig.java b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/CoapTransportConfig.java new file mode 100644 index 0000000000..bbf487de51 --- /dev/null +++ b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/CoapTransportConfig.java @@ -0,0 +1,94 @@ +/* + * + * Licensed 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.kaaproject.kaa.server.transport.coap.config; + +import org.apache.avro.Schema; +import org.kaaproject.kaa.server.common.utils.Crc32Util; +import org.kaaproject.kaa.server.transport.KaaTransportConfig; +import org.kaaproject.kaa.server.transport.Transport; +import org.kaaproject.kaa.server.transport.TransportConfig; +import org.kaaproject.kaa.server.transport.TransportService; +import org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig; + + +/** + * All-args constructor. + */ +@KaaTransportConfig +public class CoapTransportConfig implements TransportConfig { + + private static final String COAP_TRANSPORT_NAME = "org.kaaproject.kaa.server.transport.coap"; + private static final int COAP_TRANSPORT_ID = Crc32Util.crc32(COAP_TRANSPORT_NAME); + private static final String COAP_TRANSPORT_CLASS = "org.kaaproject.kaa.server.transports.coap.transport.CoapTransport"; + private static final String COAP_TRANSPORT_CONFIG = "coap-transport.config"; + + public CoapTransportConfig() { + super(); + } + + /** + * Returns the transport id. The transport id must be unique. + * + * @return the transport id + */ + @Override + public int getId() { + return COAP_TRANSPORT_ID; + } + + /** + * Returns the transport name. There is no strict rule for this + * name to be unique. + * + * @return the transport name + */ + @Override + public String getName() { + return COAP_TRANSPORT_NAME; + } + + /** + * Returns the class name of the {@link Transport} implementation. + * + * @return the class name of the {@link Transport} implementation + */ + @Override + public String getTransportClass() { + return COAP_TRANSPORT_CLASS; + } + + /** + * Returns the avro schema of the {@link Transport} configuration. + * + * @return the avro schema of the {@link Transport} configuration + */ + @Override + public Schema getConfigSchema() { + return AvroCoapConfig.getClassSchema(); + } + + /** + * Returns the configuration file name. This configuration file may + * be used by {@link TransportService} to initialize and configure + * the corresponding {@link Transport}. + * + * @return the configuration file name + */ + @Override + public String getConfigFileName() { + return COAP_TRANSPORT_CONFIG; + } +} \ No newline at end of file diff --git a/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/gen/AvroCoapConfig.java b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/gen/AvroCoapConfig.java new file mode 100644 index 0000000000..5c7905bc9c --- /dev/null +++ b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/gen/AvroCoapConfig.java @@ -0,0 +1,355 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package org.kaaproject.kaa.server.transport.coap.config.gen; +@SuppressWarnings("all") +@org.apache.avro.specific.AvroGenerated +public class AvroCoapConfig extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"AvroCoapConfig\",\"namespace\":\"org.kaaproject.kaa.server.transport.coap.config.gen\",\"fields\":[{\"name\":\"bindInterface\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"bindPort\",\"type\":\"int\"},{\"name\":\"publicInterface\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"publicPort\",\"type\":\"int\"},{\"name\":\"maxBodySize\",\"type\":\"int\"}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + private java.lang.String bindInterface; + private int bindPort; + private java.lang.String publicInterface; + private int publicPort; + private int maxBodySize; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use {@link \#newBuilder()}. + */ + public AvroCoapConfig() {} + + /** + * All-args constructor. + */ + public AvroCoapConfig(java.lang.String bindInterface, java.lang.Integer bindPort, java.lang.String publicInterface, java.lang.Integer publicPort, java.lang.Integer maxBodySize) { + this.bindInterface = bindInterface; + this.bindPort = bindPort; + this.publicInterface = publicInterface; + this.publicPort = publicPort; + this.maxBodySize = maxBodySize; + } + + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return bindInterface; + case 1: return bindPort; + case 2: return publicInterface; + case 3: return publicPort; + case 4: return maxBodySize; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: bindInterface = (java.lang.String)value$; break; + case 1: bindPort = (java.lang.Integer)value$; break; + case 2: publicInterface = (java.lang.String)value$; break; + case 3: publicPort = (java.lang.Integer)value$; break; + case 4: maxBodySize = (java.lang.Integer)value$; break; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + /** + * Gets the value of the 'bindInterface' field. + */ + public java.lang.String getBindInterface() { + return bindInterface; + } + + /** + * Sets the value of the 'bindInterface' field. + * @param value the value to set. + */ + public void setBindInterface(java.lang.String value) { + this.bindInterface = value; + } + + /** + * Gets the value of the 'bindPort' field. + */ + public java.lang.Integer getBindPort() { + return bindPort; + } + + /** + * Sets the value of the 'bindPort' field. + * @param value the value to set. + */ + public void setBindPort(java.lang.Integer value) { + this.bindPort = value; + } + + /** + * Gets the value of the 'publicInterface' field. + */ + public java.lang.String getPublicInterface() { + return publicInterface; + } + + /** + * Sets the value of the 'publicInterface' field. + * @param value the value to set. + */ + public void setPublicInterface(java.lang.String value) { + this.publicInterface = value; + } + + /** + * Gets the value of the 'publicPort' field. + */ + public java.lang.Integer getPublicPort() { + return publicPort; + } + + /** + * Sets the value of the 'publicPort' field. + * @param value the value to set. + */ + public void setPublicPort(java.lang.Integer value) { + this.publicPort = value; + } + + /** + * Gets the value of the 'maxBodySize' field. + */ + public java.lang.Integer getMaxBodySize() { + return maxBodySize; + } + + /** + * Sets the value of the 'maxBodySize' field. + * @param value the value to set. + */ + public void setMaxBodySize(java.lang.Integer value) { + this.maxBodySize = value; + } + + /** Creates a new AvroCoapConfig RecordBuilder */ + public static org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder newBuilder() { + return new org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder(); + } + + /** Creates a new AvroCoapConfig RecordBuilder by copying an existing Builder */ + public static org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder newBuilder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder other) { + return new org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder(other); + } + + /** Creates a new AvroCoapConfig RecordBuilder by copying an existing AvroCoapConfig instance */ + public static org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder newBuilder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig other) { + return new org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder(other); + } + + /** + * RecordBuilder for AvroCoapConfig instances. + */ + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.String bindInterface; + private int bindPort; + private java.lang.String publicInterface; + private int publicPort; + private int maxBodySize; + + /** Creates a new Builder */ + private Builder() { + super(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.SCHEMA$); + } + + /** Creates a Builder by copying an existing Builder */ + private Builder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder other) { + super(other); + if (isValidValue(fields()[0], other.bindInterface)) { + this.bindInterface = data().deepCopy(fields()[0].schema(), other.bindInterface); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.bindPort)) { + this.bindPort = data().deepCopy(fields()[1].schema(), other.bindPort); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.publicInterface)) { + this.publicInterface = data().deepCopy(fields()[2].schema(), other.publicInterface); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.publicPort)) { + this.publicPort = data().deepCopy(fields()[3].schema(), other.publicPort); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.maxBodySize)) { + this.maxBodySize = data().deepCopy(fields()[4].schema(), other.maxBodySize); + fieldSetFlags()[4] = true; + } + } + + /** Creates a Builder by copying an existing AvroCoapConfig instance */ + private Builder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig other) { + super(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.SCHEMA$); + if (isValidValue(fields()[0], other.bindInterface)) { + this.bindInterface = data().deepCopy(fields()[0].schema(), other.bindInterface); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.bindPort)) { + this.bindPort = data().deepCopy(fields()[1].schema(), other.bindPort); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.publicInterface)) { + this.publicInterface = data().deepCopy(fields()[2].schema(), other.publicInterface); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.publicPort)) { + this.publicPort = data().deepCopy(fields()[3].schema(), other.publicPort); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.maxBodySize)) { + this.maxBodySize = data().deepCopy(fields()[4].schema(), other.maxBodySize); + fieldSetFlags()[4] = true; + } + } + + /** Gets the value of the 'bindInterface' field */ + public java.lang.String getBindInterface() { + return bindInterface; + } + + /** Sets the value of the 'bindInterface' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setBindInterface(java.lang.String value) { + validate(fields()[0], value); + this.bindInterface = value; + fieldSetFlags()[0] = true; + return this; + } + + /** Checks whether the 'bindInterface' field has been set */ + public boolean hasBindInterface() { + return fieldSetFlags()[0]; + } + + /** Clears the value of the 'bindInterface' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearBindInterface() { + bindInterface = null; + fieldSetFlags()[0] = false; + return this; + } + + /** Gets the value of the 'bindPort' field */ + public java.lang.Integer getBindPort() { + return bindPort; + } + + /** Sets the value of the 'bindPort' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setBindPort(int value) { + validate(fields()[1], value); + this.bindPort = value; + fieldSetFlags()[1] = true; + return this; + } + + /** Checks whether the 'bindPort' field has been set */ + public boolean hasBindPort() { + return fieldSetFlags()[1]; + } + + /** Clears the value of the 'bindPort' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearBindPort() { + fieldSetFlags()[1] = false; + return this; + } + + /** Gets the value of the 'publicInterface' field */ + public java.lang.String getPublicInterface() { + return publicInterface; + } + + /** Sets the value of the 'publicInterface' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setPublicInterface(java.lang.String value) { + validate(fields()[2], value); + this.publicInterface = value; + fieldSetFlags()[2] = true; + return this; + } + + /** Checks whether the 'publicInterface' field has been set */ + public boolean hasPublicInterface() { + return fieldSetFlags()[2]; + } + + /** Clears the value of the 'publicInterface' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearPublicInterface() { + publicInterface = null; + fieldSetFlags()[2] = false; + return this; + } + + /** Gets the value of the 'publicPort' field */ + public java.lang.Integer getPublicPort() { + return publicPort; + } + + /** Sets the value of the 'publicPort' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setPublicPort(int value) { + validate(fields()[3], value); + this.publicPort = value; + fieldSetFlags()[3] = true; + return this; + } + + /** Checks whether the 'publicPort' field has been set */ + public boolean hasPublicPort() { + return fieldSetFlags()[3]; + } + + /** Clears the value of the 'publicPort' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearPublicPort() { + fieldSetFlags()[3] = false; + return this; + } + + /** Gets the value of the 'maxBodySize' field */ + public java.lang.Integer getMaxBodySize() { + return maxBodySize; + } + + /** Sets the value of the 'maxBodySize' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setMaxBodySize(int value) { + validate(fields()[4], value); + this.maxBodySize = value; + fieldSetFlags()[4] = true; + return this; + } + + /** Checks whether the 'maxBodySize' field has been set */ + public boolean hasMaxBodySize() { + return fieldSetFlags()[4]; + } + + /** Clears the value of the 'maxBodySize' field */ + public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearMaxBodySize() { + fieldSetFlags()[4] = false; + return this; + } + + @Override + public AvroCoapConfig build() { + try { + AvroCoapConfig record = new AvroCoapConfig(); + record.bindInterface = fieldSetFlags()[0] ? this.bindInterface : (java.lang.String) defaultValue(fields()[0]); + record.bindPort = fieldSetFlags()[1] ? this.bindPort : (java.lang.Integer) defaultValue(fields()[1]); + record.publicInterface = fieldSetFlags()[2] ? this.publicInterface : (java.lang.String) defaultValue(fields()[2]); + record.publicPort = fieldSetFlags()[3] ? this.publicPort : (java.lang.Integer) defaultValue(fields()[3]); + record.maxBodySize = fieldSetFlags()[4] ? this.maxBodySize : (java.lang.Integer) defaultValue(fields()[4]); + return record; + } catch (Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } +} diff --git a/server/transports/coap/pom.xml b/server/transports/coap/pom.xml new file mode 100644 index 0000000000..b69684181a --- /dev/null +++ b/server/transports/coap/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + + org.kaaproject.kaa.server + 0.11.0-SNAPSHOT + transports + + + org.kaaproject.kaa.server.transports + coap + 0.11.0-SNAPSHOT + pom + + + Kaa CoAP Transport + http://kaaproject.org + + + UTF-8 + /kaa + + + + config + transport + + + + + \ No newline at end of file diff --git a/server/transports/coap/transport/pom.xml b/server/transports/coap/transport/pom.xml new file mode 100644 index 0000000000..7db662cbcc --- /dev/null +++ b/server/transports/coap/transport/pom.xml @@ -0,0 +1,102 @@ + + + + 4.0.0 + + org.kaaproject.kaa.server.transports + 0.11.0-SNAPSHOT + coap + + org.kaaproject.kaa.server.transports.coap + transport + jar + + Kaa CoAP Transports Implementation + http://kaaproject.org + + + UTF-8 + /kaa + + + + repo.eclipse.org + Californium Repository + https://repo.eclipse.org/content/repositories/californium/ + + + + + + org.kaaproject.kaa.server.common + transport-shared + + + org.kaaproject.kaa.server.common + netty-server + + + org.kaaproject.kaa.server.transports.coap + config + 0.11.0-SNAPSHOT + coap + + + commons-codec + commons-codec + + + junit + junit + test + + + org.mockito + mockito-all + test + + + org.springframework + spring-test + + + + org.eclipse.californium + californium-core + 2.0.0-M2 + + + org.eclipse.californium + element-connector + 2.0.0-M2 + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + coap + + + + + diff --git a/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapHandler.java b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapHandler.java new file mode 100644 index 0000000000..34cc737bbd --- /dev/null +++ b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapHandler.java @@ -0,0 +1,103 @@ +/* + * + * Licensed 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.kaaproject.kaa.server.transports.coap.transport; + +import org.eclipse.californium.core.CoapResource; +import org.eclipse.californium.core.CoapServer; +import org.eclipse.californium.core.network.CoapEndpoint; +import org.eclipse.californium.core.network.EndpointManager; +import org.eclipse.californium.core.network.config.NetworkConfig; +import org.eclipse.californium.core.server.resources.CoapExchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketException; + +public class CoapHandler extends CoapServer { + + private static int COAP_PORT = NetworkConfig.getStandard().getInt(NetworkConfig.Keys.COAP_PORT); + private static final Logger LOG = LoggerFactory.getLogger(CoapHandler.class); + + /** + * Add individual endpoints listening on default CoAP port on all IPv4 addresses of all network interfaces. + */ + private void addEndpoints() { + for (InetAddress addr : EndpointManager.getEndpointManager().getNetworkInterfaces()) { + // only binds to IPv4 addresses and localhost + if (addr instanceof Inet4Address || addr.isLoopbackAddress()) { + InetSocketAddress bindToAddress = new InetSocketAddress(addr, COAP_PORT); + addEndpoint(new CoapEndpoint(bindToAddress)); + } + } + } + + /** + * Handler add endpoints and resources. + * @param port listen port of CoAP server + * @throws SocketException socket exception + */ + public CoapHandler(int port) throws SocketException { + // provide an instance of a Hello-World resource + add(new HelloWorldResource()); + COAP_PORT = port; + addEndpoints(); + LOG.info("New Resource and endpoints added."); + } + + /* + * Definition of the Hello-World Resource + */ + class HelloWorldResource extends CoapResource { + + public HelloWorldResource() { + + // set resource identifier + super("kaaCoAP"); + + // set display name + getAttributes().setTitle("Kaa-Coap Resource"); + LOG.info("Resource identifier and display name is set."); + + + } + + + @Override + public void handleGET(CoapExchange exchange) { + //sample respond to the request is like this: + + // exchange.respond("Hello World! This is a response from Kaa Coap Server!"); + LOG.info("GET method handler."); + + } + + + @Override + public void handlePOST(CoapExchange exchange) { + + //sample respond to the request is like this: + + // exchange.respond("Hello World! This is a response from Kaa Coap Server!"); + LOG.info("POST method handler."); + + + } + } + +} diff --git a/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapTransport.java b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapTransport.java new file mode 100644 index 0000000000..ce4c67a107 --- /dev/null +++ b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapTransport.java @@ -0,0 +1,138 @@ +/* + * + * Licensed 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.kaaproject.kaa.server.transports.coap.transport; + +import org.kaaproject.kaa.server.transport.AbstractKaaTransport; +import org.kaaproject.kaa.server.transport.SpecificTransportContext; +import org.kaaproject.kaa.server.transport.TransportLifecycleException; +import org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class CoapTransport extends AbstractKaaTransport { + + private static final Logger LOG = LoggerFactory.getLogger(CoapTransport.class); + private static final int SUPPORTED_VERSION = 1; + + private CoapHandler server; + + /** + * Initialize a transport instance with a particular configuration and + * common transport properties that are accessible via the context. The configuration is an Avro + * object. The serializaion/deserialization is done using the schema specified in + * {@link org.kaaproject.kaa.server.transport.KaaTransportConfig}. + * @param context the transport initialization context + * @throws TransportLifecycleException is socket exception. + */ + @Override + protected void init(SpecificTransportContext context) throws TransportLifecycleException { + + AvroCoapConfig configuration = context.getConfiguration(); + configuration.setBindInterface(replaceProperty(configuration.getBindInterface(), BIND_INTERFACE_PROP_NAME, context + .getCommonProperties().getProperty(BIND_INTERFACE_PROP_NAME, LOCALHOST))); + configuration.setPublicInterface(replaceProperty(configuration.getPublicInterface(), PUBLIC_INTERFACE_PROP_NAME, context + .getCommonProperties().getProperty(PUBLIC_INTERFACE_PROP_NAME, LOCALHOST))); + + + try { + // create server + server = new CoapHandler(configuration.getBindPort()); + + + + } catch (SocketException exception) { + System.err.println("Failed to initialize server: " + exception.getMessage()); + } + + } + + /** + * Starts a transport instance. This method should block its caller thread + * until the transport is started. This method should not block its caller + * thread after the startup sequence is successfully completed. + */ + @Override + public void start() { + + LOG.info("CoAP server is going to start"); + server.start(); + LOG.info("CoAP server is started!"); + + } + + /** + * Stops the transport instance. This method should block its current thread + * until the transport is stopped. The transport may be started again after it is + * stopped. + */ + @Override + public void stop() { + + + LOG.info("CoAP server is going to stop"); + server.stop(); + + LOG.info("CoAP server is stopped"); + + } + + /** + * Returns a min version of the transport protocol that is supported by this transport. + * Useful when a single transport instance needs to support multiple versions of the client protocol implementations. + */ + @Override + protected int getMinSupportedVersion() { + return SUPPORTED_VERSION; + } + + /** + * Returns a max version of the transport protocol that is supported by this transport. + * Useful when a single transport instance needs to support multiple versions of the client protocol implementations. + */ + @Override + protected int getMaxSupportedVersion() { + return SUPPORTED_VERSION; + } + + @Override + public Class getConfigurationClass() { + return AvroCoapConfig.class; + } + + @Override + protected List getSerializedConnectionInfoList() { + byte[] interfaceData = toUtf8Bytes(context.getConfiguration().getPublicInterface()); + byte[] publicKeyData = context.getServerKey().getEncoded(); + ByteBuffer buf = ByteBuffer.wrap( + new byte[SIZE_OF_INT * 3 + interfaceData.length + publicKeyData.length]); + buf.putInt(publicKeyData.length); + buf.put(publicKeyData); + buf.putInt(interfaceData.length); + buf.put(interfaceData); + buf.putInt(context.getConfiguration().getPublicPort()); + List connectionInfoList = new ArrayList<>(); + connectionInfoList.add(buf.array()); + + return connectionInfoList; + } + + +} \ No newline at end of file diff --git a/server/transports/pom.xml b/server/transports/pom.xml index d12fc9c2bd..74d1f699d1 100644 --- a/server/transports/pom.xml +++ b/server/transports/pom.xml @@ -36,5 +36,6 @@ http tcp + coap