From da272ba679800a40fc643979210fd165c0a8d82a Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 19 Dec 2016 21:18:24 +0100 Subject: [PATCH 01/24] started #37 in data-common: move from org.json to jackson + java objects --- data/common/pom.xml | 6 +- .../data/common/AbstractClient.java | 70 +++++----- .../data/common/Metadata.java | 120 ++++++++++++++++++ .../common/events/AbstractEventHandler.java | 4 +- .../data/common/events/ActivationHandler.java | 4 +- .../data/common/events/UplinkHandler.java | 20 +-- .../ActivationMessage.java} | 39 ++++-- .../data/messages/DataMessage.java | 32 +++++ .../data/messages/DownlinkMessage.java | 59 +++++++++ .../data/messages/RawMessage.java | 62 +++++++++ .../data/messages/UplinkMessage.java | 68 ++++++++++ 11 files changed, 417 insertions(+), 67 deletions(-) create mode 100644 data/common/src/main/java/org/thethingsnetwork/data/common/Metadata.java rename data/common/src/main/java/org/thethingsnetwork/data/{common/Message.java => messages/ActivationMessage.java} (66%) create mode 100644 data/common/src/main/java/org/thethingsnetwork/data/messages/DataMessage.java create mode 100644 data/common/src/main/java/org/thethingsnetwork/data/messages/DownlinkMessage.java create mode 100644 data/common/src/main/java/org/thethingsnetwork/data/messages/RawMessage.java create mode 100644 data/common/src/main/java/org/thethingsnetwork/data/messages/UplinkMessage.java diff --git a/data/common/pom.xml b/data/common/pom.xml index 63a5bdd..86ee4b8 100644 --- a/data/common/pom.xml +++ b/data/common/pom.xml @@ -20,9 +20,9 @@ - org.json - json - 20160810 + com.fasterxml.jackson.core + jackson-databind + 2.8.3 diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java b/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java index ad41cde..d6b0327 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java @@ -23,17 +23,31 @@ */ package org.thethingsnetwork.data.common; -import java.nio.ByteBuffer; +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; import java.util.function.BiConsumer; import java.util.function.Consumer; -import org.json.JSONObject; +import org.thethingsnetwork.data.messages.ActivationMessage; +import org.thethingsnetwork.data.messages.DownlinkMessage; +import org.thethingsnetwork.data.messages.RawMessage; /** * This is an abstract representation of the methods any real-time TTN client should provide * * @author Romain Cambier */ -public interface AbstractClient { +public abstract class AbstractClient { + + public static final ObjectMapper MAPPER = new ObjectMapper(); + + static { + MAPPER + .setVisibility(PropertyAccessor.ALL, Visibility.NONE) + .setVisibility(PropertyAccessor.FIELD, Visibility.ANY) + .setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + } /** * Start the client @@ -41,7 +55,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient start() throws Exception; + public abstract AbstractClient start() throws Exception; /** * Stop the client, waiting for max 5000 ms @@ -49,7 +63,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient end() throws Exception; + public abstract AbstractClient end() throws Exception; /** * Stop the client, waiting for max the provided timeout @@ -58,7 +72,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient end(long _timeout) throws Exception; + public abstract AbstractClient end(long _timeout) throws Exception; /** * Force-stop the client in case end() does not work. @@ -66,27 +80,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient endNow() throws Exception; - - /** - * Send a downlink message using raw data - * - * @param _devId The devId to send the message to - * @param _payload The payload to be sent - * @param _port The port to use for the message - * @throws Exception in case something goes wrong - */ - public void send(String _devId, byte[] _payload, int _port) throws Exception; - - /** - * Send a downlink message using pre-registered encoder - * - * @param _devId The devId to send the message to - * @param _payload The payload to be sent - * @param _port The port to use for the message - * @throws Exception in case something goes wrong - */ - public void send(String _devId, JSONObject _payload, int _port) throws Exception; + public abstract AbstractClient endNow() throws Exception; /** * Send a downlink message using raw data @@ -96,7 +90,7 @@ public interface AbstractClient { * @param _port The port to use for the message * @throws Exception in case something goes wrong */ - public void send(String _devId, ByteBuffer _payload, int _port) throws Exception; + public abstract void send(String _devId, DownlinkMessage _payload, int _port) throws Exception; /** * Register a connection event handler @@ -105,7 +99,7 @@ public interface AbstractClient { * @return the Connection instance * @throws Exception in case something goes wrong */ - public AbstractClient onConnected(final Consumer _handler) throws Exception; + public abstract AbstractClient onConnected(final Consumer _handler) throws Exception; /** * Register an error event handler @@ -114,7 +108,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onError(final Consumer _handler) throws Exception; + public abstract AbstractClient onError(final Consumer _handler) throws Exception; /** * Register an uplink event handler using device and field filters @@ -125,7 +119,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onMessage(final String _devId, final String _field, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(final String _devId, final String _field, final BiConsumer _handler) throws Exception; /** * Register an uplink event handler using device filter @@ -135,7 +129,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onMessage(final String _devId, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(final String _devId, final BiConsumer _handler) throws Exception; /** * Register an uplink event handler @@ -144,7 +138,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onMessage(final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(final BiConsumer _handler) throws Exception; /** * Register an activation event handler using device filter @@ -154,7 +148,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onActivation(final String _devId, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onActivation(final String _devId, final BiConsumer _handler) throws Exception; /** * Register an activation event handler @@ -163,7 +157,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onActivation(final BiConsumer _handler) throws Exception; + public abstract AbstractClient onActivation(final BiConsumer _handler) throws Exception; /** * Register a default event handler using device and event filters @@ -174,7 +168,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onDevice(final String _devId, final String _event, final TriConsumer _handler) throws Exception; + public abstract AbstractClient onDevice(final String _devId, final String _event, final TriConsumer _handler) throws Exception; /** * Register a default event handler using device filter @@ -184,7 +178,7 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onDevice(final String _devId, final TriConsumer _handler) throws Exception; + public abstract AbstractClient onDevice(final String _devId, final TriConsumer _handler) throws Exception; /** * Register a default event handler @@ -193,6 +187,6 @@ public interface AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public AbstractClient onDevice(final TriConsumer _handler) throws Exception; + public abstract AbstractClient onDevice(final TriConsumer _handler) throws Exception; } diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/Metadata.java b/data/common/src/main/java/org/thethingsnetwork/data/common/Metadata.java new file mode 100644 index 0000000..6b80a83 --- /dev/null +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/Metadata.java @@ -0,0 +1,120 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.data.common; + +import java.util.Collections; +import java.util.List; + +/** + * + * @author Romain Cambier + */ +public class Metadata { + + private String time; + private double frequency; + private String modulation; + private String dataRate; + private String bitRate; + private String codingRate; + private List gateways; + + private Metadata() { + + } + + public String getTime() { + return time; + } + + public double getFrequency() { + return frequency; + } + + public String getModulation() { + return modulation; + } + + public String getDataRate() { + return dataRate; + } + + public String getBitRate() { + return bitRate; + } + + public String getCodingRate() { + return codingRate; + } + + public List getGateways() { + if (gateways == null) { + return null; + } + return Collections.unmodifiableList(gateways); + } + + public static class Gateway { + + private String id; + private long timestamp; + private String time; + private int channel; + private double rssi; + private double snr; + private int rfChain; + + private Gateway() { + + } + + public String getId() { + return id; + } + + public long getTimestamp() { + return timestamp; + } + + public String getTime() { + return time; + } + + public int getChannel() { + return channel; + } + + public double getRssi() { + return rssi; + } + + public double getSnr() { + return snr; + } + + public int getRfChain() { + return rfChain; + } + } +} diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java b/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java index 8f97d49..cdf9495 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java @@ -23,8 +23,8 @@ */ package org.thethingsnetwork.data.common.events; -import org.json.JSONObject; import org.thethingsnetwork.data.common.Subscribable; +import org.thethingsnetwork.data.messages.RawMessage; /** * @@ -32,7 +32,7 @@ */ public abstract class AbstractEventHandler implements EventHandler { - public abstract void handle(String _devId, String _event, JSONObject _data); + public abstract void handle(String _devId, String _event, RawMessage _data); public abstract String getDevId(); diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java b/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java index 864f8f6..00a8488 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java @@ -23,7 +23,7 @@ */ package org.thethingsnetwork.data.common.events; -import org.json.JSONObject; +import org.thethingsnetwork.data.messages.ActivationMessage; import org.thethingsnetwork.data.common.Subscribable; /** @@ -32,7 +32,7 @@ */ public abstract class ActivationHandler implements EventHandler { - public abstract void handle(String _devId, JSONObject _data); + public abstract void handle(String _devId, ActivationMessage _data); public abstract String getDevId(); diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java b/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java index 5362448..b67475b 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java @@ -23,8 +23,8 @@ */ package org.thethingsnetwork.data.common.events; -import org.thethingsnetwork.data.common.Message; import org.thethingsnetwork.data.common.Subscribable; +import org.thethingsnetwork.data.messages.DataMessage; /** * @@ -32,21 +32,25 @@ */ public abstract class UplinkHandler implements EventHandler { - public abstract void handle(String _devId, Object _data); + public abstract void handle(String _devId, DataMessage _data); public abstract String getDevId(); public abstract String getField(); - public boolean matches(String _devId) { - return getDevId() == null || _devId.equals(getDevId()); + public boolean isField() { + return getField() != null; } - public Object transform(String _data) { - if (getField() == null) { - return new Message(_data); + public boolean matches(String _devId, String _field) { + if (getDevId() != null && !getDevId().equals(_devId)) { + return false; + } + if (getField() != null) { + return !(_field == null || !getField().equals(_field)); + } else { + return _field == null; } - return _data; } @Override diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/Message.java b/data/common/src/main/java/org/thethingsnetwork/data/messages/ActivationMessage.java similarity index 66% rename from data/common/src/main/java/org/thethingsnetwork/data/common/Message.java rename to data/common/src/main/java/org/thethingsnetwork/data/messages/ActivationMessage.java index eea9d36..7845a79 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/Message.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/messages/ActivationMessage.java @@ -21,29 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.data.common; +package org.thethingsnetwork.data.messages; -import java.util.Base64; -import org.json.JSONException; -import org.json.JSONObject; +import org.thethingsnetwork.data.common.Metadata; /** - * This is a wrapper class for JSONObject to provide support for base64 encoded payload * * @author Romain Cambier */ -public class Message extends JSONObject { +public class ActivationMessage { - public byte[] getBinary(String _key) { - Object object = get(_key); - if (object instanceof String) { - return Base64.getDecoder().decode((String) object); - } - throw new JSONException("JSONObject[" + quote(_key) + "] is not a base64 decodable string."); + private String appEui; + private String devEui; + private String devAddr; + private Metadata metadata; + + private ActivationMessage(){ + } - public Message(String _source) { - super(_source); + public String getAppEui() { + return appEui; } + public String getDevEui() { + return devEui; + } + + public String getDevAddr() { + return devAddr; + } + + public Metadata getMetadata() { + return metadata; + } + + } diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/DataMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/messages/DataMessage.java new file mode 100644 index 0000000..4745ef7 --- /dev/null +++ b/data/common/src/main/java/org/thethingsnetwork/data/messages/DataMessage.java @@ -0,0 +1,32 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.data.messages; + +/** + * + * @author Romain Cambier + */ +public interface DataMessage { + +} diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/DownlinkMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/messages/DownlinkMessage.java new file mode 100644 index 0000000..0c9ac8a --- /dev/null +++ b/data/common/src/main/java/org/thethingsnetwork/data/messages/DownlinkMessage.java @@ -0,0 +1,59 @@ +/* + * Shareif.com CONFIDENTIAL + * ________________________ + * + * Copyright 2016 Shareif.com SPRL + * All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of Shareif.com SPRL and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to Shareif.com SPRL + * and its suppliers and may be covered by Belgian and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * Dissemination of this information or reproduction of this material + * is strictly forbidden unless prior written permission is obtained + * from Shareif.com SPRL. + */ +package org.thethingsnetwork.data.messages; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import java.nio.ByteBuffer; +import java.util.Base64; + +/** + * + * @author Romain Cambier + */ +@JsonInclude(Include.NON_NULL) +public class DownlinkMessage { + + private int port; + private String payloadRaw; + private Object payloadFields; + + public DownlinkMessage(int _port, String _payload) { + port = _port; + payloadRaw = _payload; + } + + public DownlinkMessage(int _port, byte[] _payload) { + port = _port; + payloadRaw = Base64.getEncoder().encodeToString(_payload); + } + + public DownlinkMessage(int _port, ByteBuffer _payload) { + port = _port; + _payload.rewind(); + byte[] payload = new byte[_payload.capacity() - _payload.remaining()]; + _payload.get(payload); + payloadRaw = Base64.getEncoder().encodeToString(payload); + } + + public DownlinkMessage(int _port, Object _payload) { + port = _port; + payloadFields = _payload; + } + +} diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/RawMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/messages/RawMessage.java new file mode 100644 index 0000000..9420d4f --- /dev/null +++ b/data/common/src/main/java/org/thethingsnetwork/data/messages/RawMessage.java @@ -0,0 +1,62 @@ +/* + * Shareif.com CONFIDENTIAL + * ________________________ + * + * Copyright 2016 Shareif.com SPRL + * All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of Shareif.com SPRL and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to Shareif.com SPRL + * and its suppliers and may be covered by Belgian and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * Dissemination of this information or reproduction of this material + * is strictly forbidden unless prior written permission is obtained + * from Shareif.com SPRL. + */ +package org.thethingsnetwork.data.messages; + +import java.io.IOException; +import org.thethingsnetwork.data.common.AbstractClient; + +/** + * + * @author Romain Cambier + */ +public abstract class RawMessage implements DataMessage { + + public abstract String asString(); + + public int asInt() { + return Integer.parseInt(asString()); + } + + public double asDouble() { + return Double.parseDouble(asString()); + } + + public boolean asBoolean() { + return Boolean.parseBoolean(asString()); + } + + public T as(Class _class) throws IOException { + if (_class == null) { + throw new NullPointerException(); + } + if (_class.equals(Boolean.class)) { + return (T) (Boolean) asBoolean(); + } + if (_class.equals(Integer.class)) { + return (T) (Integer) asInt(); + } + if (_class.equals(Double.class)) { + return (T) (Double) asDouble(); + } + if (_class.equals(String.class)) { + return (T) asString(); + } + return AbstractClient.MAPPER.readValue(asString(), _class); + } + +} diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/UplinkMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/messages/UplinkMessage.java new file mode 100644 index 0000000..aba855e --- /dev/null +++ b/data/common/src/main/java/org/thethingsnetwork/data/messages/UplinkMessage.java @@ -0,0 +1,68 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.data.messages; + +import java.util.Base64; +import java.util.Collections; +import java.util.Map; +import org.thethingsnetwork.data.common.Metadata; + +/** + * This is a wrapper class for JSONObject to provide support for base64 encoded payload + * + * @author Romain Cambier + */ +public class UplinkMessage implements DataMessage { + + private int port; + private int counter; + private String payloadRaw; + private Map payloadFields; + private Metadata metadata; + + private UplinkMessage() { + + } + + public int getPort() { + return port; + } + + public int getCounter() { + return counter; + } + + public byte[] getPayloadRaw() { + return Base64.getDecoder().decode(payloadRaw); + } + + public Map getPayloadFields() { + return Collections.unmodifiableMap(payloadFields); + } + + public Metadata getMetadata() { + return metadata; + } + +} From 8d50b9b9c65957a55c36d1d1d22ff25b9d868256 Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 19 Dec 2016 21:30:57 +0100 Subject: [PATCH 02/24] changed version to 2.1.0 updated data-mqtt for #37 --- data/common/pom.xml | 2 +- .../data/common/AbstractClient.java | 13 +- .../common/events/AbstractEventHandler.java | 2 +- .../data/common/events/ActivationHandler.java | 2 +- .../data/common/events/UplinkHandler.java | 2 +- .../messages/ActivationMessage.java | 2 +- .../{ => common}/messages/DataMessage.java | 2 +- .../messages/DownlinkMessage.java | 2 +- .../{ => common}/messages/RawMessage.java | 2 +- .../{ => common}/messages/UplinkMessage.java | 2 +- data/mqtt/pom.xml | 2 +- .../thethingsnetwork/data/mqtt/Client.java | 120 ++++++++------- data/pom.xml | 2 +- management/src/main/java/Test.java | 145 ++++++++++++++++++ pom.xml | 2 +- 15 files changed, 228 insertions(+), 74 deletions(-) rename data/common/src/main/java/org/thethingsnetwork/data/{ => common}/messages/ActivationMessage.java (97%) rename data/common/src/main/java/org/thethingsnetwork/data/{ => common}/messages/DataMessage.java (95%) rename data/common/src/main/java/org/thethingsnetwork/data/{ => common}/messages/DownlinkMessage.java (97%) rename data/common/src/main/java/org/thethingsnetwork/data/{ => common}/messages/RawMessage.java (97%) rename data/common/src/main/java/org/thethingsnetwork/data/{ => common}/messages/UplinkMessage.java (97%) create mode 100644 management/src/main/java/Test.java diff --git a/data/common/pom.xml b/data/common/pom.xml index 86ee4b8..6103922 100644 --- a/data/common/pom.xml +++ b/data/common/pom.xml @@ -4,7 +4,7 @@ org.thethingsnetwork data - 2.0.0 + 2.1.0 data-common jar diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java b/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java index d6b0327..e437a35 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java @@ -29,9 +29,10 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategy; import java.util.function.BiConsumer; import java.util.function.Consumer; -import org.thethingsnetwork.data.messages.ActivationMessage; -import org.thethingsnetwork.data.messages.DownlinkMessage; -import org.thethingsnetwork.data.messages.RawMessage; +import org.thethingsnetwork.data.common.messages.ActivationMessage; +import org.thethingsnetwork.data.common.messages.DataMessage; +import org.thethingsnetwork.data.common.messages.DownlinkMessage; +import org.thethingsnetwork.data.common.messages.RawMessage; /** * This is an abstract representation of the methods any real-time TTN client should provide @@ -119,7 +120,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onMessage(final String _devId, final String _field, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(final String _devId, final String _field, final BiConsumer _handler) throws Exception; /** * Register an uplink event handler using device filter @@ -129,7 +130,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onMessage(final String _devId, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(final String _devId, final BiConsumer _handler) throws Exception; /** * Register an uplink event handler @@ -138,7 +139,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onMessage(final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(final BiConsumer _handler) throws Exception; /** * Register an activation event handler using device filter diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java b/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java index cdf9495..5bb3337 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java @@ -24,7 +24,7 @@ package org.thethingsnetwork.data.common.events; import org.thethingsnetwork.data.common.Subscribable; -import org.thethingsnetwork.data.messages.RawMessage; +import org.thethingsnetwork.data.common.messages.RawMessage; /** * diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java b/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java index 00a8488..45ce1f0 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java @@ -23,7 +23,7 @@ */ package org.thethingsnetwork.data.common.events; -import org.thethingsnetwork.data.messages.ActivationMessage; +import org.thethingsnetwork.data.common.messages.ActivationMessage; import org.thethingsnetwork.data.common.Subscribable; /** diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java b/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java index b67475b..eadf45e 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java @@ -24,7 +24,7 @@ package org.thethingsnetwork.data.common.events; import org.thethingsnetwork.data.common.Subscribable; -import org.thethingsnetwork.data.messages.DataMessage; +import org.thethingsnetwork.data.common.messages.DataMessage; /** * diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/ActivationMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java similarity index 97% rename from data/common/src/main/java/org/thethingsnetwork/data/messages/ActivationMessage.java rename to data/common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java index 7845a79..737374d 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/messages/ActivationMessage.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.data.messages; +package org.thethingsnetwork.data.common.messages; import org.thethingsnetwork.data.common.Metadata; diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/DataMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java similarity index 95% rename from data/common/src/main/java/org/thethingsnetwork/data/messages/DataMessage.java rename to data/common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java index 4745ef7..935fc36 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/messages/DataMessage.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.data.messages; +package org.thethingsnetwork.data.common.messages; /** * diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/DownlinkMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java similarity index 97% rename from data/common/src/main/java/org/thethingsnetwork/data/messages/DownlinkMessage.java rename to data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java index 0c9ac8a..9f0fd5e 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/messages/DownlinkMessage.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java @@ -15,7 +15,7 @@ * is strictly forbidden unless prior written permission is obtained * from Shareif.com SPRL. */ -package org.thethingsnetwork.data.messages; +package org.thethingsnetwork.data.common.messages; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/RawMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java similarity index 97% rename from data/common/src/main/java/org/thethingsnetwork/data/messages/RawMessage.java rename to data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java index 9420d4f..0df08e6 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/messages/RawMessage.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java @@ -15,7 +15,7 @@ * is strictly forbidden unless prior written permission is obtained * from Shareif.com SPRL. */ -package org.thethingsnetwork.data.messages; +package org.thethingsnetwork.data.common.messages; import java.io.IOException; import org.thethingsnetwork.data.common.AbstractClient; diff --git a/data/common/src/main/java/org/thethingsnetwork/data/messages/UplinkMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java similarity index 97% rename from data/common/src/main/java/org/thethingsnetwork/data/messages/UplinkMessage.java rename to data/common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java index aba855e..bf22ebe 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/messages/UplinkMessage.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.data.messages; +package org.thethingsnetwork.data.common.messages; import java.util.Base64; import java.util.Collections; diff --git a/data/mqtt/pom.xml b/data/mqtt/pom.xml index 7e4a128..4379cdd 100644 --- a/data/mqtt/pom.xml +++ b/data/mqtt/pom.xml @@ -4,7 +4,7 @@ org.thethingsnetwork data - 2.0.0 + 2.1.0 data-mqtt jar diff --git a/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java b/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java index 48340bf..4183301 100644 --- a/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java +++ b/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java @@ -25,8 +25,6 @@ import java.net.URI; import java.net.URISyntaxException; -import java.nio.ByteBuffer; -import java.util.Base64; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -45,7 +43,6 @@ import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; -import org.json.JSONObject; import org.thethingsnetwork.data.common.AbstractClient; import org.thethingsnetwork.data.common.Connection; import org.thethingsnetwork.data.common.Subscribable; @@ -56,13 +53,18 @@ import org.thethingsnetwork.data.common.events.ErrorHandler; import org.thethingsnetwork.data.common.events.EventHandler; import org.thethingsnetwork.data.common.events.UplinkHandler; +import org.thethingsnetwork.data.common.messages.ActivationMessage; +import org.thethingsnetwork.data.common.messages.DataMessage; +import org.thethingsnetwork.data.common.messages.DownlinkMessage; +import org.thethingsnetwork.data.common.messages.RawMessage; +import org.thethingsnetwork.data.common.messages.UplinkMessage; /** * This is the base class to be used to interact with The Things Network Handler * * @author Romain Cambier */ -public class Client implements AbstractClient { +public class Client extends AbstractClient { /** * Connection settings @@ -182,24 +184,42 @@ public void messageArrived(String topic, final MqttMessage message) throws Excep switch (tokens[3]) { case "up": if (handlers.containsKey(UplinkHandler.class)) { - handlers.get(UplinkHandler.class).stream().forEach((handler) -> { - executor.submit(() -> { - try { - UplinkHandler uh = (UplinkHandler) handler; - if (uh.matches(tokens[2])) { - uh.handle(tokens[2], uh.transform(new String(message.getPayload()))); - } - } catch (final Exception ex) { - if (handlers.containsKey(ErrorHandler.class)) { - handlers.get(ErrorHandler.class).stream().forEach((handler1) -> { - executor.submit(() -> { - ((ErrorHandler) handler1).safelyHandle(ex); - }); - }); - } - } - }); - }); + String field; + if (tokens.length > 4) { + field = concat(4, tokens); + } else { + field = null; + } + handlers.get(UplinkHandler.class).stream() + .forEach((handler) -> { + executor.submit(() -> { + try { + UplinkHandler uh = (UplinkHandler) handler; + if (uh.matches(tokens[2], field)) { + if (uh.isField()) { + uh.handle(tokens[2], new RawMessage() { + String str = new String(message.getPayload()); + + @Override + public String asString() { + return str; + } + }); + } else { + uh.handle(tokens[2], MAPPER.readValue(message.getPayload(), UplinkMessage.class)); + } + } + } catch (final Exception ex) { + if (handlers.containsKey(ErrorHandler.class)) { + handlers.get(ErrorHandler.class).stream().forEach((handler1) -> { + executor.submit(() -> { + ((ErrorHandler) handler1).safelyHandle(ex); + }); + }); + } + } + }); + }); } break; case "events": @@ -212,7 +232,7 @@ public void messageArrived(String topic, final MqttMessage message) throws Excep try { ActivationHandler ah = (ActivationHandler) handler; if (ah.matches(tokens[2])) { - ah.handle(tokens[2], new JSONObject(new String(message.getPayload()))); + ah.handle(tokens[2], MAPPER.readValue(message.getPayload(), ActivationMessage.class)); } } catch (final Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { @@ -235,7 +255,14 @@ public void messageArrived(String topic, final MqttMessage message) throws Excep AbstractEventHandler aeh = (AbstractEventHandler) handler; String event = concat(4, tokens); if (aeh.matches(tokens[2], event)) { - aeh.handle(tokens[2], event, new JSONObject(new String(message.getPayload()))); + aeh.handle(tokens[2], event, new RawMessage() { + String str = new String(message.getPayload()); + + @Override + public String asString() { + return str; + } + }); } } catch (final Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { @@ -352,27 +379,8 @@ public Client endNow() throws MqttException { } @Override - public void send(String _devId, byte[] _payload, int _port) throws MqttException { - JSONObject data = new JSONObject(); - data.put("payload_raw", Base64.getEncoder().encodeToString(_payload)); - data.put("port", _port != 0 ? _port : 1); - mqttClient.publish(appId + "/devices/" + _devId + "/down", data.toString().getBytes(), 0, false); - } - - @Override - public void send(String _devId, JSONObject _payload, int _port) throws MqttException { - JSONObject data = new JSONObject(); - data.put("payload_fields", _payload); - data.put("port", _port != 0 ? _port : 1); - mqttClient.publish(appId + "/devices/" + _devId + "/down", data.toString().getBytes(), 0, false); - } - - @Override - public void send(String _devId, ByteBuffer _payload, int _port) throws MqttException { - _payload.rewind(); - byte[] payload = new byte[_payload.capacity() - _payload.remaining()]; - _payload.get(payload); - send(_devId, payload, _port); + public void send(String _devId, DownlinkMessage _payload, int _port) throws Exception { + mqttClient.publish(appId + "/devices/" + _devId + "/down", MAPPER.writeValueAsBytes(_payload), 0, false); } @Override @@ -410,7 +418,7 @@ public void handle(Throwable _error) { } @Override - public Client onMessage(final String _devId, final String _field, final BiConsumer _handler) { + public Client onMessage(final String _devId, final String _field, final BiConsumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -419,7 +427,7 @@ public Client onMessage(final String _devId, final String _field, final BiConsum } handlers.get(UplinkHandler.class).add(new UplinkHandler() { @Override - public void handle(String _devId, Object _data) { + public void handle(String _devId, DataMessage _data) { _handler.accept(_devId, _data); } @@ -437,17 +445,17 @@ public String getField() { } @Override - public Client onMessage(final String _devId, final BiConsumer _handler) { + public Client onMessage(final String _devId, final BiConsumer _handler) { return onMessage(_devId, null, _handler); } @Override - public Client onMessage(final BiConsumer _handler) { + public Client onMessage(final BiConsumer _handler) { return onMessage(null, null, _handler); } @Override - public Client onActivation(final String _devId, final BiConsumer _handler) { + public Client onActivation(final String _devId, final BiConsumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -456,7 +464,7 @@ public Client onActivation(final String _devId, final BiConsumer _handler) { + public Client onActivation(final BiConsumer _handler) { return onActivation(null, _handler); } @Override - public Client onDevice(final String _devId, final String _event, final TriConsumer _handler) { + public Client onDevice(final String _devId, final String _event, final TriConsumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -483,7 +491,7 @@ public Client onDevice(final String _devId, final String _event, final TriConsum } handlers.get(AbstractEventHandler.class).add(new AbstractEventHandler() { @Override - public void handle(String _devId, String _event, JSONObject _data) { + public void handle(String _devId, String _event, RawMessage _data) { _handler.accept(_devId, _event, _data); } @@ -501,12 +509,12 @@ public String getEvent() { } @Override - public Client onDevice(final String _devId, final TriConsumer _handler) { + public Client onDevice(final String _devId, final TriConsumer _handler) { return onDevice(_devId, null, _handler); } @Override - public Client onDevice(final TriConsumer _handler) { + public Client onDevice(final TriConsumer _handler) { return onDevice(null, null, _handler); } diff --git a/data/pom.xml b/data/pom.xml index de93d11..f226ed0 100644 --- a/data/pom.xml +++ b/data/pom.xml @@ -4,7 +4,7 @@ org.thethingsnetwork app-sdk - 2.0.0 + 2.1.0 data pom diff --git a/management/src/main/java/Test.java b/management/src/main/java/Test.java new file mode 100644 index 0000000..a8e0821 --- /dev/null +++ b/management/src/main/java/Test.java @@ -0,0 +1,145 @@ + +import java.util.concurrent.TimeUnit; +import rx.Observable; +import rx.Producer; +import rx.Subscriber; +import rx.schedulers.Schedulers; + +/* + * Shareif.com CONFIDENTIAL + * ________________________ + * + * Copyright 2016 Shareif.com SPRL + * All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of Shareif.com SPRL and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to Shareif.com SPRL + * and its suppliers and may be covered by Belgian and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * Dissemination of this information or reproduction of this material + * is strictly forbidden unless prior written permission is obtained + * from Shareif.com SPRL. + */ +/** + * + * @author Romain Cambier + */ +public class Test { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) throws InterruptedException { + + Observable s1 = serie(0, 10); + Observable s2 = serie(1, 10); + + Observable[] s = new Observable[]{s1, s2}; + + Observable + .create(new Observable.OnSubscribe() { + int i = 0; + + @Override + public void call(Subscriber t) { + + t.setProducer(new Producer() { + @Override + public void request(long n) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + }); + + for (Observable obs : s) { + obs.subscribe(new Subscriber() { + @Override + public void onCompleted() { + if (t.isUnsubscribed()) { + unsubscribe(); + return; + } + i++; + if (i == s.length) { + t.onCompleted(); + } + } + + @Override + public void onError(Throwable e) { + t.onError(e); + } + + @Override + public void onNext(Integer tt) { + if (t.isUnsubscribed()) { + unsubscribe(); + return; + } + t.onNext(tt); + } + + @Override + public void onStart() { + + } + }); + } + + } + }).subscribe(new Subscriber() { + @Override + public void onCompleted() { + System.out.println("got complete"); + } + + @Override + public void onError(Throwable e) { + e.printStackTrace(); + } + + @Override + public void onNext(Integer t) { + System.out.println("got " + t); + } + }); + + TimeUnit.SECONDS.sleep(5); + + } + + public static Observable serie(int _offset, int _max) { + return Observable + .create(new Observable.OnSubscribe() { + @Override + public void call(Subscriber t) { + t.setProducer(new Producer() { + int i = 0; + + @Override + public void request(long n) { + for (int j = 0; j < n; j++) { + if (t.isUnsubscribed()) { + System.out.println("broken"); + break; + } + try { + TimeUnit.MILLISECONDS.sleep(10); + } catch (Exception ex) { + + } + t.onNext(100 - (_offset + 5 * i++)); + if (i > _max) { + t.onCompleted(); + break; + } + } + } + }); + } + }) + .subscribeOn(Schedulers.io()); + } + +} diff --git a/pom.xml b/pom.xml index c9890f1..623378b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.thethingsnetwork app-sdk - 2.0.0 + 2.1.0 pom From f36327a0666633443ed2f8a51d56eb056e2b06ef Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 19 Dec 2016 21:39:02 +0100 Subject: [PATCH 03/24] updated data-amqp and implemented #37 --- account/pom.xml | 2 +- data/amqp/pom.xml | 2 +- .../thethingsnetwork/data/amqp/Client.java | 125 +++++++++--------- management/pom.xml | 2 +- 4 files changed, 69 insertions(+), 62 deletions(-) diff --git a/account/pom.xml b/account/pom.xml index 98c9ee9..da2746e 100644 --- a/account/pom.xml +++ b/account/pom.xml @@ -4,7 +4,7 @@ org.thethingsnetwork app-sdk - 2.0.0 + 2.1.0 account jar diff --git a/data/amqp/pom.xml b/data/amqp/pom.xml index 1bf65cf..39f0a3b 100644 --- a/data/amqp/pom.xml +++ b/data/amqp/pom.xml @@ -4,7 +4,7 @@ org.thethingsnetwork data - 2.0.0 + 2.1.0 data-amqp jar diff --git a/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java b/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java index 1be9c58..08554ab 100644 --- a/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java +++ b/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java @@ -31,8 +31,6 @@ import com.rabbitmq.client.Envelope; import java.io.IOException; import java.net.URISyntaxException; -import java.nio.ByteBuffer; -import java.util.Base64; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -43,8 +41,8 @@ import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; -import org.json.JSONObject; import org.thethingsnetwork.data.common.AbstractClient; +import static org.thethingsnetwork.data.common.AbstractClient.MAPPER; import org.thethingsnetwork.data.common.Subscribable; import org.thethingsnetwork.data.common.TriConsumer; import org.thethingsnetwork.data.common.events.AbstractEventHandler; @@ -53,12 +51,17 @@ import org.thethingsnetwork.data.common.events.ErrorHandler; import org.thethingsnetwork.data.common.events.EventHandler; import org.thethingsnetwork.data.common.events.UplinkHandler; +import org.thethingsnetwork.data.common.messages.ActivationMessage; +import org.thethingsnetwork.data.common.messages.DataMessage; +import org.thethingsnetwork.data.common.messages.DownlinkMessage; +import org.thethingsnetwork.data.common.messages.RawMessage; +import org.thethingsnetwork.data.common.messages.UplinkMessage; /** * * @author Romain Cambier */ -public class Client implements AbstractClient { +public class Client extends AbstractClient { /** * Connection settings @@ -141,24 +144,43 @@ public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProp switch (tokens[3]) { case "up": if (handlers.containsKey(UplinkHandler.class)) { - handlers.get(UplinkHandler.class).stream().forEach((handler) -> { - executor.submit(() -> { - try { - UplinkHandler uh = (UplinkHandler) handler; - if (uh.matches(tokens[2])) { - uh.handle(tokens[2], uh.transform(new String(body))); - } - } catch (final Exception ex) { - if (handlers.containsKey(ErrorHandler.class)) { - handlers.get(ErrorHandler.class).stream().forEach((org.thethingsnetwork.data.common.events.EventHandler handler1) -> { - executor.submit(() -> { - ((ErrorHandler) handler1).safelyHandle(ex); - }); - }); - } - } - }); - }); + String field; + if (tokens.length > 4) { + field = concat(4, tokens); + } else { + field = null; + } + handlers.get(UplinkHandler.class).stream() + .forEach((handler) -> { + executor.submit(() -> { + try { + UplinkHandler uh = (UplinkHandler) handler; + + if (uh.matches(tokens[2], field)) { + if (uh.isField()) { + uh.handle(tokens[2], new RawMessage() { + String str = new String(body); + + @Override + public String asString() { + return str; + } + }); + } else { + uh.handle(tokens[2], MAPPER.readValue(body, UplinkMessage.class)); + } + } + } catch (final Exception ex) { + if (handlers.containsKey(ErrorHandler.class)) { + handlers.get(ErrorHandler.class).stream().forEach((org.thethingsnetwork.data.common.events.EventHandler handler1) -> { + executor.submit(() -> { + ((ErrorHandler) handler1).safelyHandle(ex); + }); + }); + } + } + }); + }); } break; case "events": @@ -171,7 +193,7 @@ public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProp try { ActivationHandler ah = (ActivationHandler) handler; if (ah.matches(tokens[2])) { - ah.handle(tokens[2], new JSONObject(new String(body))); + ah.handle(tokens[2], MAPPER.readValue(body, ActivationMessage.class)); } } catch (final Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { @@ -194,7 +216,14 @@ public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProp AbstractEventHandler aeh = (AbstractEventHandler) handler; String event = concat(4, tokens); if (aeh.matches(tokens[2], event)) { - aeh.handle(tokens[2], event, new JSONObject(new String(body))); + aeh.handle(tokens[2], event, new RawMessage() { + String str = new String(body); + + @Override + public String asString() { + return str; + } + }); } } catch (final Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { @@ -304,30 +333,8 @@ public Client endNow() throws IOException { } @Override - public void send(String _devId, byte[] _payload, int _port) throws IOException { - JSONObject data = new JSONObject(); - data.put("payload_raw", Base64.getEncoder().encodeToString(_payload)); - data.put("port", _port != 0 ? _port : 1); - channel.basicPublish(exchange, appId + "/devices/" + _devId + "/down", null, data.toString().getBytes()); - } - - @Override - public void send(String _devId, JSONObject _payload, int _port) throws IOException { - JSONObject data = new JSONObject(); - data.put("payload_fields", _payload); - data.put("port", _port != 0 ? _port : 1); - channel.basicPublish(exchange, appId + "/devices/" + _devId + "/down", null, data.toString().getBytes()); - } - - @Override - public void send(String _devId, ByteBuffer _payload, int _port) throws IOException { - JSONObject data = new JSONObject(); - _payload.rewind(); - byte[] payload = new byte[_payload.capacity() - _payload.remaining()]; - _payload.get(payload); - data.put("payload_fields", Base64.getEncoder().encodeToString(payload)); - data.put("port", _port != 0 ? _port : 1); - channel.basicPublish(exchange, appId + "/devices/" + _devId + "/down", null, data.toString().getBytes()); + public void send(String _devId, DownlinkMessage _payload, int _port) throws IOException { + channel.basicPublish(exchange, appId + "/devices/" + _devId + "/down", null, MAPPER.writeValueAsBytes(_payload)); } @Override @@ -366,7 +373,7 @@ public void handle(Throwable _error) { } @Override - public Client onMessage(final String _devId, final String _field, final BiConsumer _handler) { + public Client onMessage(final String _devId, final String _field, final BiConsumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -375,7 +382,7 @@ public Client onMessage(final String _devId, final String _field, final BiConsum } handlers.get(UplinkHandler.class).add(new UplinkHandler() { @Override - public void handle(String _devId, Object _data) { + public void handle(String _devId, DataMessage _data) { _handler.accept(_devId, _data); } @@ -393,17 +400,17 @@ public String getField() { } @Override - public Client onMessage(final String _devId, final BiConsumer _handler) { + public Client onMessage(final String _devId, final BiConsumer _handler) { return onMessage(_devId, null, _handler); } @Override - public Client onMessage(final BiConsumer _handler) { + public Client onMessage(final BiConsumer _handler) { return onMessage(null, null, _handler); } @Override - public Client onActivation(final String _devId, final BiConsumer _handler) { + public Client onActivation(final String _devId, final BiConsumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -412,7 +419,7 @@ public Client onActivation(final String _devId, final BiConsumer _handler) { + public Client onActivation(final BiConsumer _handler) { return onActivation(null, _handler); } @Override - public Client onDevice(final String _devId, final String _event, final TriConsumer _handler) { + public Client onDevice(final String _devId, final String _event, final TriConsumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -439,7 +446,7 @@ public Client onDevice(final String _devId, final String _event, final TriConsum } handlers.get(AbstractEventHandler.class).add(new AbstractEventHandler() { @Override - public void handle(String _devId, String _event, JSONObject _data) { + public void handle(String _devId, String _event, RawMessage _data) { _handler.accept(_devId, _event, _data); } @@ -457,12 +464,12 @@ public String getEvent() { } @Override - public Client onDevice(final String _devId, final TriConsumer _handler) { + public Client onDevice(final String _devId, final TriConsumer _handler) { return onDevice(_devId, null, _handler); } @Override - public Client onDevice(final TriConsumer _handler) { + public Client onDevice(final TriConsumer _handler) { return onDevice(null, null, _handler); } } diff --git a/management/pom.xml b/management/pom.xml index 38b228e..31b4baf 100644 --- a/management/pom.xml +++ b/management/pom.xml @@ -4,7 +4,7 @@ org.thethingsnetwork app-sdk - 2.0.0 + 2.1.0 management jar From 4cd59c70127822bac4cdc1d3fdd8d78dd3ec08dd Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 19 Dec 2016 21:55:44 +0100 Subject: [PATCH 04/24] updated sample to make it working again after #37 --- .../thethingsnetwork/data/amqp/Client.java | 36 +++++++++---------- .../data/common/AbstractClient.java | 23 ++++++------ .../thethingsnetwork/data/mqtt/Client.java | 36 +++++++++---------- samples/mqtt/pom.xml | 2 +- .../thethingsnetwork/samples/mqtt/App.java | 28 +++++++++++---- samples/pom.xml | 2 +- 6 files changed, 70 insertions(+), 57 deletions(-) diff --git a/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java b/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java index 08554ab..1e24d98 100644 --- a/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java +++ b/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java @@ -132,12 +132,12 @@ public Client start() throws Exception { connection = factory.newConnection(); channel = connection.createChannel(); - final String queue = channel.queueDeclare().getQueue(); + String queue = channel.queueDeclare().getQueue(); channel.basicConsume(queue, new DefaultConsumer(channel) { @Override - public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, final byte[] body) throws IOException { - final String[] tokens = envelope.getRoutingKey().split("\\."); + public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { + String[] tokens = envelope.getRoutingKey().split("\\."); if (tokens.length < 4) { return; } @@ -170,7 +170,7 @@ public String asString() { uh.handle(tokens[2], MAPPER.readValue(body, UplinkMessage.class)); } } - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((org.thethingsnetwork.data.common.events.EventHandler handler1) -> { executor.submit(() -> { @@ -195,7 +195,7 @@ public String asString() { if (ah.matches(tokens[2])) { ah.handle(tokens[2], MAPPER.readValue(body, ActivationMessage.class)); } - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((org.thethingsnetwork.data.common.events.EventHandler handler1) -> { executor.submit(() -> { @@ -225,7 +225,7 @@ public String asString() { } }); } - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((org.thethingsnetwork.data.common.events.EventHandler handler1) -> { executor.submit(() -> { @@ -278,7 +278,7 @@ public String getPathWildcard() { executor.submit(() -> { try { ((ConnectHandler) handler).handle(() -> channel); - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((org.thethingsnetwork.data.common.events.EventHandler handler1) -> { executor.submit(() -> { @@ -333,12 +333,12 @@ public Client endNow() throws IOException { } @Override - public void send(String _devId, DownlinkMessage _payload, int _port) throws IOException { + public void send(String _devId, DownlinkMessage _payload) throws IOException { channel.basicPublish(exchange, appId + "/devices/" + _devId + "/down", null, MAPPER.writeValueAsBytes(_payload)); } @Override - public Client onConnected(final Consumer _handler) { + public Client onConnected(Consumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -356,7 +356,7 @@ public void handle(org.thethingsnetwork.data.common.Connection _client) { } @Override - public Client onError(final Consumer _handler) { + public Client onError(Consumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -373,7 +373,7 @@ public void handle(Throwable _error) { } @Override - public Client onMessage(final String _devId, final String _field, final BiConsumer _handler) { + public Client onMessage(String _devId, String _field, BiConsumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -400,17 +400,17 @@ public String getField() { } @Override - public Client onMessage(final String _devId, final BiConsumer _handler) { + public Client onMessage(String _devId, BiConsumer _handler) { return onMessage(_devId, null, _handler); } @Override - public Client onMessage(final BiConsumer _handler) { + public Client onMessage(BiConsumer _handler) { return onMessage(null, null, _handler); } @Override - public Client onActivation(final String _devId, final BiConsumer _handler) { + public Client onActivation(String _devId, BiConsumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -432,12 +432,12 @@ public String getDevId() { } @Override - public Client onActivation(final BiConsumer _handler) { + public Client onActivation(BiConsumer _handler) { return onActivation(null, _handler); } @Override - public Client onDevice(final String _devId, final String _event, final TriConsumer _handler) { + public Client onDevice(String _devId, String _event, TriConsumer _handler) { if (connection != null) { throw new RuntimeException("Already connected"); } @@ -464,12 +464,12 @@ public String getEvent() { } @Override - public Client onDevice(final String _devId, final TriConsumer _handler) { + public Client onDevice(String _devId, TriConsumer _handler) { return onDevice(_devId, null, _handler); } @Override - public Client onDevice(final TriConsumer _handler) { + public Client onDevice(TriConsumer _handler) { return onDevice(null, null, _handler); } } diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java b/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java index e437a35..8072201 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java @@ -88,10 +88,9 @@ public abstract class AbstractClient { * * @param _devId The devId to send the message to * @param _payload The payload to be sent - * @param _port The port to use for the message * @throws Exception in case something goes wrong */ - public abstract void send(String _devId, DownlinkMessage _payload, int _port) throws Exception; + public abstract void send(String _devId, DownlinkMessage _payload) throws Exception; /** * Register a connection event handler @@ -100,7 +99,7 @@ public abstract class AbstractClient { * @return the Connection instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onConnected(final Consumer _handler) throws Exception; + public abstract AbstractClient onConnected(Consumer _handler) throws Exception; /** * Register an error event handler @@ -109,7 +108,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onError(final Consumer _handler) throws Exception; + public abstract AbstractClient onError(Consumer _handler) throws Exception; /** * Register an uplink event handler using device and field filters @@ -120,7 +119,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onMessage(final String _devId, final String _field, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(String _devId, String _field, BiConsumer _handler) throws Exception; /** * Register an uplink event handler using device filter @@ -130,7 +129,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onMessage(final String _devId, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(String _devId, BiConsumer _handler) throws Exception; /** * Register an uplink event handler @@ -139,7 +138,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onMessage(final BiConsumer _handler) throws Exception; + public abstract AbstractClient onMessage(BiConsumer _handler) throws Exception; /** * Register an activation event handler using device filter @@ -149,7 +148,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onActivation(final String _devId, final BiConsumer _handler) throws Exception; + public abstract AbstractClient onActivation(String _devId, BiConsumer _handler) throws Exception; /** * Register an activation event handler @@ -158,7 +157,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onActivation(final BiConsumer _handler) throws Exception; + public abstract AbstractClient onActivation(BiConsumer _handler) throws Exception; /** * Register a default event handler using device and event filters @@ -169,7 +168,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onDevice(final String _devId, final String _event, final TriConsumer _handler) throws Exception; + public abstract AbstractClient onDevice(String _devId, String _event, TriConsumer _handler) throws Exception; /** * Register a default event handler using device filter @@ -179,7 +178,7 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onDevice(final String _devId, final TriConsumer _handler) throws Exception; + public abstract AbstractClient onDevice(String _devId, TriConsumer _handler) throws Exception; /** * Register a default event handler @@ -188,6 +187,6 @@ public abstract class AbstractClient { * @return the Client instance * @throws Exception in case something goes wrong */ - public abstract AbstractClient onDevice(final TriConsumer _handler) throws Exception; + public abstract AbstractClient onDevice(TriConsumer _handler) throws Exception; } diff --git a/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java b/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java index 4183301..d256d09 100644 --- a/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java +++ b/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java @@ -164,7 +164,7 @@ public Client start() throws MqttException, Exception { mqttClient.connect(connOpts); mqttClient.setCallback(new MqttCallback() { @Override - public void connectionLost(final Throwable cause) { + public void connectionLost(Throwable cause) { mqttClient = null; if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((handler) -> { @@ -176,8 +176,8 @@ public void connectionLost(final Throwable cause) { } @Override - public void messageArrived(String topic, final MqttMessage message) throws Exception { - final String[] tokens = topic.split("\\/"); + public void messageArrived(String topic, MqttMessage message) throws Exception { + String[] tokens = topic.split("\\/"); if (tokens.length < 4) { return; } @@ -209,7 +209,7 @@ public String asString() { uh.handle(tokens[2], MAPPER.readValue(message.getPayload(), UplinkMessage.class)); } } - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((handler1) -> { executor.submit(() -> { @@ -234,7 +234,7 @@ public String asString() { if (ah.matches(tokens[2])) { ah.handle(tokens[2], MAPPER.readValue(message.getPayload(), ActivationMessage.class)); } - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((handler1) -> { executor.submit(() -> { @@ -264,7 +264,7 @@ public String asString() { } }); } - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((handler1) -> { executor.submit(() -> { @@ -324,7 +324,7 @@ public String getPathWildcard() { executor.submit(() -> { try { ((ConnectHandler) handler).handle(() -> mqttClient); - } catch (final Exception ex) { + } catch (Exception ex) { if (handlers.containsKey(ErrorHandler.class)) { handlers.get(ErrorHandler.class).stream().forEach((handler1) -> { executor.submit(() -> { @@ -379,12 +379,12 @@ public Client endNow() throws MqttException { } @Override - public void send(String _devId, DownlinkMessage _payload, int _port) throws Exception { + public void send(String _devId, DownlinkMessage _payload) throws Exception { mqttClient.publish(appId + "/devices/" + _devId + "/down", MAPPER.writeValueAsBytes(_payload), 0, false); } @Override - public Client onConnected(final Consumer _handler) { + public Client onConnected(Consumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -401,7 +401,7 @@ public void handle(Connection _client) { } @Override - public Client onError(final Consumer _handler) { + public Client onError(Consumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -418,7 +418,7 @@ public void handle(Throwable _error) { } @Override - public Client onMessage(final String _devId, final String _field, final BiConsumer _handler) { + public Client onMessage(String _devId, String _field, BiConsumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -445,17 +445,17 @@ public String getField() { } @Override - public Client onMessage(final String _devId, final BiConsumer _handler) { + public Client onMessage(String _devId, BiConsumer _handler) { return onMessage(_devId, null, _handler); } @Override - public Client onMessage(final BiConsumer _handler) { + public Client onMessage(BiConsumer _handler) { return onMessage(null, null, _handler); } @Override - public Client onActivation(final String _devId, final BiConsumer _handler) { + public Client onActivation(String _devId, BiConsumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -477,12 +477,12 @@ public String getDevId() { } @Override - public Client onActivation(final BiConsumer _handler) { + public Client onActivation(BiConsumer _handler) { return onActivation(null, _handler); } @Override - public Client onDevice(final String _devId, final String _event, final TriConsumer _handler) { + public Client onDevice(String _devId, String _event, TriConsumer _handler) { if (mqttClient != null) { throw new RuntimeException("Already connected"); } @@ -509,12 +509,12 @@ public String getEvent() { } @Override - public Client onDevice(final String _devId, final TriConsumer _handler) { + public Client onDevice(String _devId, TriConsumer _handler) { return onDevice(_devId, null, _handler); } @Override - public Client onDevice(final TriConsumer _handler) { + public Client onDevice(TriConsumer _handler) { return onDevice(null, null, _handler); } diff --git a/samples/mqtt/pom.xml b/samples/mqtt/pom.xml index 10ddc8b..23cb761 100644 --- a/samples/mqtt/pom.xml +++ b/samples/mqtt/pom.xml @@ -4,7 +4,7 @@ org.thethingsnetwork samples - 2.0.0 + 2.1.0 samples-mqtt jar diff --git a/samples/mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java b/samples/mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java index 18b66b3..2929d6a 100644 --- a/samples/mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java +++ b/samples/mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java @@ -23,8 +23,12 @@ */ package org.thethingsnetwork.samples.mqtt; -import org.json.JSONObject; import org.thethingsnetwork.data.common.Connection; +import org.thethingsnetwork.data.common.messages.ActivationMessage; +import org.thethingsnetwork.data.common.messages.DataMessage; +import org.thethingsnetwork.data.common.messages.DownlinkMessage; +import org.thethingsnetwork.data.common.messages.RawMessage; +import org.thethingsnetwork.data.common.messages.UplinkMessage; import org.thethingsnetwork.data.mqtt.Client; /** @@ -40,25 +44,35 @@ public static void main(String[] args) throws Exception { Client client = new Client(region, appId, accessKey); - client.onMessage(null, "led", (String _devId, Object _data) -> { + class Response { + + private boolean led; + + public Response(boolean _led) { + led = _led; + } + } + + client.onMessage(null, "led", (String _devId, DataMessage _data) -> { try { + RawMessage message = (RawMessage) _data; // Toggle the LED - JSONObject response = new JSONObject().put("led", !_data.equals("true")); + DownlinkMessage response = new DownlinkMessage(0, new Response(!message.asBoolean())); /** * If you don't have an encoder payload function: - * client.send(_devId, _data.equals("true") ? new byte[]{0x00} : new byte[]{0x01}, 0); + * client.send(_devId, new Response(0, message.asBoolean() ? new byte[]{0x00} : new byte[]{0x01})); */ System.out.println("Sending: " + response); - client.send(_devId, response, 0); + client.send(_devId, response); } catch (Exception ex) { System.out.println("Response failed: " + ex.getMessage()); } }); - client.onMessage((String devId, Object data) -> System.out.println("Message: " + devId + " " + data)); + client.onMessage((String devId, DataMessage data) -> System.out.println("Message: " + devId + " " + ((UplinkMessage) data).getCounter())); - client.onActivation((String _devId, JSONObject _data) -> System.out.println("Activation: " + _devId + ", data: " + _data)); + client.onActivation((String _devId, ActivationMessage _data) -> System.out.println("Activation: " + _devId + ", data: " + _data.getDevAddr())); client.onError((Throwable _error) -> System.err.println("error: " + _error.getMessage())); diff --git a/samples/pom.xml b/samples/pom.xml index eff15a7..2b1c775 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.thethingsnetwork samples - 2.0.0 + 2.1.0 pom The Things Network SDK Samples From 0250d29b2da47628c56548eef5808b48b8db7b5f Mon Sep 17 00:00:00 2001 From: cambierr Date: Tue, 20 Dec 2016 10:06:08 +0100 Subject: [PATCH 05/24] implemented #28 --- .../account/async/AsyncApplication.java | 22 ++--- .../auth/grant/AsyncApplicationPassword.java} | 21 +++-- .../auth/grant/AsyncAuthorizationCode.java} | 23 ++--- .../auth/token/AsyncJsonWebToken.java} | 16 ++-- .../async/auth/token/AsyncOAuth2Token.java | 47 ++++++++++ .../token/AsyncRenewableJsonWebToken.java} | 30 +++--- .../{ => common}/AbstractApplication.java | 6 +- .../account/{ => common}/AccessKey.java | 2 +- .../account/{ => common}/Collaborator.java | 2 +- .../account/sync/Application.java | 20 ++-- .../sync/auth/grant/ApplicationPassword.java | 64 +++++++++++++ .../sync/auth/grant/AuthorizationCode.java | 65 +++++++++++++ .../account/sync/auth/token/JsonWebToken.java | 90 ++++++++++++++++++ .../{ => sync}/auth/token/OAuth2Token.java | 12 ++- .../auth/token/RenewableJsonWebToken.java | 94 +++++++++++++++++++ .../{common => util}/HttpException.java | 2 +- .../account/{common => util}/HttpRequest.java | 8 +- 17 files changed, 444 insertions(+), 80 deletions(-) rename account/src/main/java/org/thethingsnetwork/account/{auth/grant/ApplicationPassword.java => async/auth/grant/AsyncApplicationPassword.java} (82%) rename account/src/main/java/org/thethingsnetwork/account/{auth/grant/AuthorizationCode.java => async/auth/grant/AsyncAuthorizationCode.java} (86%) rename account/src/main/java/org/thethingsnetwork/account/{auth/token/JsonWebToken.java => async/auth/token/AsyncJsonWebToken.java} (87%) create mode 100644 account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java rename account/src/main/java/org/thethingsnetwork/account/{auth/token/RenewableJsonWebToken.java => async/auth/token/AsyncRenewableJsonWebToken.java} (68%) rename account/src/main/java/org/thethingsnetwork/account/{ => common}/AbstractApplication.java (89%) rename account/src/main/java/org/thethingsnetwork/account/{ => common}/AccessKey.java (97%) rename account/src/main/java/org/thethingsnetwork/account/{ => common}/Collaborator.java (97%) create mode 100644 account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java create mode 100644 account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java create mode 100644 account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java rename account/src/main/java/org/thethingsnetwork/account/{ => sync}/auth/token/OAuth2Token.java (85%) create mode 100644 account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java rename account/src/main/java/org/thethingsnetwork/account/{common => util}/HttpException.java (97%) rename account/src/main/java/org/thethingsnetwork/account/{common => util}/HttpRequest.java (96%) diff --git a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java index 2ac6a82..3526c17 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java @@ -26,12 +26,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import okhttp3.RequestBody; import okhttp3.Response; -import org.thethingsnetwork.account.AbstractApplication; -import org.thethingsnetwork.account.AccessKey; -import org.thethingsnetwork.account.Collaborator; -import org.thethingsnetwork.account.auth.token.OAuth2Token; -import org.thethingsnetwork.account.common.HttpRequest; +import org.thethingsnetwork.account.common.AbstractApplication; +import org.thethingsnetwork.account.common.AccessKey; +import org.thethingsnetwork.account.common.Collaborator; +import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; /** * @@ -43,7 +43,7 @@ public class AsyncApplication implements AbstractApplication { private String name; private String created; @JsonIgnore - protected OAuth2Token creds; + protected AsyncOAuth2Token creds; private AsyncApplication() { } @@ -74,7 +74,7 @@ public String getCreated() { } @Override - public void updateCredentials(OAuth2Token _creds) { + public void updateCredentials(AsyncOAuth2Token _creds) { creds = _creds; } @@ -85,7 +85,7 @@ private void refresh(AsyncApplication _other) { creds = _other.creds; } - public static Observable findAll(OAuth2Token _creds) { + public static Observable findAll(AsyncOAuth2Token _creds) { /** * GET /applications */ @@ -98,7 +98,7 @@ public static Observable findAll(OAuth2Token _creds) { .doOnNext((AsyncApplication app) -> app.updateCredentials(_creds)); } - public static Observable create(OAuth2Token _creds, AbstractApplication _app) { + public static Observable create(AsyncOAuth2Token _creds, AbstractApplication _app) { /** * POST /applications */ @@ -116,7 +116,7 @@ public static Observable create(OAuth2Token _creds, AbstractAp .doOnNext((AsyncApplication ap) -> ap.updateCredentials(_creds)); } - public static Observable findOne(OAuth2Token _creds, String _id) { + public static Observable findOne(AsyncOAuth2Token _creds, String _id) { /** * GET /applications/{app_id} */ @@ -314,7 +314,7 @@ public Observable getRights() { return getRights(creds); } - public Observable getRights(OAuth2Token _creds) { + public Observable getRights(AsyncOAuth2Token _creds) { /** * GET /applications/{app_id}/rights */ diff --git a/account/src/main/java/org/thethingsnetwork/account/auth/grant/ApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java similarity index 82% rename from account/src/main/java/org/thethingsnetwork/account/auth/grant/ApplicationPassword.java rename to account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java index d402f7a..98d6378 100644 --- a/account/src/main/java/org/thethingsnetwork/account/auth/grant/ApplicationPassword.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.auth.grant; +package org.thethingsnetwork.account.async.auth.grant; import java.net.URI; import java.util.Base64; import okhttp3.HttpUrl; import okhttp3.RequestBody; -import org.thethingsnetwork.account.auth.token.JsonWebToken; -import org.thethingsnetwork.account.common.HttpRequest; +import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; +import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; import rx.Subscriber; @@ -36,7 +37,7 @@ * * @author Romain Cambier */ -public class ApplicationPassword extends GrantType { +public class AsyncApplicationPassword extends GrantType { private final String clientId; private final String clientSecret; @@ -44,7 +45,7 @@ public class ApplicationPassword extends GrantType { private final String key; private final URI accountServer; - public ApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret, URI _accountServer) { + public AsyncApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret, URI _accountServer) { if (_key == null) { throw new IllegalArgumentException("key can not be null"); } @@ -67,7 +68,7 @@ public ApplicationPassword(String _appId, String _key, String _clientId, String clientSecret = _clientSecret; } - public ApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret) { + public AsyncApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret) { this(_appId, _key, _clientId, _clientSecret, GrantType.DEFAULT_ACCOUNT_SERVER); } @@ -80,7 +81,7 @@ private String getBasicAuthHeader() { return "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()); } - public Observable getToken() { + public Observable getToken() { return Observable .create((Subscriber t) -> { try { @@ -108,13 +109,13 @@ public Observable getToken() { t.getBuilder().header("Authorization", getBasicAuthHeader()); }) .flatMap((HttpRequest t) -> t.doExecuteForType(TokenResponse.class)) - .map((TokenResponse t) -> new JsonWebToken(t.accessToken, System.currentTimeMillis() + 1000 * t.expiresIn, accountServer)); + .map((TokenResponse t) -> new AsyncJsonWebToken(t.accessToken, System.currentTimeMillis() + 1000 * t.expiresIn, accountServer)); } private class TokenRequest { - private final String username = ApplicationPassword.this.appId; - private final String password = ApplicationPassword.this.key; + private final String username = AsyncApplicationPassword.this.appId; + private final String password = AsyncApplicationPassword.this.key; private final String grantType = "password"; } diff --git a/account/src/main/java/org/thethingsnetwork/account/auth/grant/AuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java similarity index 86% rename from account/src/main/java/org/thethingsnetwork/account/auth/grant/AuthorizationCode.java rename to account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java index 1e4fa0c..92704dc 100644 --- a/account/src/main/java/org/thethingsnetwork/account/auth/grant/AuthorizationCode.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.auth.grant; +package org.thethingsnetwork.account.async.auth.grant; import java.net.URI; import java.util.Base64; import okhttp3.HttpUrl; import okhttp3.RequestBody; -import org.thethingsnetwork.account.auth.token.RenewableJsonWebToken; -import org.thethingsnetwork.account.common.HttpRequest; +import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; +import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; import rx.Subscriber; @@ -36,13 +37,13 @@ * * @author Romain Cambier */ -public class AuthorizationCode extends GrantType { +public class AsyncAuthorizationCode extends GrantType { private final String clientId; private final String clientSecret; private final URI accountServer; - public AuthorizationCode(String _clientId, String _clientSecret, URI _accountServer) { + public AsyncAuthorizationCode(String _clientId, String _clientSecret, URI _accountServer) { if (_clientId == null) { throw new IllegalArgumentException("clientId can not be null"); } @@ -57,7 +58,7 @@ public AuthorizationCode(String _clientId, String _clientSecret, URI _accountSer accountServer = _accountServer; } - public AuthorizationCode(String _clientId, String _clientSecret) { + public AsyncAuthorizationCode(String _clientId, String _clientSecret) { this(_clientId, _clientSecret, GrantType.DEFAULT_ACCOUNT_SERVER); } @@ -82,7 +83,7 @@ public HttpUrl buildAuthorizationURL(URI _redirect) { .build(); } - public Observable getToken(String _authorizationCode) { + public Observable getToken(String _authorizationCode) { return Observable .create((Subscriber t) -> { try { @@ -110,10 +111,10 @@ public Observable getToken(String _authorizationCode) { t.getBuilder().header("Authorization", getBasicAuthHeader()); }) .flatMap((HttpRequest t) -> t.doExecuteForType(TokenResponse.class)) - .map((TokenResponse t) -> new RenewableJsonWebToken(t.accessToken, System.currentTimeMillis() + 1000 * t.expiresIn, t.refreshToken, this)); + .map((TokenResponse t) -> new AsyncRenewableJsonWebToken(t.accessToken, System.currentTimeMillis() + 1000 * t.expiresIn, t.refreshToken, this)); } - public Observable refreshToken(RenewableJsonWebToken _token) { + public Observable refreshToken(AsyncRenewableJsonWebToken _token) { return Observable .create((Subscriber t) -> { try { @@ -146,7 +147,7 @@ public Observable refreshToken(RenewableJsonWebToken _tok private class TokenRequest { - private String clientId = AuthorizationCode.this.clientId; + private String clientId = AsyncAuthorizationCode.this.clientId; private String grantType = "authorization_code"; private String code; @@ -166,7 +167,7 @@ private static class TokenResponse { private class RefreshRequest { - private String clientId = AuthorizationCode.this.clientId; + private String clientId = AsyncAuthorizationCode.this.clientId; private String grantType = "refresh_token"; private String refresh_token; diff --git a/account/src/main/java/org/thethingsnetwork/account/auth/token/JsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java similarity index 87% rename from account/src/main/java/org/thethingsnetwork/account/auth/token/JsonWebToken.java rename to account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java index c96637a..3d02205 100644 --- a/account/src/main/java/org/thethingsnetwork/account/auth/token/JsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java @@ -21,14 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.auth.token; +package org.thethingsnetwork.account.async.auth.token; import java.net.URI; import java.util.Arrays; import java.util.List; import okhttp3.HttpUrl; import okhttp3.RequestBody; -import org.thethingsnetwork.account.common.HttpRequest; +import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; import rx.Subscriber; @@ -36,13 +36,13 @@ * * @author Romain Cambier */ -public class JsonWebToken implements OAuth2Token { +public class AsyncJsonWebToken implements AsyncOAuth2Token { private String token; private long expiration; private final URI accountServer; - public JsonWebToken(String _token, long _expiration, URI _accountServer) { + public AsyncJsonWebToken(String _token, long _expiration, URI _accountServer) { if (_token == null) { throw new IllegalArgumentException("token can not be null"); } @@ -63,7 +63,7 @@ public boolean hasRefresh() { } @Override - public Observable refresh() { + public Observable refresh() { return Observable.error(new UnsupportedOperationException("Not supported.")); } @@ -94,7 +94,7 @@ public URI getAccountServer() { return accountServer; } - public Observable restrict(List _claims) { + public Observable restrict(List _claims) { return Observable .create((Subscriber t) -> { try { @@ -120,10 +120,10 @@ public Observable restrict(List _claims) { }) ) .flatMap((HttpRequest t) -> t.doExecuteForType(RestrictResponse.class)) - .map((RestrictResponse t) -> new JsonWebToken(t.accessToken, expiration, accountServer)); + .map((RestrictResponse t) -> new AsyncJsonWebToken(t.accessToken, expiration, accountServer)); } - public Observable restrict(String... _claims) { + public Observable restrict(String... _claims) { return restrict(Arrays.asList(_claims)); } diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java new file mode 100644 index 0000000..5fd1c89 --- /dev/null +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java @@ -0,0 +1,47 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.account.async.auth.token; + +import java.net.URI; +import rx.Observable; + +/** + * + * @author Romain Cambier + */ +public interface AsyncOAuth2Token { + + public boolean hasRefresh(); + + public Observable refresh(); + + public boolean isExpired(); + + public String getToken(); + + public String getRawToken(); + + public URI getAccountServer(); + +} diff --git a/account/src/main/java/org/thethingsnetwork/account/auth/token/RenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java similarity index 68% rename from account/src/main/java/org/thethingsnetwork/account/auth/token/RenewableJsonWebToken.java rename to account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java index c65a50f..33f68da 100644 --- a/account/src/main/java/org/thethingsnetwork/account/auth/token/RenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java @@ -21,23 +21,23 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.auth.token; +package org.thethingsnetwork.account.async.auth.token; import java.util.Arrays; import java.util.List; -import org.thethingsnetwork.account.auth.grant.AuthorizationCode; +import org.thethingsnetwork.account.async.auth.grant.AsyncAuthorizationCode; import rx.Observable; /** * * @author Romain Cambier */ -public class RenewableJsonWebToken extends JsonWebToken { +public class AsyncRenewableJsonWebToken extends AsyncJsonWebToken { private String refreshToken; - private final AuthorizationCode provider; + private final AsyncAuthorizationCode provider; - public RenewableJsonWebToken(String _token, long _expiration, String _refreshToken, AuthorizationCode _provider) { + public AsyncRenewableJsonWebToken(String _token, long _expiration, String _refreshToken, AsyncAuthorizationCode _provider) { super(_token, _expiration, _provider.getAccountServer()); if (_refreshToken == null) { throw new IllegalArgumentException("refreshToken can not be null"); @@ -63,23 +63,23 @@ public String getRefreshToken() { } @Override - public Observable refresh() { + public Observable refresh() { return provider.refreshToken(this); } @Override - public Observable restrict(List _claims) { - RenewableJsonWebToken that = this; + public Observable restrict(List _claims) { + AsyncRenewableJsonWebToken that = this; return super.restrict(_claims) - .map((JsonWebToken t) -> new RenewableJsonWebToken(t.getRawToken(), t.getExpiration(), "", provider) { + .map((AsyncJsonWebToken t) -> new AsyncRenewableJsonWebToken(t.getRawToken(), t.getExpiration(), "", provider) { @Override - public Observable refresh() { + public Observable refresh() { return that.refresh() - .map((OAuth2Token t1) -> (RenewableJsonWebToken) t1) - .flatMap((RenewableJsonWebToken t1) -> t1 + .map((AsyncOAuth2Token t1) -> (AsyncRenewableJsonWebToken) t1) + .flatMap((AsyncRenewableJsonWebToken t1) -> t1 .restrict(_claims) - .map((JsonWebToken t2) -> { + .map((AsyncJsonWebToken t2) -> { refresh("", t2.getRawToken(), t1.getExpiration()); return this; })); @@ -89,11 +89,11 @@ public Observable refresh() { } @Override - public Observable restrict(String... _claims) { + public Observable restrict(String... _claims) { return restrict(Arrays.asList(_claims)); } - public RenewableJsonWebToken refresh(String _refreshToken, String _accessToken, long _expiration) { + public AsyncRenewableJsonWebToken refresh(String _refreshToken, String _accessToken, long _expiration) { setRefreshToken(_refreshToken); setToken(_accessToken); setExpiration(_expiration); diff --git a/account/src/main/java/org/thethingsnetwork/account/AbstractApplication.java b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java similarity index 89% rename from account/src/main/java/org/thethingsnetwork/account/AbstractApplication.java rename to account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java index 92682a1..8c30296 100644 --- a/account/src/main/java/org/thethingsnetwork/account/AbstractApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account; +package org.thethingsnetwork.account.common; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.thethingsnetwork.account.auth.token.OAuth2Token; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; /** * @@ -41,6 +41,6 @@ public interface AbstractApplication { public void setName(String _name); - public void updateCredentials(OAuth2Token _creds); + public void updateCredentials(AsyncOAuth2Token _creds); } diff --git a/account/src/main/java/org/thethingsnetwork/account/AccessKey.java b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java similarity index 97% rename from account/src/main/java/org/thethingsnetwork/account/AccessKey.java rename to account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java index e2c6794..4a10a3a 100644 --- a/account/src/main/java/org/thethingsnetwork/account/AccessKey.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account; +package org.thethingsnetwork.account.common; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.Collections; diff --git a/account/src/main/java/org/thethingsnetwork/account/Collaborator.java b/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java similarity index 97% rename from account/src/main/java/org/thethingsnetwork/account/Collaborator.java rename to account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java index 21b12dc..c7c2689 100644 --- a/account/src/main/java/org/thethingsnetwork/account/Collaborator.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account; +package org.thethingsnetwork.account.common; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.Collections; diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java index d84f04c..1717b4e 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java @@ -24,17 +24,17 @@ package org.thethingsnetwork.account.sync; import java.util.List; -import org.thethingsnetwork.account.AbstractApplication; -import org.thethingsnetwork.account.AccessKey; -import org.thethingsnetwork.account.Collaborator; +import org.thethingsnetwork.account.common.AbstractApplication; +import org.thethingsnetwork.account.common.AccessKey; +import org.thethingsnetwork.account.common.Collaborator; import org.thethingsnetwork.account.async.AsyncApplication; -import org.thethingsnetwork.account.auth.token.OAuth2Token; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; /** * * @author Romain Cambier */ -public class Application implements AbstractApplication { +public class Application implements AbstractApplication{ private final AsyncApplication wrapped; @@ -46,7 +46,7 @@ private Application(AsyncApplication _wrap) { wrapped = _wrap; } - public static List findAll(OAuth2Token _creds) { + public static List findAll(AsyncOAuth2Token _creds) { return AsyncApplication.findAll(_creds) .map((AsyncApplication t) -> new Application(t)) .toList() @@ -54,14 +54,14 @@ public static List findAll(OAuth2Token _creds) { .single(); } - public static Application create(OAuth2Token _creds, AbstractApplication _app) { + public static Application create(AsyncOAuth2Token _creds, AbstractApplication _app) { return AsyncApplication.create(_creds, _app) .map((AsyncApplication t) -> new Application(t)) .toBlocking() .single(); } - public static Application findOne(OAuth2Token _creds, String _id) { + public static Application findOne(AsyncOAuth2Token _creds, String _id) { return AsyncApplication.findOne(_creds, _id) .map((AsyncApplication t) -> new Application(t)) .toBlocking() @@ -171,7 +171,7 @@ public List getRights() { .single(); } - public List getRights(OAuth2Token _creds) { + public List getRights(AsyncOAuth2Token _creds) { return wrapped.getRights(_creds) .toList() .toBlocking() @@ -199,7 +199,7 @@ public void setName(String _name) { } @Override - public void updateCredentials(OAuth2Token _creds) { + public void updateCredentials(AsyncOAuth2Token _creds) { wrapped.updateCredentials(_creds); } diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java new file mode 100644 index 0000000..38c4760 --- /dev/null +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java @@ -0,0 +1,64 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.account.sync.auth.grant; + +import java.net.URI; +import org.thethingsnetwork.account.async.auth.grant.AsyncApplicationPassword; +import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; +import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.sync.auth.token.JsonWebToken; + +/** + * + * @author Romain Cambier + */ +public class ApplicationPassword extends GrantType { + + private final AsyncApplicationPassword wrapped; + + public ApplicationPassword(AsyncApplicationPassword _wrapped) { + wrapped = _wrapped; + } + + public ApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret, URI _accountServer) { + wrapped = new AsyncApplicationPassword(_appId, _key, _clientId, _clientSecret, _accountServer); + } + + public ApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret) { + wrapped = new AsyncApplicationPassword(_appId, _key, _clientId, _clientSecret); + } + + @Override + public URI getAccountServer() { + return wrapped.getAccountServer(); + } + + public JsonWebToken getToken() { + return wrapped.getToken() + .map((AsyncJsonWebToken t) -> new JsonWebToken(t)) + .toBlocking() + .single(); + } + +} diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java new file mode 100644 index 0000000..4cb0e40 --- /dev/null +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java @@ -0,0 +1,65 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.account.sync.auth.grant; + +import java.net.URI; +import okhttp3.HttpUrl; +import org.thethingsnetwork.account.async.auth.grant.AsyncAuthorizationCode; +import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; +import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.sync.auth.token.RenewableJsonWebToken; + +/** + * + * @author Romain Cambier + */ +public class AuthorizationCode extends GrantType{ + + private final AsyncAuthorizationCode wrapped; + + public AuthorizationCode(String _clientId, String _clientSecret, URI _accountServer) { + wrapped = new AsyncAuthorizationCode(_clientId, _clientSecret, _accountServer); + } + + public AuthorizationCode(String _clientId, String _clientSecret) { + wrapped = new AsyncAuthorizationCode(_clientId, _clientSecret); + } + + @Override + public URI getAccountServer() { + return wrapped.getAccountServer(); + } + + public HttpUrl buildAuthorizationURL(URI _redirect) { + return wrapped.buildAuthorizationURL(_redirect); + } + + public RenewableJsonWebToken getToken(String _authorizationCode) { + return wrapped.getToken(_authorizationCode) + .map((AsyncRenewableJsonWebToken t) -> new RenewableJsonWebToken(t)) + .toBlocking() + .single(); + } + +} diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java new file mode 100644 index 0000000..44026a2 --- /dev/null +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java @@ -0,0 +1,90 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.account.sync.auth.token; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; + +/** + * + * @author Romain Cambier + */ +public class JsonWebToken implements OAuth2Token { + + private final AsyncJsonWebToken wrapped; + + public JsonWebToken(AsyncJsonWebToken _wrap) { + wrapped = _wrap; + } + + @Override + public boolean hasRefresh() { + return wrapped.hasRefresh(); + } + + @Override + public JsonWebToken refresh() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean isExpired() { + return wrapped.isExpired(); + } + + @Override + public String getToken() { + return wrapped.getToken(); + } + + @Override + public String getRawToken() { + return wrapped.getRawToken(); + } + + @Override + public URI getAccountServer() { + return wrapped.getAccountServer(); + } + + public JsonWebToken restrict(List _claims) { + return wrapped + .restrict(_claims) + .map((AsyncJsonWebToken t) -> new JsonWebToken(t)) + .toBlocking() + .single(); + } + + public JsonWebToken restrict(String... _claims) { + return restrict(Arrays.asList(_claims)); + } + + @Override + public AsyncJsonWebToken async() { + return wrapped; + } + +} diff --git a/account/src/main/java/org/thethingsnetwork/account/auth/token/OAuth2Token.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java similarity index 85% rename from account/src/main/java/org/thethingsnetwork/account/auth/token/OAuth2Token.java rename to account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java index 7ad9164..91e3745 100644 --- a/account/src/main/java/org/thethingsnetwork/account/auth/token/OAuth2Token.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java @@ -21,20 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.auth.token; +package org.thethingsnetwork.account.sync.auth.token; import java.net.URI; -import rx.Observable; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; /** * * @author Romain Cambier */ public interface OAuth2Token { - + public boolean hasRefresh(); - public Observable refresh(); + public T refresh(); public boolean isExpired(); @@ -43,5 +43,7 @@ public interface OAuth2Token { public String getRawToken(); public URI getAccountServer(); - + + public T async(); + } diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java new file mode 100644 index 0000000..bec557d --- /dev/null +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java @@ -0,0 +1,94 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.account.sync.auth.token; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; +import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; + +/** + * + * @author Romain Cambier + */ +public class RenewableJsonWebToken implements OAuth2Token { + + private final AsyncRenewableJsonWebToken wrapped; + + public RenewableJsonWebToken(AsyncRenewableJsonWebToken _wrap) { + wrapped = _wrap; + } + + @Override + public boolean hasRefresh() { + return wrapped.hasRefresh(); + } + + @Override + public RenewableJsonWebToken refresh() { + return wrapped + .refresh() + .map((AsyncRenewableJsonWebToken t) -> this) + .toBlocking() + .single(); + } + + @Override + public boolean isExpired() { + return wrapped.isExpired(); + } + + @Override + public String getToken() { + return wrapped.getToken(); + } + + @Override + public String getRawToken() { + return wrapped.getRawToken(); + } + + @Override + public URI getAccountServer() { + return wrapped.getAccountServer(); + } + + public JsonWebToken restrict(List _claims) { + return wrapped.restrict(_claims) + .map((AsyncJsonWebToken t) -> new JsonWebToken(t)) + .toBlocking() + .single(); + } + + public JsonWebToken restrict(String... _claims) { + return restrict(Arrays.asList(_claims)); + } + + @Override + public AsyncRenewableJsonWebToken async() { + return wrapped; + } + +} diff --git a/account/src/main/java/org/thethingsnetwork/account/common/HttpException.java b/account/src/main/java/org/thethingsnetwork/account/util/HttpException.java similarity index 97% rename from account/src/main/java/org/thethingsnetwork/account/common/HttpException.java rename to account/src/main/java/org/thethingsnetwork/account/util/HttpException.java index 68f40b6..a1f95ee 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/HttpException.java +++ b/account/src/main/java/org/thethingsnetwork/account/util/HttpException.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.common; +package org.thethingsnetwork.account.util; /** * diff --git a/account/src/main/java/org/thethingsnetwork/account/common/HttpRequest.java b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java similarity index 96% rename from account/src/main/java/org/thethingsnetwork/account/common/HttpRequest.java rename to account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java index 92dbff8..516a543 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/HttpRequest.java +++ b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.common; +package org.thethingsnetwork.account.util; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; @@ -37,7 +37,7 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; -import org.thethingsnetwork.account.auth.token.OAuth2Token; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; import rx.Observable; import rx.Subscriber; import rx.schedulers.Schedulers; @@ -100,13 +100,13 @@ public static Observable from(HttpUrl _url) { }); } - public Observable inject(OAuth2Token _creds) { + public Observable inject(AsyncOAuth2Token _creds) { if (_creds == null) { return Observable.just(this); } if (_creds.isExpired()) { if (_creds.hasRefresh()) { - return _creds.refresh().flatMap((OAuth2Token t) -> inject(t)); + return _creds.refresh().flatMap((AsyncOAuth2Token t) -> inject(t)); } else { return Observable.error(new Exception("non-renewable token expired")); } From 757e289aae6ecd4dcbb3288dde7bc6b5177aca80 Mon Sep 17 00:00:00 2001 From: cambierr Date: Tue, 20 Dec 2016 10:08:41 +0100 Subject: [PATCH 06/24] fixed license headers --- .../data/common/TriConsumer.java | 32 +++++++++++-------- .../data/common/messages/DownlinkMessage.java | 32 +++++++++++-------- .../data/common/messages/RawMessage.java | 32 +++++++++++-------- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java b/data/common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java index e9dde5b..605d9b8 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java @@ -1,19 +1,25 @@ /* - * Shareif.com CONFIDENTIAL - * ________________________ + * The MIT License * - * Copyright 2016 Shareif.com SPRL - * All Rights Reserved. + * Copyright (c) 2016 The Things Network * - * NOTICE: All information contained herein is, and remains - * the property of Shareif.com SPRL and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to Shareif.com SPRL - * and its suppliers and may be covered by Belgian and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material - * is strictly forbidden unless prior written permission is obtained - * from Shareif.com SPRL. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ package org.thethingsnetwork.data.common; diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java index 9f0fd5e..2cc7e14 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java @@ -1,19 +1,25 @@ /* - * Shareif.com CONFIDENTIAL - * ________________________ + * The MIT License * - * Copyright 2016 Shareif.com SPRL - * All Rights Reserved. + * Copyright (c) 2016 The Things Network * - * NOTICE: All information contained herein is, and remains - * the property of Shareif.com SPRL and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to Shareif.com SPRL - * and its suppliers and may be covered by Belgian and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material - * is strictly forbidden unless prior written permission is obtained - * from Shareif.com SPRL. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ package org.thethingsnetwork.data.common.messages; diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java index 0df08e6..e9427c1 100644 --- a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java +++ b/data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java @@ -1,19 +1,25 @@ /* - * Shareif.com CONFIDENTIAL - * ________________________ + * The MIT License * - * Copyright 2016 Shareif.com SPRL - * All Rights Reserved. + * Copyright (c) 2016 The Things Network * - * NOTICE: All information contained herein is, and remains - * the property of Shareif.com SPRL and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to Shareif.com SPRL - * and its suppliers and may be covered by Belgian and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material - * is strictly forbidden unless prior written permission is obtained - * from Shareif.com SPRL. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ package org.thethingsnetwork.data.common.messages; From a57c0c2c5525d0e28e0575e2531b95bd6cd05f59 Mon Sep 17 00:00:00 2001 From: cambierr Date: Tue, 20 Dec 2016 10:12:12 +0100 Subject: [PATCH 07/24] fixed management after account updates due to #28 --- management/src/main/java/Test.java | 145 ------------------ .../management/async/AsyncDiscovery.java | 8 +- .../management/async/AsyncHandler.java | 6 +- 3 files changed, 7 insertions(+), 152 deletions(-) delete mode 100644 management/src/main/java/Test.java diff --git a/management/src/main/java/Test.java b/management/src/main/java/Test.java deleted file mode 100644 index a8e0821..0000000 --- a/management/src/main/java/Test.java +++ /dev/null @@ -1,145 +0,0 @@ - -import java.util.concurrent.TimeUnit; -import rx.Observable; -import rx.Producer; -import rx.Subscriber; -import rx.schedulers.Schedulers; - -/* - * Shareif.com CONFIDENTIAL - * ________________________ - * - * Copyright 2016 Shareif.com SPRL - * All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains - * the property of Shareif.com SPRL and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to Shareif.com SPRL - * and its suppliers and may be covered by Belgian and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material - * is strictly forbidden unless prior written permission is obtained - * from Shareif.com SPRL. - */ -/** - * - * @author Romain Cambier - */ -public class Test { - - /** - * @param args the command line arguments - */ - public static void main(String[] args) throws InterruptedException { - - Observable s1 = serie(0, 10); - Observable s2 = serie(1, 10); - - Observable[] s = new Observable[]{s1, s2}; - - Observable - .create(new Observable.OnSubscribe() { - int i = 0; - - @Override - public void call(Subscriber t) { - - t.setProducer(new Producer() { - @Override - public void request(long n) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - }); - - for (Observable obs : s) { - obs.subscribe(new Subscriber() { - @Override - public void onCompleted() { - if (t.isUnsubscribed()) { - unsubscribe(); - return; - } - i++; - if (i == s.length) { - t.onCompleted(); - } - } - - @Override - public void onError(Throwable e) { - t.onError(e); - } - - @Override - public void onNext(Integer tt) { - if (t.isUnsubscribed()) { - unsubscribe(); - return; - } - t.onNext(tt); - } - - @Override - public void onStart() { - - } - }); - } - - } - }).subscribe(new Subscriber() { - @Override - public void onCompleted() { - System.out.println("got complete"); - } - - @Override - public void onError(Throwable e) { - e.printStackTrace(); - } - - @Override - public void onNext(Integer t) { - System.out.println("got " + t); - } - }); - - TimeUnit.SECONDS.sleep(5); - - } - - public static Observable serie(int _offset, int _max) { - return Observable - .create(new Observable.OnSubscribe() { - @Override - public void call(Subscriber t) { - t.setProducer(new Producer() { - int i = 0; - - @Override - public void request(long n) { - for (int j = 0; j < n; j++) { - if (t.isUnsubscribed()) { - System.out.println("broken"); - break; - } - try { - TimeUnit.MILLISECONDS.sleep(10); - } catch (Exception ex) { - - } - t.onNext(100 - (_offset + 5 * i++)); - if (i > _max) { - t.onCompleted(); - break; - } - } - } - }); - } - }) - .subscribeOn(Schedulers.io()); - } - -} diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java index f565e8d..cdb31f7 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java @@ -26,7 +26,7 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import java.io.ByteArrayInputStream; -import org.thethingsnetwork.account.auth.token.OAuth2Token; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; import org.thethingsnetwork.management.proto.DiscoveryGrpc; import org.thethingsnetwork.management.proto.DiscoveryOuterClass; import org.thethingsnetwork.management.proto.DiscoveryOuterClass.GetRequest; @@ -70,20 +70,20 @@ public static Observable getDefault() { return from(HOST, PORT); } - public Observable getHandler(OAuth2Token _creds, String _handlerId) { + public Observable getHandler(AsyncOAuth2Token _creds, String _handlerId) { return Observable .from(stub.get(GetRequest.newBuilder().setId(_handlerId).setServiceName(Services.HANDLER.name().toLowerCase()).build()), Schedulers.io()) .flatMap((DiscoveryOuterClass.Announcement t) -> from(_creds, t)); } - public Observable getHandlers(OAuth2Token _creds) { + public Observable getHandlers(AsyncOAuth2Token _creds) { return Observable .from(stub.getAll(DiscoveryOuterClass.GetServiceRequest.newBuilder().setServiceName(Services.HANDLER.name().toLowerCase()).build()), Schedulers.io()) .flatMap((DiscoveryOuterClass.AnnouncementsResponse t) -> Observable.from(t.getServicesList())) .flatMap((DiscoveryOuterClass.Announcement t) -> from(_creds, t)); } - private Observable from(OAuth2Token _creds, DiscoveryOuterClass.Announcement _announcement) { + private Observable from(AsyncOAuth2Token _creds, DiscoveryOuterClass.Announcement _announcement) { return Observable.from(_announcement.getNetAddress().split(",")) .flatMap((String tt) -> Observable .create((Subscriber t) -> { diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java index 76af16a..f53b4a5 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java @@ -34,8 +34,8 @@ import io.grpc.netty.NegotiationType; import io.grpc.netty.NettyChannelBuilder; import java.io.InputStream; -import org.thethingsnetwork.account.AbstractApplication; -import org.thethingsnetwork.account.auth.token.OAuth2Token; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; +import org.thethingsnetwork.account.common.AbstractApplication; import org.thethingsnetwork.management.HandlerApplication; import org.thethingsnetwork.management.HandlerDevice; import org.thethingsnetwork.management.proto.ApplicationManagerGrpc; @@ -56,7 +56,7 @@ private AsyncHandler(ApplicationManagerGrpc.ApplicationManagerFutureStub _stub) stub = _stub; } - public static Observable from(OAuth2Token _credentials, String _host, int _port, InputStream _certificate) { + public static Observable from(AsyncOAuth2Token _credentials, String _host, int _port, InputStream _certificate) { return Observable .create((Subscriber t) -> { From 97181a79e644ec37ee0e392a9a479ff24826c436 Mon Sep 17 00:00:00 2001 From: cambierr Date: Tue, 20 Dec 2016 14:21:46 +0100 Subject: [PATCH 08/24] first complete (not tested) implementation (async only) of #25 --- .../management/HandlerDevice.java | 69 ++++- .../management/LorawanDevice.java | 245 ++++++++++++++++++ .../management/async/AsyncHandler.java | 38 ++- 3 files changed, 346 insertions(+), 6 deletions(-) create mode 100644 management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java diff --git a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java index e57b0d4..a212fdd 100644 --- a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java @@ -23,10 +23,77 @@ */ package org.thethingsnetwork.management; +import org.thethingsnetwork.management.proto.DeviceOuterClass; +import org.thethingsnetwork.management.proto.HandlerOuterClass; +import rx.Observable; +import rx.Subscriber; + /** * * @author Romain Cambier */ public class HandlerDevice { - + + private final String appId; + private final String devId; + private LorawanDevice lorawan; + + private HandlerDevice(String _appId, String _devId, LorawanDevice _lorawan) { + appId = _appId; + devId = _devId; + lorawan = _lorawan; + } + + public String getAppId() { + return appId; + } + + public String getDevId() { + return devId; + } + + public LorawanDevice getLorawan() { + return lorawan; + } + + public static Observable from(HandlerOuterClass.Device _proto) { + + return LorawanDevice.from(_proto.getLorawanDevice()) + .flatMap((LorawanDevice tt) -> Observable + .create((Subscriber t) -> { + try { + t.onNext(new HandlerDevice( + _proto.getAppId(), + _proto.getDevId(), + tt + )); + t.onCompleted(); + } catch (Exception ex) { + t.onError(ex); + } + }) + ); + + } + + public Observable toProto() { + + return lorawan.toProto() + .flatMap((DeviceOuterClass.Device tt) -> Observable + .create((Subscriber t) -> { + try { + t.onNext(HandlerOuterClass.Device.newBuilder() + .setAppId(appId) + .setDevId(devId) + .setLorawanDevice(tt) + .build() + ); + t.onCompleted(); + } catch (Exception ex) { + t.onError(ex); + } + })); + + } + } diff --git a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java new file mode 100644 index 0000000..e663dcc --- /dev/null +++ b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java @@ -0,0 +1,245 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.management; + +import com.google.protobuf.ByteString; +import org.thethingsnetwork.management.proto.DeviceOuterClass; +import rx.Observable; +import rx.Subscriber; + +/** + * + * @author Romain Cambier + */ +public class LorawanDevice { + + private static final String[] validActivationConstraints = new String[]{"otaa", "abp", "world", "local", "private", "testing"}; + + private byte[] appEui; + private byte[] devEui; + private final String appId; + private final String devId; + private byte[] devAddr; + private byte[] nwkSKey; + private byte[] appSKey; + private byte[] appKey; + private int fCntUp; + private int fCntDown; + private boolean disableFCntCheck; + private boolean uses32BitFCnt; + private String activationConstraints; + private long lastSeen; + + public LorawanDevice(byte[] _appEui, byte[] _devEui, String _appId, String _devId, byte[] _devAddr, byte[] _nwkSKey, byte[] _appSKey, byte[] _appKey, int _fCntUp, int _fCntDown, boolean _disableFCntCheck, boolean _uses32BitFCnt, String _activationConstraints, long _lastSeen) { + appEui = _appEui; + devEui = _devEui; + appId = _appId; + devId = _devId; + devAddr = _devAddr; + nwkSKey = _nwkSKey; + appSKey = _appSKey; + appKey = _appKey; + fCntUp = _fCntUp; + fCntDown = _fCntDown; + disableFCntCheck = _disableFCntCheck; + uses32BitFCnt = _uses32BitFCnt; + activationConstraints = _activationConstraints; + lastSeen = _lastSeen; + } + + public static Observable from(DeviceOuterClass.Device _proto) { + + return Observable + .create((Subscriber t) -> { + try { + t.onNext(new LorawanDevice( + _proto.getAppEui().toByteArray(), + _proto.getDevEui().toByteArray(), + _proto.getAppId(), + _proto.getDevId(), + _proto.getDevAddr().toByteArray(), + _proto.getNwkSKey().toByteArray(), + _proto.getAppSKey().toByteArray(), + _proto.getAppKey().toByteArray(), + _proto.getFCntUp(), + _proto.getFCntDown(), + _proto.getDisableFCntCheck(), + _proto.getUses32BitFCnt(), + _proto.getActivationConstraints(), + _proto.getLastSeen() + )); + t.onCompleted(); + } catch (Exception ex) { + t.onError(ex); + } + }); + } + + public Observable toProto() { + + return Observable + .create((Subscriber t) -> { + try { + t.onNext(DeviceOuterClass.Device.newBuilder() + .setAppEui(ByteString.copyFrom(appEui)) + .setDevEui(ByteString.copyFrom(devEui)) + .setAppId(appId) + .setDevId(appId) + .setDevAddr(ByteString.copyFrom(devAddr)) + .setNwkSKey(ByteString.copyFrom(nwkSKey)) + .setAppSKey(ByteString.copyFrom(appSKey)) + .setAppKey(ByteString.copyFrom(appKey)) + .setFCntUp(fCntUp) + .setFCntDown(fCntDown) + .setDisableFCntCheck(disableFCntCheck) + .setUses32BitFCnt(uses32BitFCnt) + .setActivationConstraints(activationConstraints) + .setLastSeen(lastSeen) + .build() + ); + t.onCompleted(); + } catch (Exception ex) { + t.onError(ex); + } + }); + + } + + public byte[] getAppEui() { + return appEui; + } + + public void setAppEui(byte[] _appEui) { + if (_appEui.length != 8) { + throw new IllegalArgumentException("appEui should be 8 bytes long"); + } + appEui = _appEui; + } + + public byte[] getDevEui() { + return devEui; + } + + public void setDevEui(byte[] _devEui) { + if (_devEui.length != 8) { + throw new IllegalArgumentException("devEui should be 8 bytes long"); + } + devEui = _devEui; + } + + public String getAppId() { + return appId; + } + + public String getDevId() { + return devId; + } + + public byte[] getDevAddr() { + return devAddr; + } + + public void setDevAddr(byte[] _devAddr) { + if (_devAddr.length != 4) { + throw new IllegalArgumentException("devAddr should be 4 bytes long"); + } + devAddr = _devAddr; + } + + public byte[] getNwkSKey() { + return nwkSKey; + } + + public void setNwkSKey(byte[] _nwkSKey) { + if (_nwkSKey.length != 16) { + throw new IllegalArgumentException("nwkSKey should be 16 bytes long"); + } + nwkSKey = _nwkSKey; + } + + public byte[] getAppSKey() { + return appSKey; + } + + public void setAppSKey(byte[] _appSKey) { + if (_appSKey.length != 16) { + throw new IllegalArgumentException("appSKey should be 16 bytes long"); + } + appSKey = _appSKey; + } + + public byte[] getAppKey() { + return appKey; + } + + public void setAppKey(byte[] _appKey) { + if (_appKey.length != 16) { + throw new IllegalArgumentException("appKey should be 16 bytes long"); + } + appKey = _appKey; + } + + public int getfCntUp() { + return fCntUp; + } + + public int getfCntDown() { + return fCntDown; + } + + public boolean isDisableFCntCheck() { + return disableFCntCheck; + } + + public void setDisableFCntCheck(boolean _disableFCntCheck) { + disableFCntCheck = _disableFCntCheck; + } + + public boolean isUses32BitFCnt() { + return uses32BitFCnt; + } + + public void setUses32BitFCnt(boolean _uses32BitFCnt) { + uses32BitFCnt = _uses32BitFCnt; + } + + public String getActivationConstraints() { + return activationConstraints; + } + + public void setActivationConstraints(String _activationConstraints) { + for (String vac : validActivationConstraints) { + if (vac.equals(_activationConstraints)) { + activationConstraints = _activationConstraints; + return; + } + } + throw new IllegalArgumentException(_activationConstraints + " is not a valid activation constraint"); + } + + public long getLastSeen() { + return lastSeen; + } + +} diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java index f53b4a5..c48985e 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java @@ -133,19 +133,47 @@ public Observable deleteApplication(HandlerApplication _appl } public Observable getDevices(HandlerApplication _application) { - return null; + return Observable + .from(stub.getDevicesForApplication( + HandlerOuterClass.ApplicationIdentifier + .newBuilder() + .setAppId(_application.getAppId()) + .build() + ), Schedulers.io()) + .flatMap((HandlerOuterClass.DeviceList t) -> Observable.from(t.getDevicesList())) + .flatMap((HandlerOuterClass.Device t) -> HandlerDevice.from(t)); } - public Observable getDevice(String _deviceId) { - return null; + public Observable getDevice(HandlerApplication _application, String _deviceId) { + return Observable + .from(stub.getDevice( + HandlerOuterClass.DeviceIdentifier + .newBuilder() + .setAppId(_application.getAppId()) + .setDevId(_deviceId) + .build() + ), Schedulers.io()) + .flatMap((HandlerOuterClass.Device t) -> HandlerDevice.from(t)); } public Observable setDevice(HandlerDevice _device) { - return null; + return _device.toProto() + .flatMap((HandlerOuterClass.Device tt) -> Observable + .from(stub.setDevice(tt), Schedulers.io()) + .map((t) -> _device)); + } public Observable deleteDevice(HandlerDevice _device) { - return null; + return Observable + .from(stub.deleteDevice( + HandlerOuterClass.DeviceIdentifier + .newBuilder() + .setAppId(_device.getAppId()) + .setDevId(_device.getDevId()) + .build() + ), Schedulers.io()) + .map((t) -> _device); } } From b7dfdd0ab8a4cb259715de2038c091b1f6c8e31b Mon Sep 17 00:00:00 2001 From: cambierr Date: Thu, 22 Dec 2016 09:29:58 +0100 Subject: [PATCH 09/24] added sync version of management objects --- .../management/async/AsyncDiscovery.java | 4 +- .../management/sync/Discovery.java | 68 ++++++++++++ .../management/sync/Handler.java | 103 ++++++++++++++++++ 3 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java create mode 100644 management/src/main/java/org/thethingsnetwork/management/sync/Handler.java diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java index cdb31f7..f81b1da 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java @@ -40,8 +40,8 @@ */ public class AsyncDiscovery { - private static final String HOST = "discovery.thethingsnetwork.org"; - private static final int PORT = 1900; + public static final String HOST = "discovery.thethingsnetwork.org"; + public static final int PORT = 1900; private final DiscoveryGrpc.DiscoveryFutureStub stub; diff --git a/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java b/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java new file mode 100644 index 0000000..0816437 --- /dev/null +++ b/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java @@ -0,0 +1,68 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.management.sync; + +import java.util.List; +import org.thethingsnetwork.account.sync.auth.token.OAuth2Token; +import org.thethingsnetwork.management.async.AsyncDiscovery; +import org.thethingsnetwork.management.async.AsyncHandler; + +/** + * + * @author Romain Cambier + */ +public class Discovery { + + private final AsyncDiscovery wrapped; + + protected Discovery(AsyncDiscovery _wrap) { + wrapped = _wrap; + } + + public static Discovery from(String _host, int _port) { + return AsyncDiscovery.from(_host, _port) + .map((AsyncDiscovery t) -> new Discovery(t)) + .toBlocking() + .single(); + } + + public static Discovery getDefault() { + return from(AsyncDiscovery.HOST, AsyncDiscovery.PORT); + } + + public Handler getHandler(OAuth2Token _creds, String _handlerId) { + return wrapped.getHandler(_creds.async(), _handlerId) + .map((AsyncHandler t) -> new Handler(t)) + .toBlocking() + .single(); + } + + public List getHandlers(OAuth2Token _creds) { + return wrapped.getHandlers(_creds.async()) + .map((AsyncHandler t) -> new Handler(t)) + .toList() + .toBlocking() + .single(); + } +} diff --git a/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java b/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java new file mode 100644 index 0000000..c3d1452 --- /dev/null +++ b/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java @@ -0,0 +1,103 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.management.sync; + +import java.io.InputStream; +import java.util.List; +import org.thethingsnetwork.account.common.AbstractApplication; +import org.thethingsnetwork.account.sync.auth.token.OAuth2Token; +import org.thethingsnetwork.management.HandlerApplication; +import org.thethingsnetwork.management.HandlerDevice; +import org.thethingsnetwork.management.async.AsyncHandler; + +/** + * + * @author Romain Cambier + */ +public class Handler { + + private final AsyncHandler wrapped; + + protected Handler(AsyncHandler _wrap) { + wrapped = _wrap; + } + + public static Handler from(OAuth2Token _credentials, String _host, int _port, InputStream _certificate) { + return AsyncHandler.from(_credentials.async(), _host, _port, _certificate) + .map((AsyncHandler t) -> new Handler(t)) + .toBlocking() + .single(); + } + + public HandlerApplication registerApplication(AbstractApplication _application) { + return wrapped.registerApplication(_application) + .toBlocking() + .single(); + } + + public HandlerApplication getApplication(String _applicationId) { + return wrapped.getApplication(_applicationId) + .toBlocking() + .single(); + } + + public HandlerApplication setApplication(HandlerApplication _application) { + return wrapped.setApplication(_application) + .toBlocking() + .single(); + } + + public HandlerApplication deleteApplication(HandlerApplication _application) { + return wrapped.deleteApplication(_application) + .toBlocking() + .single(); + } + + public List getDevices(HandlerApplication _application) { + return wrapped.getDevices(_application) + .toList() + .toBlocking() + .single(); + } + + public HandlerDevice getDevice(HandlerApplication _application, String _deviceId) { + return wrapped.getDevice(_application, _deviceId) + .toBlocking() + .single(); + } + + public HandlerDevice setDevice(HandlerDevice _device) { + return wrapped.setDevice(_device) + .toBlocking() + .single(); + + } + + public HandlerDevice deleteDevice(HandlerDevice _device) { + return wrapped.deleteDevice(_device) + .toBlocking() + .single(); + } + +} From b9a18510b8241d0fead814a6fe50b87ee534f5d5 Mon Sep 17 00:00:00 2001 From: cambierr Date: Thu, 22 Dec 2016 09:46:47 +0100 Subject: [PATCH 10/24] added constructors for user-created objects added settes for editable fields --- .../management/HandlerApplication.java | 58 ++++++++++++------- .../management/HandlerDevice.java | 4 +- .../management/LorawanDevice.java | 34 ++++++++++- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java b/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java index 79c27c1..4d60635 100644 --- a/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java +++ b/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java @@ -33,30 +33,10 @@ */ public class HandlerApplication { - private String appId; + private final String appId; private String decoder; private String converter; private String validator; - - public String getAppId() { - return appId; - } - - public String getDecoder() { - return decoder; - } - - public String getConverter() { - return converter; - } - - public String getValidator() { - return validator; - } - - public String getEncoder() { - return encoder; - } private String encoder; private HandlerApplication(String _appId, String _decoder, String _converter, String _validator, String _encoder) { @@ -107,4 +87,40 @@ public Observable toProto() { }); } + + public String getAppId() { + return appId; + } + + public String getDecoder() { + return decoder; + } + + public String getConverter() { + return converter; + } + + public String getValidator() { + return validator; + } + + public String getEncoder() { + return encoder; + } + + public void setDecoder(String _decoder) { + decoder = _decoder; + } + + public void setConverter(String _converter) { + converter = _converter; + } + + public void setValidator(String _validator) { + validator = _validator; + } + + public void setEncoder(String _encoder) { + encoder = _encoder; + } } diff --git a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java index a212fdd..adcb289 100644 --- a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java @@ -36,9 +36,9 @@ public class HandlerDevice { private final String appId; private final String devId; - private LorawanDevice lorawan; + private final LorawanDevice lorawan; - private HandlerDevice(String _appId, String _devId, LorawanDevice _lorawan) { + public HandlerDevice(String _appId, String _devId, LorawanDevice _lorawan) { appId = _appId; devId = _devId; lorawan = _lorawan; diff --git a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java index e663dcc..f19a516 100644 --- a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java @@ -51,7 +51,7 @@ public class LorawanDevice { private String activationConstraints; private long lastSeen; - public LorawanDevice(byte[] _appEui, byte[] _devEui, String _appId, String _devId, byte[] _devAddr, byte[] _nwkSKey, byte[] _appSKey, byte[] _appKey, int _fCntUp, int _fCntDown, boolean _disableFCntCheck, boolean _uses32BitFCnt, String _activationConstraints, long _lastSeen) { + private LorawanDevice(byte[] _appEui, byte[] _devEui, String _appId, String _devId, byte[] _devAddr, byte[] _nwkSKey, byte[] _appSKey, byte[] _appKey, int _fCntUp, int _fCntDown, boolean _disableFCntCheck, boolean _uses32BitFCnt, String _activationConstraints, long _lastSeen) { appEui = _appEui; devEui = _devEui; appId = _appId; @@ -68,6 +68,38 @@ public LorawanDevice(byte[] _appEui, byte[] _devEui, String _appId, String _devI lastSeen = _lastSeen; } + public static LorawanDevice createOTAA(String _appId, String _devId, byte[] _appEui, byte[] _devEui, byte[] _appKey) { + if (_appEui.length != 8) { + throw new IllegalArgumentException("appEui should be 8 bytes long"); + } + if (_devEui.length != 8) { + throw new IllegalArgumentException("devEui should be 8 bytes long"); + } + if (_appKey.length != 16) { + throw new IllegalArgumentException("appKey should be 16 bytes long"); + } + return new LorawanDevice(_appEui, _devEui, _appId, _devId, null, null, null, _appKey, 0, 0, false, true, "otaa", 0); + } + + public static LorawanDevice createABP(String _appId, String _devId, byte[] _appEui, byte[] _devEui, byte[] _devAddr, byte[] _nwkSKey, byte[] _appSKey, boolean _disableFCntCheck, boolean _uses32BitFCnt) { + if (_appEui.length != 8) { + throw new IllegalArgumentException("appEui should be 8 bytes long"); + } + if (_devEui.length != 8) { + throw new IllegalArgumentException("devEui should be 8 bytes long"); + } + if (_devAddr.length != 4) { + throw new IllegalArgumentException("devAddr should be 4 bytes long"); + } + if (_nwkSKey.length != 16) { + throw new IllegalArgumentException("nwkSKey should be 16 bytes long"); + } + if (_appSKey.length != 16) { + throw new IllegalArgumentException("appSKey should be 16 bytes long"); + } + return new LorawanDevice(_appEui, _devEui, _appId, _devId, _devAddr, _nwkSKey, _appSKey, null, 0, 0, _disableFCntCheck, _uses32BitFCnt, "abp", 0); + } + public static Observable from(DeviceOuterClass.Device _proto) { return Observable From 0d4426192e5a537e37a38642acd7fc753891dcda Mon Sep 17 00:00:00 2001 From: cambierr Date: Thu, 22 Dec 2016 10:43:06 +0100 Subject: [PATCH 11/24] removed useless check --- .../management/LorawanDevice.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java index f19a516..b2dfae6 100644 --- a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java @@ -34,8 +34,6 @@ */ public class LorawanDevice { - private static final String[] validActivationConstraints = new String[]{"otaa", "abp", "world", "local", "private", "testing"}; - private byte[] appEui; private byte[] devEui; private final String appId; @@ -49,7 +47,7 @@ public class LorawanDevice { private boolean disableFCntCheck; private boolean uses32BitFCnt; private String activationConstraints; - private long lastSeen; + private final long lastSeen; private LorawanDevice(byte[] _appEui, byte[] _devEui, String _appId, String _devId, byte[] _devAddr, byte[] _nwkSKey, byte[] _appSKey, byte[] _appKey, int _fCntUp, int _fCntDown, boolean _disableFCntCheck, boolean _uses32BitFCnt, String _activationConstraints, long _lastSeen) { appEui = _appEui; @@ -261,17 +259,19 @@ public String getActivationConstraints() { } public void setActivationConstraints(String _activationConstraints) { - for (String vac : validActivationConstraints) { - if (vac.equals(_activationConstraints)) { - activationConstraints = _activationConstraints; - return; - } - } - throw new IllegalArgumentException(_activationConstraints + " is not a valid activation constraint"); + activationConstraints = _activationConstraints; } public long getLastSeen() { return lastSeen; } + public void resetFCntUp() { + fCntUp = 0; + } + + public void resetFCntDown() { + fCntDown = 0; + } + } From 0553a35c654aa533624f60ed78e252b8d4b4517d Mon Sep 17 00:00:00 2001 From: cambierr Date: Thu, 22 Dec 2016 13:17:11 +0100 Subject: [PATCH 12/24] removex restrict stuff on non-renewable jwt --- .../account/async/AsyncApplication.java | 170 ++++++++++++++++-- .../async/auth/token/AsyncJsonWebToken.java | 53 ------ .../token/AsyncRenewableJsonWebToken.java | 48 ++++- .../account/common/AbstractApplication.java | 25 ++- .../account/sync/Application.java | 21 ++- .../account/sync/auth/token/JsonWebToken.java | 14 -- .../account/util/HttpRequest.java | 4 + 7 files changed, 238 insertions(+), 97 deletions(-) diff --git a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java index 3526c17..86e05be 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java @@ -26,15 +26,18 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import okhttp3.RequestBody; import okhttp3.Response; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; import org.thethingsnetwork.account.common.AbstractApplication; import org.thethingsnetwork.account.common.AccessKey; import org.thethingsnetwork.account.common.Collaborator; +import org.thethingsnetwork.account.sync.Application; import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; -import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; /** + * This class is an async wrapper for an TTN application. * + * @see Application for a sync version * @author Romain Cambier */ public class AsyncApplication implements AbstractApplication { @@ -48,6 +51,12 @@ public class AsyncApplication implements AbstractApplication { private AsyncApplication() { } + /** + * Create a new application + * + * @param _id the new application ID + * @param _name the new application name + */ public AsyncApplication(String _id, String _name) { id = _id; name = _name; @@ -85,6 +94,12 @@ private void refresh(AsyncApplication _other) { creds = _other.creds; } + /** + * List all applications available with this token + * + * @param _creds the AsyncOAuth2Token to be used for authentication + * @return the list of AsyncApplication as an Observable stream + */ public static Observable findAll(AsyncOAuth2Token _creds) { /** * GET /applications @@ -98,6 +113,13 @@ public static Observable findAll(AsyncOAuth2Token _creds) { .doOnNext((AsyncApplication app) -> app.updateCredentials(_creds)); } + /** + * Create an application + * + * @param _creds the AsyncOAuth2Token to be used for authentication + * @param _app the AsyncApplication template + * @return the new AsyncApplication as an Observable stream. + */ public static Observable create(AsyncOAuth2Token _creds, AbstractApplication _app) { /** * POST /applications @@ -116,6 +138,13 @@ public static Observable create(AsyncOAuth2Token _creds, Abstr .doOnNext((AsyncApplication ap) -> ap.updateCredentials(_creds)); } + /** + * Fetch an application + * + * @param _creds the AsyncOAuth2Token to be used for authentication + * @param _id the application ID to fetch + * @return the AsyncApplication as an Observable stream. + */ public static Observable findOne(AsyncOAuth2Token _creds, String _id) { /** * GET /applications/{app_id} @@ -128,16 +157,34 @@ public static Observable findOne(AsyncOAuth2Token _creds, Stri .doOnNext((AsyncApplication app) -> app.updateCredentials(_creds)); } + /** + * Update this application + * + * @return the updated AsyncApplication as an Observable stream. + */ public Observable save() { /** * PATCH /applications/{app_id} */ - /** - * @todo: implement - */ - return Observable.error(new UnsupportedOperationException("Not supported yet.")); + return HttpRequest + .from(creds.getAccountServer() + "/applications/" + id) + .flatMap((HttpRequest t) -> t.inject(creds)) + .flatMap((HttpRequest t) -> HttpRequest + .buildRequestBody(this) + .map((RequestBody rb) -> { + t.getBuilder().patch(rb); + return t; + }) + ) + .flatMap((HttpRequest t) -> t.doExecute()) + .map((i) -> this); } + /** + * Delete this application + * + * @return the updated AsyncApplication as an Observable stream. + */ public Observable delete() { /** * DELETE /applications/{app_id} @@ -150,6 +197,11 @@ public Observable delete() { .map((Response r) -> this); } + /** + * List all EUIs of this application + * + * @return the EUIs of this AsyncApplication as an Observable stream. + */ public Observable findAllEUIs() { /** * GET /applications/{app_id}/euis @@ -162,6 +214,11 @@ public Observable findAllEUIs() { .flatMap(Observable::from); } + /** + * Create a random EUI on this application + * + * @return the new EUI as an Observable stream. + */ public Observable createEUI() { /** * POST /applications/{app_id}/euis @@ -174,7 +231,13 @@ public Observable createEUI() { .map((EuiCreationResponse t) -> t.eui); } - public Observable addEUI(String _eui) { + /** + * Create a defined EUI on this application + * + * @param _eui the new EUI + * the updated AsyncApplication as an Observable stream. + */ + public Observable addEUI(String _eui) { /** * PUT /applications/{app_id}/euis/{eui} */ @@ -183,10 +246,16 @@ public Observable addEUI(String _eui) { .flatMap((HttpRequest t) -> t.inject(creds)) .doOnNext((HttpRequest t) -> t.getBuilder().put(RequestBody.create(null, new byte[0]))) .flatMap((HttpRequest t) -> t.doExecute()) - .map((Response r) -> _eui); + .map((Response r) -> this); } - public Observable deleteEUI(String _eui) { + /** + * Delete an EUI from this application + * + * @param _eui the EUI to be deleted + * @return the updated AsyncApplication as an Observable stream. + */ + public Observable deleteEUI(String _eui) { /** * DELETE /applications/{app_id}/euis/{eui} */ @@ -195,9 +264,14 @@ public Observable deleteEUI(String _eui) { .flatMap((HttpRequest t) -> t.inject(creds)) .doOnNext((HttpRequest t) -> t.getBuilder().delete()) .flatMap((HttpRequest t) -> t.doExecute()) - .map((Response r) -> _eui); + .map((Response r) -> this); } + /** + * List all collaborators of this application + * + * @return the list of Collaborator of this AsyncApplication as an Observable stream. + */ public Observable getCollaborators() { /** * GET /applications/{app_id}/collaborators @@ -210,6 +284,12 @@ public Observable getCollaborators() { .flatMap((Collaborator[] cs) -> Observable.from(cs)); } + /** + * Fetch one collaborator from this application + * + * @param _username the username of the Collaborator + * @return the Collaborator as an Observable stream. + */ public Observable findOneCollaborator(String _username) { /** * GET /applications/{app_id}/collaborators/{username} @@ -221,7 +301,13 @@ public Observable findOneCollaborator(String _username) { .flatMap((HttpRequest t) -> t.doExecuteForType(Collaborator.class)); } - public Observable addCollaborator(Collaborator _collaborator) { + /** + * Add a collaborator to this application + * + * @param _collaborator the Collaborator to be added + * @return the updated AsyncApplication as an Observable stream. + */ + public Observable addCollaborator(Collaborator _collaborator) { /** * PUT /applications/{app_id}/collaborators/{username} */ @@ -236,10 +322,16 @@ public Observable addCollaborator(Collaborator _collaborator) { }) ) .flatMap((HttpRequest t) -> t.doExecute()) - .map((Response c) -> _collaborator); + .map((Response c) -> this); } - public Observable removeCollaborator(Collaborator _collaborator) { + /** + * Remove a collaborator from this application + * + * @param _collaborator the Collaborator to be removed + * @return the updated AsyncApplication as an Observable stream. + */ + public Observable removeCollaborator(Collaborator _collaborator) { /** * DELETE /applications/{app_id}/euis/{eui} */ @@ -248,9 +340,14 @@ public Observable removeCollaborator(Collaborator _collaborator) { .flatMap((HttpRequest t) -> t.inject(creds)) .doOnNext((HttpRequest t) -> t.getBuilder().delete()) .flatMap((HttpRequest t) -> t.doExecute()) - .map((Response c) -> _collaborator); + .map((Response c) -> this); } + /** + * List all access-keys of this application + * + * @return the list of AccessKey of this AsyncApplication as an Observable stream. + */ public Observable getAccessKeys() { /** * GET /applications/{app_id}/access-keys @@ -263,6 +360,12 @@ public Observable getAccessKeys() { .flatMap((AccessKey[] cs) -> Observable.from(cs)); } + /** + * Fetch one access-key of this application + * + * @param _keyname the name of the AccessKey + * @return the AccessKey as an Observable stream. + */ public Observable findOneAccessKey(String _keyname) { /** * GET /applications/{app_id}/access-keys/{keyname} @@ -274,6 +377,12 @@ public Observable findOneAccessKey(String _keyname) { .flatMap((HttpRequest t) -> t.doExecuteForType(AccessKey.class)); } + /** + * Add an access-key to this application + * + * @param _key the AccessKey template + * @return the new AccessKey as an Observable stream. + */ public Observable addAccessKey(AccessKey _key) { /** * POST /applications/{app_id}/access-keys/{username} @@ -288,11 +397,17 @@ public Observable addAccessKey(AccessKey _key) { return t; }) ) - .flatMap((HttpRequest t) -> t.doExecute()) - .map((Response c) -> _key); + .flatMap((HttpRequest t) -> t.doExecuteForType(AccessKey.class)) + .map((AccessKey c) -> c); } - public Observable removeAccessKey(AccessKey _key) { + /** + * Remove an access-key from this application + * + * @param _key the AccessKey + * @return the updated AsyncApplication as an Observable stream. + */ + public Observable removeAccessKey(AccessKey _key) { /** * DELETE /applications/{app_id}/access-keys/{keyname} */ @@ -301,19 +416,35 @@ public Observable removeAccessKey(AccessKey _key) { .flatMap((HttpRequest t) -> t.inject(creds)) .doOnNext((HttpRequest t) -> t.getBuilder().delete()) .flatMap((HttpRequest t) -> t.doExecute()) - .map((Response c) -> _key); + .map((Response c) -> this); } + /** + * Refresh this local application + * + * @return the updated AsyncApplication as an Observable stream. + */ public Observable refresh() { return findOne(creds, getId()) .doOnNext((AsyncApplication t) -> refresh(t)) .map((AsyncApplication app) -> this); } + /** + * List all rights of this application and token + * + * @return the list of rights (String) of this AsyncApplication as an Observable stream. + */ public Observable getRights() { return getRights(creds); } + /** + * List all rights of the provided token on this application + * + * @param _creds the AsyncOAuth2Token to check right of + * @return the list of rights (String) of this AsyncApplication as an Observable stream. + */ public Observable getRights(AsyncOAuth2Token _creds) { /** * GET /applications/{app_id}/rights @@ -326,6 +457,11 @@ public Observable getRights(AsyncOAuth2Token _creds) { .flatMap(Observable::from); } + @Override + public String toString() { + return "Application \"" + name + "\" (" + id + ")"; + } + private static class EuiCreationResponse { public String eui; diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java index 3d02205..4615579 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java @@ -24,13 +24,7 @@ package org.thethingsnetwork.account.async.auth.token; import java.net.URI; -import java.util.Arrays; -import java.util.List; -import okhttp3.HttpUrl; -import okhttp3.RequestBody; -import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; -import rx.Subscriber; /** * @@ -94,56 +88,9 @@ public URI getAccountServer() { return accountServer; } - public Observable restrict(List _claims) { - return Observable - .create((Subscriber t) -> { - try { - t.onNext(new HttpUrl.Builder() - .host(accountServer.getHost()) - .scheme(accountServer.getScheme()) - .port(accountServer.getPort() == -1 ? (accountServer.getScheme().equals("http") ? 80 : 443) : accountServer.getPort()) - .addPathSegments("users/restrict-token") - .build() - ); - t.onCompleted(); - } catch (Exception ex) { - t.onError(ex); - } - }) - .flatMap(HttpRequest::from) - .flatMap((HttpRequest t) -> t.inject(this)) - .flatMap((HttpRequest t) -> HttpRequest - .buildRequestBody(new RestrictRequest(_claims)) - .map((RequestBody rb) -> { - t.getBuilder().post(rb); - return t; - }) - ) - .flatMap((HttpRequest t) -> t.doExecuteForType(RestrictResponse.class)) - .map((RestrictResponse t) -> new AsyncJsonWebToken(t.accessToken, expiration, accountServer)); - } - - public Observable restrict(String... _claims) { - return restrict(Arrays.asList(_claims)); - } - @Override public String getRawToken() { return token; } - private class RestrictRequest { - - public List scope; - - public RestrictRequest(List _scope) { - scope = _scope; - } - } - - private static class RestrictResponse { - - public String accessToken; - } - } diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java index 33f68da..451a5a1 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java @@ -25,8 +25,12 @@ import java.util.Arrays; import java.util.List; +import okhttp3.HttpUrl; +import okhttp3.RequestBody; import org.thethingsnetwork.account.async.auth.grant.AsyncAuthorizationCode; +import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; +import rx.Subscriber; /** * @@ -67,11 +71,34 @@ public Observable refresh() { return provider.refreshToken(this); } - @Override public Observable restrict(List _claims) { AsyncRenewableJsonWebToken that = this; - return super.restrict(_claims) - .map((AsyncJsonWebToken t) -> new AsyncRenewableJsonWebToken(t.getRawToken(), t.getExpiration(), "", provider) { + return Observable + .create((Subscriber t) -> { + try { + t.onNext(new HttpUrl.Builder() + .host(getAccountServer().getHost()) + .scheme(getAccountServer().getScheme()) + .port(getAccountServer().getPort() == -1 ? (getAccountServer().getScheme().equals("http") ? 80 : 443) : getAccountServer().getPort()) + .addPathSegments("users/restrict-token") + .build() + ); + t.onCompleted(); + } catch (Exception ex) { + t.onError(ex); + } + }) + .flatMap(HttpRequest::from) + .flatMap((HttpRequest t) -> t.inject(this)) + .flatMap((HttpRequest t) -> HttpRequest + .buildRequestBody(new RestrictRequest(_claims)) + .map((RequestBody rb) -> { + t.getBuilder().post(rb); + return t; + }) + ) + .flatMap((HttpRequest t) -> t.doExecuteForType(RestrictResponse.class)) + .map((RestrictResponse t) -> new AsyncRenewableJsonWebToken(t.accessToken, getExpiration(), "", provider) { @Override public Observable refresh() { @@ -88,7 +115,6 @@ public Observable refresh() { }); } - @Override public Observable restrict(String... _claims) { return restrict(Arrays.asList(_claims)); } @@ -99,4 +125,18 @@ public AsyncRenewableJsonWebToken refresh(String _refreshToken, String _accessTo setExpiration(_expiration); return this; } + + private class RestrictRequest { + + public List scope; + + public RestrictRequest(List _scope) { + scope = _scope; + } + } + + private static class RestrictResponse { + + public String accessToken; + } } diff --git a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java index 8c30296..e68d4f6 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java @@ -33,14 +33,37 @@ @JsonIgnoreProperties(ignoreUnknown = true) public interface AbstractApplication { + /** + * Get the application ID + * + * @return the application ID + */ public String getId(); + /** + * Get the application name + * + * @return the application name + */ public String getName(); + /** + * Get the application creation time + * + * @return the application creation time + */ public String getCreated(); + /** + * Update the application name + * @param _name the new name to be set + */ public void setName(String _name); - + + /** + * Update the AsyncOAuth2Token to be used by this application wrapper + * @param _creds the new AsyncOAuth2Token to be used + */ public void updateCredentials(AsyncOAuth2Token _creds); } diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java index 1717b4e..141699f 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java @@ -24,17 +24,17 @@ package org.thethingsnetwork.account.sync; import java.util.List; +import org.thethingsnetwork.account.async.AsyncApplication; +import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; import org.thethingsnetwork.account.common.AbstractApplication; import org.thethingsnetwork.account.common.AccessKey; import org.thethingsnetwork.account.common.Collaborator; -import org.thethingsnetwork.account.async.AsyncApplication; -import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; /** * * @author Romain Cambier */ -public class Application implements AbstractApplication{ +public class Application implements AbstractApplication { private final AsyncApplication wrapped; @@ -95,14 +95,16 @@ public String createEUI() { .single(); } - public String addEUI(String _eui) { + public Application addEUI(String _eui) { return wrapped.addEUI(_eui) + .map((i) -> this) .toBlocking() .single(); } - public String deleteEUI(String _eui) { + public Application deleteEUI(String _eui) { return wrapped.deleteEUI(_eui) + .map((i) -> this) .toBlocking() .single(); } @@ -120,14 +122,16 @@ public Collaborator findOneCollaborator(String _username) { .singleOrDefault(null); } - public Collaborator addCollaborator(Collaborator _collaborator) { + public Application addCollaborator(Collaborator _collaborator) { return wrapped.addCollaborator(_collaborator) + .map((i) -> this) .toBlocking() .single(); } - public Collaborator removeCollaborator(Collaborator _collaborator) { + public Application removeCollaborator(Collaborator _collaborator) { return wrapped.removeCollaborator(_collaborator) + .map((i) -> this) .toBlocking() .single(); } @@ -151,8 +155,9 @@ public AccessKey addAccessKey(AccessKey _key) { .single(); } - public AccessKey removeAccessKey(AccessKey _key) { + public Application removeAccessKey(AccessKey _key) { return wrapped.removeAccessKey(_key) + .map((i) -> this) .toBlocking() .single(); } diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java index 44026a2..98b39ed 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java @@ -24,8 +24,6 @@ package org.thethingsnetwork.account.sync.auth.token; import java.net.URI; -import java.util.Arrays; -import java.util.List; import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; /** @@ -70,18 +68,6 @@ public URI getAccountServer() { return wrapped.getAccountServer(); } - public JsonWebToken restrict(List _claims) { - return wrapped - .restrict(_claims) - .map((AsyncJsonWebToken t) -> new JsonWebToken(t)) - .toBlocking() - .single(); - } - - public JsonWebToken restrict(String... _claims) { - return restrict(Arrays.asList(_claims)); - } - @Override public AsyncJsonWebToken async() { return wrapped; diff --git a/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java index 516a543..1ebabb7 100644 --- a/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java +++ b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java @@ -195,6 +195,10 @@ public Observable doExecuteForType(Class _type) { ); } + + public static void shutdown(){ + client.dispatcher().executorService().shutdown(); + } public Request.Builder getBuilder() { return builder; From 5b82c2d08f3a7c784f3c95b39b66dd740ecbc57c Mon Sep 17 00:00:00 2001 From: cambierr Date: Fri, 23 Dec 2016 12:03:34 +0100 Subject: [PATCH 13/24] added ApplicationRights mapper (account) added account sample (not complete: missing app password) --- .gitignore | 4 +- account/pom.xml | 6 +- .../account/async/AsyncApplication.java | 17 +- .../auth/grant/AsyncApplicationPassword.java | 25 ++- .../auth/grant/AsyncAuthorizationCode.java | 52 +++++- .../token/AsyncRenewableJsonWebToken.java | 4 +- .../account/auth/grant/GrantType.java | 4 + .../account/common/AbstractApplication.java | 5 +- .../account/common/AccessKey.java | 6 +- .../account/common/ApplicationRights.java | 53 ++++++ .../account/sync/Application.java | 20 ++- .../auth/token/RenewableJsonWebToken.java | 7 +- pom.xml | 2 +- samples/pom.xml | 3 +- samples/samples-account/pom.xml | 26 +++ .../thethingsnetwork/samples/account/App.java | 67 ++++++++ .../account/AuthorizationCodeAsync.java | 156 ++++++++++++++++++ .../account/AuthorizationCodeSync.java | 83 ++++++++++ samples/{mqtt => samples-mqtt}/pom.xml | 0 .../thethingsnetwork/samples/mqtt/App.java | 0 20 files changed, 497 insertions(+), 43 deletions(-) create mode 100644 account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java create mode 100644 samples/samples-account/pom.xml create mode 100644 samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java create mode 100644 samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java create mode 100644 samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java rename samples/{mqtt => samples-mqtt}/pom.xml (100%) rename samples/{mqtt => samples-mqtt}/src/main/java/org/thethingsnetwork/samples/mqtt/App.java (100%) diff --git a/.gitignore b/.gitignore index aeda362..d4e796d 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,6 @@ /data/target/ /samples/mqtt/target/ /.license -/management/src/main/proto/ \ No newline at end of file +/management/src/main/proto/ +/samples/account/target/ +/samples/samples-account/target/ \ No newline at end of file diff --git a/account/pom.xml b/account/pom.xml index da2746e..beb0913 100644 --- a/account/pom.xml +++ b/account/pom.xml @@ -24,17 +24,17 @@ io.reactivex rxjava - 1.1.10 + 1.2.3 com.fasterxml.jackson.core jackson-databind - 2.8.3 + 2.8.5 com.squareup.okhttp3 okhttp - 3.4.2 + 3.5.0 \ No newline at end of file diff --git a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java index 86e05be..6cd7a2a 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java @@ -29,6 +29,7 @@ import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; import org.thethingsnetwork.account.common.AbstractApplication; import org.thethingsnetwork.account.common.AccessKey; +import org.thethingsnetwork.account.common.ApplicationRights; import org.thethingsnetwork.account.common.Collaborator; import org.thethingsnetwork.account.sync.Application; import org.thethingsnetwork.account.util.HttpRequest; @@ -40,7 +41,7 @@ * @see Application for a sync version * @author Romain Cambier */ -public class AsyncApplication implements AbstractApplication { +public class AsyncApplication implements AbstractApplication { private String id; private String name; @@ -235,7 +236,7 @@ public Observable createEUI() { * Create a defined EUI on this application * * @param _eui the new EUI - * the updated AsyncApplication as an Observable stream. + * @return the updated AsyncApplication as an Observable stream. */ public Observable addEUI(String _eui) { /** @@ -385,7 +386,7 @@ public Observable findOneAccessKey(String _keyname) { */ public Observable addAccessKey(AccessKey _key) { /** - * POST /applications/{app_id}/access-keys/{username} + * POST /applications/{app_id}/access-keys */ return HttpRequest .from(creds.getAccountServer() + "/applications/" + getId() + "/access-keys") @@ -433,9 +434,9 @@ public Observable refresh() { /** * List all rights of this application and token * - * @return the list of rights (String) of this AsyncApplication as an Observable stream. + * @return the list of ApplicationRights of this AsyncApplication as an Observable stream. */ - public Observable getRights() { + public Observable getRights() { return getRights(creds); } @@ -443,9 +444,9 @@ public Observable getRights() { * List all rights of the provided token on this application * * @param _creds the AsyncOAuth2Token to check right of - * @return the list of rights (String) of this AsyncApplication as an Observable stream. + * @return the list of ApplicationRights of this AsyncApplication as an Observable stream. */ - public Observable getRights(AsyncOAuth2Token _creds) { + public Observable getRights(AsyncOAuth2Token _creds) { /** * GET /applications/{app_id}/rights */ @@ -453,7 +454,7 @@ public Observable getRights(AsyncOAuth2Token _creds) { .from(creds.getAccountServer() + "/applications/" + getId() + "/rights") .flatMap((HttpRequest t) -> t.inject(_creds)) .doOnNext((HttpRequest t) -> t.getBuilder().get()) - .flatMap((HttpRequest t) -> t.doExecuteForType(String[].class)) + .flatMap((HttpRequest t) -> t.doExecuteForType(ApplicationRights[].class)) .flatMap(Observable::from); } diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java index 98d6378..8b9aeca 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java @@ -27,13 +27,14 @@ import java.util.Base64; import okhttp3.HttpUrl; import okhttp3.RequestBody; -import org.thethingsnetwork.account.auth.grant.GrantType; import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; +import org.thethingsnetwork.account.auth.grant.GrantType; import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; import rx.Subscriber; /** + * This token provider uses application credentials (id + access-key) to generate a token only usable for the owning application * * @author Romain Cambier */ @@ -45,6 +46,15 @@ public class AsyncApplicationPassword extends GrantType { private final String key; private final URI accountServer; + /** + * Create an instance of this token provider using fully-customized settings + * + * @param _appId The application id + * @param _key The application access-key + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + * @param _accountServer The account server to be used + */ public AsyncApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret, URI _accountServer) { if (_key == null) { throw new IllegalArgumentException("key can not be null"); @@ -68,6 +78,14 @@ public AsyncApplicationPassword(String _appId, String _key, String _clientId, St clientSecret = _clientSecret; } + /** + * Create an instance of this token provider using default account server + * + * @param _appId The application id + * @param _key The application access-key + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + */ public AsyncApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret) { this(_appId, _key, _clientId, _clientSecret, GrantType.DEFAULT_ACCOUNT_SERVER); } @@ -81,6 +99,11 @@ private String getBasicAuthHeader() { return "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()); } + /** + * Create a token using the settings provided in the constructor + * + * @return the AsyncJsonWebToken as an Observable stream + */ public Observable getToken() { return Observable .create((Subscriber t) -> { diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java index 92704dc..94425bc 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java @@ -27,13 +27,14 @@ import java.util.Base64; import okhttp3.HttpUrl; import okhttp3.RequestBody; -import org.thethingsnetwork.account.auth.grant.GrantType; import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; +import org.thethingsnetwork.account.auth.grant.GrantType; import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; import rx.Subscriber; /** + * This token provider uses authorization-code flow, meaning it requires user-interraction * * @author Romain Cambier */ @@ -43,6 +44,13 @@ public class AsyncAuthorizationCode extends GrantType { private final String clientSecret; private final URI accountServer; + /** + * Create an instance of this token provider using fully-customized settings + * + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + * @param _accountServer The account server to be used + */ public AsyncAuthorizationCode(String _clientId, String _clientSecret, URI _accountServer) { if (_clientId == null) { throw new IllegalArgumentException("clientId can not be null"); @@ -58,6 +66,12 @@ public AsyncAuthorizationCode(String _clientId, String _clientSecret, URI _accou accountServer = _accountServer; } + /** + * Create an instance of this token provider using default account server + * + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + */ public AsyncAuthorizationCode(String _clientId, String _clientSecret) { this(_clientId, _clientSecret, GrantType.DEFAULT_ACCOUNT_SERVER); } @@ -71,6 +85,16 @@ private String getBasicAuthHeader() { return "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()); } + /** + * Generate an authorization endpoint to be sent to the user. + * + * Once the user will proceed to authorization (even in case of error) he will redirected to the provided URI, with some query parameters including the code in case of success, or an error if something went wrong + * + * Warning: The redirect URI has to be whitelisted in the account server ! + * + * @param _redirect The redirect URI where the user should be driven after authorization + * @return The HttpUrl where the user should go to access the authorization form + */ public HttpUrl buildAuthorizationURL(URI _redirect) { return new HttpUrl.Builder() .host(accountServer.getHost()) @@ -83,6 +107,12 @@ public HttpUrl buildAuthorizationURL(URI _redirect) { .build(); } + /** + * Request a token from an authorization-code after successfull authorization + * + * @param _authorizationCode the authorization-code generated by the account server + * @return the AsyncRenewableJsonWebToken as an Observable stream + */ public Observable getToken(String _authorizationCode) { return Observable .create((Subscriber t) -> { @@ -114,6 +144,14 @@ public Observable getToken(String _authorizationCode .map((TokenResponse t) -> new AsyncRenewableJsonWebToken(t.accessToken, System.currentTimeMillis() + 1000 * t.expiresIn, t.refreshToken, this)); } + /** + * Request a refresh for the provided token. + * + * This in internally used and should not be used by users + * + * @param _token The Token to be refreshed + * @return the AsyncRenewableJsonWebToken as an Observable stream. The returned one is actually the updated provided one + */ public Observable refreshToken(AsyncRenewableJsonWebToken _token) { return Observable .create((Subscriber t) -> { @@ -147,9 +185,9 @@ public Observable refreshToken(AsyncRenewableJsonWeb private class TokenRequest { - private String clientId = AsyncAuthorizationCode.this.clientId; - private String grantType = "authorization_code"; - private String code; + private final String clientId = AsyncAuthorizationCode.this.clientId; + private final String grantType = "authorization_code"; + private final String code; private TokenRequest(String _code) { code = _code; @@ -167,9 +205,9 @@ private static class TokenResponse { private class RefreshRequest { - private String clientId = AsyncAuthorizationCode.this.clientId; - private String grantType = "refresh_token"; - private String refresh_token; + private final String clientId = AsyncAuthorizationCode.this.clientId; + private final String grantType = "refresh_token"; + private final String refresh_token; private RefreshRequest(String _refresh_token) { refresh_token = _refresh_token; diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java index 451a5a1..dc9a080 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java @@ -71,7 +71,7 @@ public Observable refresh() { return provider.refreshToken(this); } - public Observable restrict(List _claims) { + public Observable restrict(List _claims) { AsyncRenewableJsonWebToken that = this; return Observable .create((Subscriber t) -> { @@ -115,7 +115,7 @@ public Observable refresh() { }); } - public Observable restrict(String... _claims) { + public Observable restrict(String... _claims) { return restrict(Arrays.asList(_claims)); } diff --git a/account/src/main/java/org/thethingsnetwork/account/auth/grant/GrantType.java b/account/src/main/java/org/thethingsnetwork/account/auth/grant/GrantType.java index 62496de..f47a802 100644 --- a/account/src/main/java/org/thethingsnetwork/account/auth/grant/GrantType.java +++ b/account/src/main/java/org/thethingsnetwork/account/auth/grant/GrantType.java @@ -42,6 +42,10 @@ public abstract class GrantType { } } + /** + * Get the account server used by this token provider + * @return The account server URI + */ public abstract URI getAccountServer(); } diff --git a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java index e68d4f6..85f8eb9 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java @@ -24,14 +24,13 @@ package org.thethingsnetwork.account.common; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; /** * * @author Romain Cambier */ @JsonIgnoreProperties(ignoreUnknown = true) -public interface AbstractApplication { +public interface AbstractApplication { /** * Get the application ID @@ -64,6 +63,6 @@ public interface AbstractApplication { * Update the AsyncOAuth2Token to be used by this application wrapper * @param _creds the new AsyncOAuth2Token to be used */ - public void updateCredentials(AsyncOAuth2Token _creds); + public void updateCredentials(R _creds); } diff --git a/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java index 4a10a3a..b79b260 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java @@ -36,13 +36,13 @@ public class AccessKey { private String name; private String key; - private List rights; + private List rights; public AccessKey() { } - public AccessKey(String _name, List _rights) { + public AccessKey(String _name, List _rights) { name = _name; rights = _rights; } @@ -55,7 +55,7 @@ public String getKey() { return key; } - public List getRights() { + public List getRights() { return Collections.unmodifiableList(rights); } } diff --git a/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java b/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java new file mode 100644 index 0000000..dd96257 --- /dev/null +++ b/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java @@ -0,0 +1,53 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.account.common; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * + * @author Romain Cambier + */ +public enum ApplicationRights { + + SETTINGS("settings"), + DELETE("delete"), + COLLABORATORS("collaborators"), + MESSAGE_UP_R("messages:up:r"), + MESSAGE_UP_W("messages:up:w"), + MESSAGE_DOWN_W("messages:down:w"), + DEVICES("devices"); + + private final String serialized; + + private ApplicationRights(String _serialized) { + serialized = _serialized; + } + + @JsonValue + public String toJson() { + return serialized; + } + +} diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java index 141699f..e45c540 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java @@ -28,13 +28,15 @@ import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; import org.thethingsnetwork.account.common.AbstractApplication; import org.thethingsnetwork.account.common.AccessKey; +import org.thethingsnetwork.account.common.ApplicationRights; import org.thethingsnetwork.account.common.Collaborator; +import org.thethingsnetwork.account.sync.auth.token.OAuth2Token; /** * * @author Romain Cambier */ -public class Application implements AbstractApplication { +public class Application implements AbstractApplication { private final AsyncApplication wrapped; @@ -46,16 +48,16 @@ private Application(AsyncApplication _wrap) { wrapped = _wrap; } - public static List findAll(AsyncOAuth2Token _creds) { - return AsyncApplication.findAll(_creds) + public static List findAll(OAuth2Token _creds) { + return AsyncApplication.findAll(_creds.async()) .map((AsyncApplication t) -> new Application(t)) .toList() .toBlocking() .single(); } - public static Application create(AsyncOAuth2Token _creds, AbstractApplication _app) { - return AsyncApplication.create(_creds, _app) + public static Application create(OAuth2Token _creds, AbstractApplication _app) { + return AsyncApplication.create(_creds.async(), _app) .map((AsyncApplication t) -> new Application(t)) .toBlocking() .single(); @@ -169,14 +171,14 @@ public Application refresh() { .single(); } - public List getRights() { + public List getRights() { return wrapped.getRights() .toList() .toBlocking() .single(); } - public List getRights(AsyncOAuth2Token _creds) { + public List getRights(AsyncOAuth2Token _creds) { return wrapped.getRights(_creds) .toList() .toBlocking() @@ -204,8 +206,8 @@ public void setName(String _name) { } @Override - public void updateCredentials(AsyncOAuth2Token _creds) { - wrapped.updateCredentials(_creds); + public void updateCredentials(OAuth2Token _creds) { + wrapped.updateCredentials(_creds.async()); } } diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java index bec557d..6a94fa5 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java @@ -26,7 +26,6 @@ import java.net.URI; import java.util.Arrays; import java.util.List; -import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; /** @@ -75,14 +74,14 @@ public URI getAccountServer() { return wrapped.getAccountServer(); } - public JsonWebToken restrict(List _claims) { + public RenewableJsonWebToken restrict(List _claims) { return wrapped.restrict(_claims) - .map((AsyncJsonWebToken t) -> new JsonWebToken(t)) + .map((AsyncRenewableJsonWebToken t) -> new RenewableJsonWebToken(t)) .toBlocking() .single(); } - public JsonWebToken restrict(String... _claims) { + public RenewableJsonWebToken restrict(String... _claims) { return restrict(Arrays.asList(_claims)); } diff --git a/pom.xml b/pom.xml index 623378b..27626e1 100644 --- a/pom.xml +++ b/pom.xml @@ -7,9 +7,9 @@ pom - account data management + account The Things Network Java SDK diff --git a/samples/pom.xml b/samples/pom.xml index 2b1c775..994ad2c 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -9,7 +9,8 @@ The Things Network SDK Samples The Things Network SDK Samples - mqtt + samples-mqtt + samples-account UTF-8 diff --git a/samples/samples-account/pom.xml b/samples/samples-account/pom.xml new file mode 100644 index 0000000..d0756ec --- /dev/null +++ b/samples/samples-account/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + org.thethingsnetwork + samples + 2.1.0 + + samples-account + jar + + The Things Network Account Sample + The Things Network Account Sample + + + ${project.groupId} + account + ${project.version} + + + + UTF-8 + 1.8 + 1.8 + + \ No newline at end of file diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java new file mode 100644 index 0000000..6614659 --- /dev/null +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java @@ -0,0 +1,67 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.account; + +import java.net.URI; +import org.thethingsnetwork.account.util.HttpRequest; + +/** + * + * @author Romain Cambier + */ +public class App { + + public static void main(String[] args) throws Exception { + Config cfg = new Config(); + cfg.cliendId = System.getenv("cliendId"); + cfg.clientSecret = System.getenv("clientSecret"); + cfg.redirect = (System.getenv("redirect") == null) ? null : new URI(System.getenv("redirect")); + cfg.applicationId = System.getenv("applicationId"); + cfg.applicationKey = System.getenv("applicationKey"); + + System.out.println("Starting AuthorizationCodeAsync"); + AuthorizationCodeAsync.run(cfg); + System.out.println("Starting AuthorizationCodeSync"); + AuthorizationCodeSync.run(cfg); + System.out.println("Starting ApplicationPasswordAsync"); + //ApplicationPasswordAsync.run(cfg); + System.out.println("Starting ApplicationPasswordSync"); + //ApplicationPasswordSync.run(cfg); + + HttpRequest.shutdown(); + + } + + public static class Config { + + public String cliendId; + public String clientSecret; + //for authorization code + public URI redirect; + //for app password + public String applicationId; + public String applicationKey; + + } +} diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java new file mode 100644 index 0000000..fd4398e --- /dev/null +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java @@ -0,0 +1,156 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.account; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.concurrent.CountDownLatch; +import org.thethingsnetwork.account.async.AsyncApplication; +import org.thethingsnetwork.account.async.auth.grant.AsyncAuthorizationCode; +import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; +import org.thethingsnetwork.account.common.Collaborator; +import rx.Observable; +import rx.functions.Action0; +import rx.functions.Action1; +import rx.functions.Func1; + +/** + * + * @author Romain Cambier + */ +public class AuthorizationCodeAsync { + + public static void run(App.Config _conf) throws Exception { + + if (_conf.cliendId == null) { + throw new NullPointerException("missing cliendId"); + } + + if (_conf.clientSecret == null) { + throw new NullPointerException("missing clientSecret"); + } + + if (_conf.redirect == null) { + throw new NullPointerException("missing redirect"); + } + + AsyncAuthorizationCode tokenProvider = new AsyncAuthorizationCode(_conf.cliendId, _conf.clientSecret); + + String redirect = tokenProvider.buildAuthorizationURL(_conf.redirect).toString(); + + System.out.println("here is the authorization url: " + redirect); + System.out.print("Enter code: "); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String code = br.readLine(); + + if (code == null || code.equals("")) { + throw new IllegalArgumentException("invalid code"); + } + + /** + * I won't use lambdas just so that everybody can ready this code ! + */ + CountDownLatch cdl = new CountDownLatch(1); + tokenProvider + .getToken(code) + .flatMap(new Func1>() { + @Override + public Observable call(AsyncRenewableJsonWebToken token) { + return AsyncApplication + .findAll(token) + .flatMap(new Func1>() { + @Override + public Observable call(AsyncApplication application) { + return token + .restrict("apps:" + application.getId()) + .doOnNext(new Action1() { + @Override + public void call(AsyncRenewableJsonWebToken restrictedToken) { + application.updateCredentials(restrictedToken); + } + }) + .flatMap(new Func1>() { + @Override + public Observable call(AsyncRenewableJsonWebToken restrictedToken) { + return application.getCollaborators(); + } + }) + .count() + .map(new Func1() { + @Override + public String call(Integer collabCount) { + return "\tapplication " + application.getName() + " has " + collabCount + " collaborators"; + } + }); + } + }); + } + }) + .doOnNext(new Action1() { + @Override + public void call(String t) { + System.out.println(t); + } + }) + .doOnCompleted(new Action0() { + @Override + public void call() { + cdl.countDown(); + } + }) + .doOnError(new Action1() { + @Override + public void call(Throwable t) { + t.printStackTrace(); + } + }) + .subscribe(); + /** + * this is to prevent exiting the run() before the async code complete. + * In a real async flow, you don't block stuff ! + */ + cdl.await(); + + /** + * Just so that you know how lambdas looks: + */ + tokenProvider + .getToken(code) + .flatMap((AsyncRenewableJsonWebToken token) -> AsyncApplication + .findAll(token) + .flatMap((AsyncApplication application) -> token + .restrict("apps:" + application.getId()) + .doOnNext(application::updateCredentials) + .flatMap((ignore) -> application.getCollaborators()) + .count() + .map((Integer collabCount) -> "\tapplication " + application.getName() + " has " + collabCount + " collaborators") + ) + ) + .doOnNext(System.out::println) + .doOnCompleted(cdl::countDown) + .doOnError(Throwable::printStackTrace); //I removed the subscribe() to avoid running the code twice + + } + +} diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java new file mode 100644 index 0000000..6c4286f --- /dev/null +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java @@ -0,0 +1,83 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.account; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.List; +import org.thethingsnetwork.account.common.Collaborator; +import org.thethingsnetwork.account.sync.Application; +import org.thethingsnetwork.account.sync.auth.grant.AuthorizationCode; +import org.thethingsnetwork.account.sync.auth.token.RenewableJsonWebToken; + +/** + * + * @author Romain Cambier + */ +public class AuthorizationCodeSync { + + public static void run(App.Config _conf) throws Exception { + if (_conf.cliendId == null) { + throw new NullPointerException("missing cliendId"); + } + + if (_conf.clientSecret == null) { + throw new NullPointerException("missing clientSecret"); + } + + if (_conf.redirect == null) { + throw new NullPointerException("missing redirect"); + } + + AuthorizationCode tokenProvider = new AuthorizationCode(_conf.cliendId, _conf.clientSecret); + + String redirect = tokenProvider.buildAuthorizationURL(_conf.redirect).toString(); + + System.out.println("here is the authorization url: " + redirect); + System.out.print("Enter code: "); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String code = br.readLine(); + + if (code == null || code.equals("")) { + throw new IllegalArgumentException("invalid code"); + } + + RenewableJsonWebToken token = tokenProvider.getToken(code); + + List apps = Application.findAll(token); + + for (Application app : apps) { + + RenewableJsonWebToken restrictedToken = token.restrict("apps:" + app.getId()); + + app.updateCredentials(restrictedToken); + + List collaborators = app.getCollaborators(); + + System.out.println("\tapplication " + app.getName() + " has " + collaborators.size() + " collaborators"); + + } + } + +} diff --git a/samples/mqtt/pom.xml b/samples/samples-mqtt/pom.xml similarity index 100% rename from samples/mqtt/pom.xml rename to samples/samples-mqtt/pom.xml diff --git a/samples/mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java b/samples/samples-mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java similarity index 100% rename from samples/mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java rename to samples/samples-mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java From 1854e55c43a56682e2b110dbfee17bcc634d5d79 Mon Sep 17 00:00:00 2001 From: cambierr Date: Fri, 23 Dec 2016 12:37:32 +0100 Subject: [PATCH 14/24] fixed bugs on endpoint methods (account) samples for account are ready --- .../account/async/AsyncApplication.java | 2 +- .../account/sync/Application.java | 9 +- .../account/util/HttpRequest.java | 19 ++- .../thethingsnetwork/samples/account/App.java | 4 +- .../account/ApplicationPasswordAsync.java | 129 ++++++++++++++++++ .../account/ApplicationPasswordSync.java | 66 +++++++++ .../account/AuthorizationCodeAsync.java | 16 +-- .../account/AuthorizationCodeSync.java | 6 +- 8 files changed, 230 insertions(+), 21 deletions(-) create mode 100644 samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java create mode 100644 samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java diff --git a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java index 6cd7a2a..a4d30dd 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java @@ -318,7 +318,7 @@ public Observable addCollaborator(Collaborator _collaborator) .flatMap((HttpRequest t) -> HttpRequest .buildRequestBody(_collaborator) .map((RequestBody rb) -> { - t.getBuilder().post(rb); + t.getBuilder().put(rb); return t; }) ) diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java index e45c540..f84c87b 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java @@ -25,7 +25,6 @@ import java.util.List; import org.thethingsnetwork.account.async.AsyncApplication; -import org.thethingsnetwork.account.async.auth.token.AsyncOAuth2Token; import org.thethingsnetwork.account.common.AbstractApplication; import org.thethingsnetwork.account.common.AccessKey; import org.thethingsnetwork.account.common.ApplicationRights; @@ -63,8 +62,8 @@ public static Application create(OAuth2Token _creds, AbstractApplication _app) { .single(); } - public static Application findOne(AsyncOAuth2Token _creds, String _id) { - return AsyncApplication.findOne(_creds, _id) + public static Application findOne(OAuth2Token _creds, String _id) { + return AsyncApplication.findOne(_creds.async(), _id) .map((AsyncApplication t) -> new Application(t)) .toBlocking() .singleOrDefault(null); @@ -178,8 +177,8 @@ public List getRights() { .single(); } - public List getRights(AsyncOAuth2Token _creds) { - return wrapped.getRights(_creds) + public List getRights(OAuth2Token _creds) { + return wrapped.getRights(_creds.async()) .toList() .toBlocking() .single(); diff --git a/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java index 1ebabb7..fe9e0b8 100644 --- a/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java +++ b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java @@ -154,6 +154,21 @@ public Observable doExecute() { client.newCall(r).enqueue(new SubscriberCallback(t)); }) .subscribeOn(Schedulers.io()) + ) + .flatMap((Response r) -> Observable + .create((Subscriber t) -> { + try { + if (!r.isSuccessful()) { + t.onError(new HttpException(r.code(), r.message(), new String(r.body().bytes()))); + return; + } + t.onNext(r); + t.onCompleted(); + } catch (IOException ex) { + t.onError(ex); + } + }) + .subscribeOn(Schedulers.io()) ); } @@ -195,8 +210,8 @@ public Observable doExecuteForType(Class _type) { ); } - - public static void shutdown(){ + + public static void shutdown() { client.dispatcher().executorService().shutdown(); } diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java index 6614659..d9a0333 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java @@ -45,9 +45,9 @@ public static void main(String[] args) throws Exception { System.out.println("Starting AuthorizationCodeSync"); AuthorizationCodeSync.run(cfg); System.out.println("Starting ApplicationPasswordAsync"); - //ApplicationPasswordAsync.run(cfg); + ApplicationPasswordAsync.run(cfg); System.out.println("Starting ApplicationPasswordSync"); - //ApplicationPasswordSync.run(cfg); + ApplicationPasswordSync.run(cfg); HttpRequest.shutdown(); diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java new file mode 100644 index 0000000..52329fd --- /dev/null +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java @@ -0,0 +1,129 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.account; + +import java.util.concurrent.CountDownLatch; +import org.thethingsnetwork.account.async.AsyncApplication; +import org.thethingsnetwork.account.async.auth.grant.AsyncApplicationPassword; +import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; +import org.thethingsnetwork.samples.account.App.Config; +import rx.Observable; +import rx.functions.Action0; +import rx.functions.Action1; +import rx.functions.Func1; + +/** + * + * @author Romain Cambier + */ +public class ApplicationPasswordAsync { + + public static void run(Config _conf) throws Exception { + if (_conf.cliendId == null) { + throw new NullPointerException("missing cliendId"); + } + + if (_conf.clientSecret == null) { + throw new NullPointerException("missing clientSecret"); + } + + if (_conf.applicationId == null) { + throw new NullPointerException("missing applicationId"); + } + + if (_conf.applicationKey == null) { + throw new NullPointerException("missing applicationKey"); + } + + AsyncApplicationPassword tokenProvider = new AsyncApplicationPassword(_conf.applicationId, _conf.applicationKey, _conf.cliendId, _conf.clientSecret); + + /** + * I won't use lambdas just so that everybody can ready this code ! + */ + CountDownLatch cdl = new CountDownLatch(1); + tokenProvider + .getToken() + .flatMap(new Func1>() { + @Override + public Observable call(AsyncJsonWebToken t) { + return AsyncApplication.findOne(t, _conf.applicationId); + } + }) + .flatMap(new Func1>() { + @Override + public Observable call(AsyncApplication app) { + return app + .getAccessKeys() + .count() + .map(new Func1() { + @Override + public String call(Integer count) { + return "\tapplication " + app.getName() + " has " + count + " keys"; + } + }); + } + }) + .doOnNext(new Action1() { + @Override + public void call(String t) { + System.out.println(t); + } + }) + .doOnCompleted(new Action0() { + @Override + public void call() { + cdl.countDown(); + } + }) + .doOnError(new Action1() { + @Override + public void call(Throwable t) { + t.printStackTrace(); + } + }) + .subscribe(); + /** + * this is to prevent exiting the run() before the async code complete. + * In a real async flow, you don't block stuff ! + */ + cdl.await(); + + /** + * Just so that you know how lambdas looks: + */ + tokenProvider + .getToken() + .flatMap((AsyncJsonWebToken t) -> AsyncApplication.findOne(t, _conf.applicationId)) + .flatMap((AsyncApplication app) -> app + .getAccessKeys() + .count() + .map((Integer count) -> "\tapplication " + app.getName() + " has " + count + " keys") + ) + .doOnNext(System.out::println) + .doOnCompleted(cdl::countDown) + .doOnError(Throwable::printStackTrace); //I removed the subscribe() to avoid running the code twice + + } + +} diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java new file mode 100644 index 0000000..83efc6f --- /dev/null +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java @@ -0,0 +1,66 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.account; + +import java.util.List; +import org.thethingsnetwork.account.common.AccessKey; +import org.thethingsnetwork.account.sync.Application; +import org.thethingsnetwork.account.sync.auth.grant.ApplicationPassword; +import org.thethingsnetwork.account.sync.auth.token.JsonWebToken; + +/** + * + * @author Romain Cambier + */ +public class ApplicationPasswordSync { + + public static void run(App.Config _conf) { + if (_conf.cliendId == null) { + throw new NullPointerException("missing cliendId"); + } + + if (_conf.clientSecret == null) { + throw new NullPointerException("missing clientSecret"); + } + + if (_conf.applicationId == null) { + throw new NullPointerException("missing applicationId"); + } + + if (_conf.applicationKey == null) { + throw new NullPointerException("missing applicationKey"); + } + + ApplicationPassword tokenProvider = new ApplicationPassword(_conf.applicationId, _conf.applicationKey, _conf.cliendId, _conf.clientSecret); + + JsonWebToken token = tokenProvider.getToken(); + + Application app = Application.findOne(token, _conf.applicationId); + + List accessKeys = app.getAccessKeys(); + + System.out.println("\tapplication " + app.getName() + " has " + accessKeys.size() + " keys"); + } + +} diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java index fd4398e..6f461bd 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java @@ -29,7 +29,7 @@ import org.thethingsnetwork.account.async.AsyncApplication; import org.thethingsnetwork.account.async.auth.grant.AsyncAuthorizationCode; import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; -import org.thethingsnetwork.account.common.Collaborator; +import org.thethingsnetwork.account.common.AccessKey; import rx.Observable; import rx.functions.Action0; import rx.functions.Action1; @@ -90,17 +90,17 @@ public void call(AsyncRenewableJsonWebToken restrictedToken) { application.updateCredentials(restrictedToken); } }) - .flatMap(new Func1>() { + .flatMap(new Func1>() { @Override - public Observable call(AsyncRenewableJsonWebToken restrictedToken) { - return application.getCollaborators(); + public Observable call(AsyncRenewableJsonWebToken restrictedToken) { + return application.getAccessKeys(); } }) .count() .map(new Func1() { @Override - public String call(Integer collabCount) { - return "\tapplication " + application.getName() + " has " + collabCount + " collaborators"; + public String call(Integer accessKeysCount) { + return "\tapplication " + application.getName() + " has " + accessKeysCount + " keys"; } }); } @@ -142,9 +142,9 @@ public void call(Throwable t) { .flatMap((AsyncApplication application) -> token .restrict("apps:" + application.getId()) .doOnNext(application::updateCredentials) - .flatMap((ignore) -> application.getCollaborators()) + .flatMap((ignore) -> application.getAccessKeys()) .count() - .map((Integer collabCount) -> "\tapplication " + application.getName() + " has " + collabCount + " collaborators") + .map((Integer accessKeysCount) -> "\tapplication " + application.getName() + " has " + accessKeysCount + " keys") ) ) .doOnNext(System.out::println) diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java index 6c4286f..adaa378 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java @@ -26,7 +26,7 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.List; -import org.thethingsnetwork.account.common.Collaborator; +import org.thethingsnetwork.account.common.AccessKey; import org.thethingsnetwork.account.sync.Application; import org.thethingsnetwork.account.sync.auth.grant.AuthorizationCode; import org.thethingsnetwork.account.sync.auth.token.RenewableJsonWebToken; @@ -73,9 +73,9 @@ public static void run(App.Config _conf) throws Exception { app.updateCredentials(restrictedToken); - List collaborators = app.getCollaborators(); + List accessKeys = app.getAccessKeys(); - System.out.println("\tapplication " + app.getName() + " has " + collaborators.size() + " collaborators"); + System.out.println("\tapplication " + app.getName() + " has " + accessKeys.size() + " keys"); } } From 4cf3a306a26ff95bc21724500ad1d91deb7df6cb Mon Sep 17 00:00:00 2001 From: cambierr Date: Fri, 23 Dec 2016 12:40:27 +0100 Subject: [PATCH 15/24] added data-amqp sample --- samples/pom.xml | 1 + samples/samples-amqp/pom.xml | 26 ++++++ .../thethingsnetwork/samples/amqp/App.java | 84 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 samples/samples-amqp/pom.xml create mode 100644 samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java diff --git a/samples/pom.xml b/samples/pom.xml index 994ad2c..cfd0997 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -11,6 +11,7 @@ samples-mqtt samples-account + samples-amqp UTF-8 diff --git a/samples/samples-amqp/pom.xml b/samples/samples-amqp/pom.xml new file mode 100644 index 0000000..84ea2d7 --- /dev/null +++ b/samples/samples-amqp/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + org.thethingsnetwork + samples + 2.1.0 + + samples-amqp + jar + + The Things Network AMQP Sample + The Things Network AMQP Sample + + + ${project.groupId} + data-amqp + ${project.version} + + + + UTF-8 + 1.8 + 1.8 + + \ No newline at end of file diff --git a/samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java b/samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java new file mode 100644 index 0000000..3ec9d59 --- /dev/null +++ b/samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java @@ -0,0 +1,84 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.mqtt; + +import org.thethingsnetwork.data.amqp.Client; +import org.thethingsnetwork.data.common.Connection; +import org.thethingsnetwork.data.common.messages.ActivationMessage; +import org.thethingsnetwork.data.common.messages.DataMessage; +import org.thethingsnetwork.data.common.messages.DownlinkMessage; +import org.thethingsnetwork.data.common.messages.RawMessage; +import org.thethingsnetwork.data.common.messages.UplinkMessage; + +/** + * + * @author Romain Cambier + */ +public class App { + + public static void main(String[] args) throws Exception { + String region = System.getenv("region"); + String appId = System.getenv("appId"); + String accessKey = System.getenv("accessKey"); + + Client client = new Client(region, appId, accessKey); + + class Response { + + private boolean led; + + public Response(boolean _led) { + led = _led; + } + } + + client.onMessage(null, "led", (String _devId, DataMessage _data) -> { + try { + RawMessage message = (RawMessage) _data; + // Toggle the LED + DownlinkMessage response = new DownlinkMessage(0, new Response(!message.asBoolean())); + + /** + * If you don't have an encoder payload function: + * client.send(_devId, new Response(0, message.asBoolean() ? new byte[]{0x00} : new byte[]{0x01})); + */ + System.out.println("Sending: " + response); + client.send(_devId, response); + } catch (Exception ex) { + System.out.println("Response failed: " + ex.getMessage()); + } + }); + + client.onMessage((String devId, DataMessage data) -> System.out.println("Message: " + devId + " " + ((UplinkMessage) data).getCounter())); + + client.onActivation((String _devId, ActivationMessage _data) -> System.out.println("Activation: " + _devId + ", data: " + _data.getDevAddr())); + + client.onError((Throwable _error) -> System.err.println("error: " + _error.getMessage())); + + client.onConnected((Connection _client) -> System.out.println("connected !")); + + client.start(); + } + +} From a5917ffdcd804ffaf66d2d7d7363db80d027ff0b Mon Sep 17 00:00:00 2001 From: cambierr Date: Fri, 23 Dec 2016 12:45:14 +0100 Subject: [PATCH 16/24] readme updates --- README.md | 6 +++--- samples/README.md | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3ec399b..90f2994 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ This is the Java SDK for [The Things Network](https://www.thethingsnetwork.org) ## Modules -- **[WIP]** [Account](account) - Interact with The Things Network account server -- **[WIP]** [Management](management) - Interact with The Things Network Handler via the API -- **[WIP]** [Data AMQP](data/amqp) - Subscribe to Things Network Handler to send/receive data via AMQP +- [Account](account) - Interact with The Things Network account server +- [Management](management) - Interact with The Things Network Handler via the API +- [Data AMQP](data/amqp) - Subscribe to Things Network Handler to send/receive data via AMQP - [Data MQTT](data/mqtt) - Subscribe to Things Network Handler to send/receive data via MQTT - [Samples](samples) - Samples of how to use previous libraries diff --git a/samples/README.md b/samples/README.md index 2a472d3..9e42625 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1 +1,14 @@ -# The Things Network Java SDK Samples \ No newline at end of file +# The Things Network Java SDK Samples + +Here are some samples codes on how to start with the Java SDK + +## Saples + +- [Account](samples-account) - Interact with The Things Network account server +- [Data AMQP](samples-amqp) - Subscribe to Things Network Handler to send/receive data via AMQP +- [Data MQTT](samples-mqtt) - Subscribe to Things Network Handler to send/receive data via MQTT + +## Documentation + +- [The Things Network Documentation](https://www.thethingsnetwork.org/docs/applications/java/) +- [Javadoc](https://thethingsnetwork.github.io/java-app-sdk/) From 19ad35b3b5fd21ca124bc4d3a7b8b0469d1135a3 Mon Sep 17 00:00:00 2001 From: cambierr Date: Fri, 23 Dec 2016 20:57:50 +0100 Subject: [PATCH 17/24] re-ordered the repo --- .gitignore | 3 ++- .../account/async/auth/grant/AsyncApplicationPassword.java | 2 +- .../account/async/auth/grant/AsyncAuthorizationCode.java | 2 +- .../account/{auth/grant => common}/GrantType.java | 2 +- .../account/sync/auth/grant/ApplicationPassword.java | 2 +- .../account/sync/auth/grant/AuthorizationCode.java | 2 +- data/{amqp => data-amqp}/pom.xml | 0 .../main/java/org/thethingsnetwork/data/amqp/Client.java | 0 data/{common => data-common}/pom.xml | 0 .../org/thethingsnetwork/data/common/AbstractClient.java | 0 .../java/org/thethingsnetwork/data/common/Connection.java | 0 .../java/org/thethingsnetwork/data/common/Metadata.java | 0 .../java/org/thethingsnetwork/data/common/Subscribable.java | 0 .../java/org/thethingsnetwork/data/common/TriConsumer.java | 0 .../data/common/events/AbstractEventHandler.java | 0 .../data/common/events/ActivationHandler.java | 0 .../thethingsnetwork/data/common/events/ConnectHandler.java | 0 .../thethingsnetwork/data/common/events/ErrorHandler.java | 0 .../thethingsnetwork/data/common/events/EventHandler.java | 0 .../thethingsnetwork/data/common/events/UplinkHandler.java | 0 .../data/common/messages/ActivationMessage.java | 0 .../thethingsnetwork/data/common/messages/DataMessage.java | 0 .../data/common/messages/DownlinkMessage.java | 0 .../thethingsnetwork/data/common/messages/RawMessage.java | 0 .../data/common/messages/UplinkMessage.java | 0 data/{mqtt => data-mqtt}/API.md | 0 data/{mqtt => data-mqtt}/README.md | 0 data/{mqtt => data-mqtt}/pom.xml | 0 .../main/java/org/thethingsnetwork/data/mqtt/Client.java | 0 data/pom.xml | 6 +++--- 30 files changed, 10 insertions(+), 9 deletions(-) rename account/src/main/java/org/thethingsnetwork/account/{auth/grant => common}/GrantType.java (97%) rename data/{amqp => data-amqp}/pom.xml (100%) rename data/{amqp => data-amqp}/src/main/java/org/thethingsnetwork/data/amqp/Client.java (100%) rename data/{common => data-common}/pom.xml (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/Connection.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/Metadata.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/Subscribable.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java (100%) rename data/{common => data-common}/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java (100%) rename data/{mqtt => data-mqtt}/API.md (100%) rename data/{mqtt => data-mqtt}/README.md (100%) rename data/{mqtt => data-mqtt}/pom.xml (100%) rename data/{mqtt => data-mqtt}/src/main/java/org/thethingsnetwork/data/mqtt/Client.java (100%) diff --git a/.gitignore b/.gitignore index d4e796d..32a8ef0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ /.license /management/src/main/proto/ /samples/account/target/ -/samples/samples-account/target/ \ No newline at end of file +/samples/samples-account/target/ +/data/data-common/target/ \ No newline at end of file diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java index 8b9aeca..b205bbb 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java @@ -28,7 +28,7 @@ import okhttp3.HttpUrl; import okhttp3.RequestBody; import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; -import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.common.GrantType; import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; import rx.Subscriber; diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java index 94425bc..8d7d222 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java @@ -28,7 +28,7 @@ import okhttp3.HttpUrl; import okhttp3.RequestBody; import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; -import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.common.GrantType; import org.thethingsnetwork.account.util.HttpRequest; import rx.Observable; import rx.Subscriber; diff --git a/account/src/main/java/org/thethingsnetwork/account/auth/grant/GrantType.java b/account/src/main/java/org/thethingsnetwork/account/common/GrantType.java similarity index 97% rename from account/src/main/java/org/thethingsnetwork/account/auth/grant/GrantType.java rename to account/src/main/java/org/thethingsnetwork/account/common/GrantType.java index f47a802..8042c31 100644 --- a/account/src/main/java/org/thethingsnetwork/account/auth/grant/GrantType.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/GrantType.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.thethingsnetwork.account.auth.grant; +package org.thethingsnetwork.account.common; import java.net.URI; import java.net.URISyntaxException; diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java index 38c4760..9fab26b 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java @@ -26,7 +26,7 @@ import java.net.URI; import org.thethingsnetwork.account.async.auth.grant.AsyncApplicationPassword; import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; -import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.common.GrantType; import org.thethingsnetwork.account.sync.auth.token.JsonWebToken; /** diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java index 4cb0e40..4b506bf 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java @@ -27,7 +27,7 @@ import okhttp3.HttpUrl; import org.thethingsnetwork.account.async.auth.grant.AsyncAuthorizationCode; import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; -import org.thethingsnetwork.account.auth.grant.GrantType; +import org.thethingsnetwork.account.common.GrantType; import org.thethingsnetwork.account.sync.auth.token.RenewableJsonWebToken; /** diff --git a/data/amqp/pom.xml b/data/data-amqp/pom.xml similarity index 100% rename from data/amqp/pom.xml rename to data/data-amqp/pom.xml diff --git a/data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java b/data/data-amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java similarity index 100% rename from data/amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java rename to data/data-amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java diff --git a/data/common/pom.xml b/data/data-common/pom.xml similarity index 100% rename from data/common/pom.xml rename to data/data-common/pom.xml diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/Connection.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/Connection.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/Metadata.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/Metadata.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java diff --git a/data/common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java similarity index 100% rename from data/common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java rename to data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java diff --git a/data/mqtt/API.md b/data/data-mqtt/API.md similarity index 100% rename from data/mqtt/API.md rename to data/data-mqtt/API.md diff --git a/data/mqtt/README.md b/data/data-mqtt/README.md similarity index 100% rename from data/mqtt/README.md rename to data/data-mqtt/README.md diff --git a/data/mqtt/pom.xml b/data/data-mqtt/pom.xml similarity index 100% rename from data/mqtt/pom.xml rename to data/data-mqtt/pom.xml diff --git a/data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java b/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java similarity index 100% rename from data/mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java rename to data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java diff --git a/data/pom.xml b/data/pom.xml index f226ed0..8eb5b9b 100644 --- a/data/pom.xml +++ b/data/pom.xml @@ -10,9 +10,9 @@ pom - mqtt - amqp - common + data-mqtt + data-amqp + data-common The Things Network Data SDK From 5d20225ad38c781b3e926006e62c9926f1d9208e Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 9 Jan 2017 11:17:36 +0100 Subject: [PATCH 18/24] added management sample --- .gitignore | 4 +- samples/pom.xml | 1 + samples/samples-management/pom.xml | 26 ++++++ .../samples/management/App.java | 74 +++++++++++++++ .../samples/management/ManagementAsync.java | 92 +++++++++++++++++++ .../samples/management/ManagementSync.java | 83 +++++++++++++++++ 6 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 samples/samples-management/pom.xml create mode 100644 samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java create mode 100644 samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java create mode 100644 samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java diff --git a/.gitignore b/.gitignore index 32a8ef0..12b4571 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,6 @@ /management/src/main/proto/ /samples/account/target/ /samples/samples-account/target/ -/data/data-common/target/ \ No newline at end of file +/data/data-common/target/ +/samples/ttnmgmt/target/ +/samples/samples-management/target/ \ No newline at end of file diff --git a/samples/pom.xml b/samples/pom.xml index cfd0997..6517590 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -12,6 +12,7 @@ samples-mqtt samples-account samples-amqp + samples-management UTF-8 diff --git a/samples/samples-management/pom.xml b/samples/samples-management/pom.xml new file mode 100644 index 0000000..2928aa1 --- /dev/null +++ b/samples/samples-management/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + org.thethingsnetwork + samples + 2.1.0 + + samples-management + jar + + The Things Network Management Sample + The Things Network Management Sample + + + ${project.groupId} + management + ${project.version} + + + + UTF-8 + 1.8 + 1.8 + + \ No newline at end of file diff --git a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java new file mode 100644 index 0000000..7bb7a07 --- /dev/null +++ b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java @@ -0,0 +1,74 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.management; + +import org.thethingsnetwork.account.util.HttpRequest; + +/** + * + * @author Romain Cambier + */ +public class App { + + public static void main(String[] args) throws Exception { + Config cfg = new Config(); + cfg.cliendId = System.getenv("cliendId"); + cfg.clientSecret = System.getenv("clientSecret"); + cfg.handlerId = System.getenv("handlerId"); + cfg.applicationId = System.getenv("applicationId"); + cfg.applicationKey = System.getenv("applicationKey"); + + System.out.println("Starting ManagementAsync"); + ManagementAsync.run(cfg); + System.out.println("Starting ManagementSync"); + ManagementSync.run(cfg); + + HttpRequest.shutdown(); + + } + + public static class Config { + + public String cliendId; + public String clientSecret; + //for app password + public String applicationId; + public String applicationKey; + //for handler choice + public String handlerId; + + private final static char[] hexChars = "0123456789ABCDEF".toCharArray(); + + public String printArray(byte[] _data) { + char[] hexChars = new char[2 * _data.length]; + for (int i = 0; i < _data.length; i++) { + int j = _data[i] & 0xFF; + hexChars[i * 2] = hexChars[j >>> 4]; + hexChars[i * 2 + 1] = hexChars[j & 0x0F]; + } + return new String(hexChars); + } + } + +} diff --git a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java new file mode 100644 index 0000000..b43751c --- /dev/null +++ b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java @@ -0,0 +1,92 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.management; + +import java.util.concurrent.CountDownLatch; +import org.thethingsnetwork.account.async.auth.grant.AsyncApplicationPassword; +import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; +import org.thethingsnetwork.management.HandlerApplication; +import org.thethingsnetwork.management.HandlerDevice; +import org.thethingsnetwork.management.async.AsyncDiscovery; +import org.thethingsnetwork.management.async.AsyncHandler; + +/** + * + * @author Romain Cambier + */ +public class ManagementAsync { + + public static void run(App.Config _conf) throws Exception { + + if (_conf.cliendId == null) { + throw new NullPointerException("missing cliendId"); + } + + if (_conf.clientSecret == null) { + throw new NullPointerException("missing clientSecret"); + } + + if (_conf.applicationId == null) { + throw new NullPointerException("missing applicationId"); + } + + if (_conf.applicationKey == null) { + throw new NullPointerException("missing applicationKey"); + } + + if (_conf.handlerId == null) { + throw new NullPointerException("missing handlerId"); + } + + AsyncApplicationPassword tokenProvider = new AsyncApplicationPassword(_conf.applicationId, _conf.applicationKey, _conf.cliendId, _conf.clientSecret); + + CountDownLatch cdl = new CountDownLatch(1); + + tokenProvider + .getToken() + .flatMap((AsyncJsonWebToken token) -> AsyncDiscovery + .getDefault() + .flatMap((AsyncDiscovery t) -> t.getHandler(token, _conf.handlerId)) + ) + .single() + .flatMap((AsyncHandler handler) -> handler + .getApplication(_conf.applicationId) + .doOnNext((HandlerApplication app) -> { + System.out.println("## HandlerApplication " + app.getAppId() + " has a decoder function being: \n" + app.getDecoder()); + System.out.println("## HandlerApplication " + app.getAppId() + " device list:"); + }) + .flatMap(handler::getDevices) + ) + .doOnNext((HandlerDevice t) -> { + System.out.println("\t HandlerDevice " + t.getDevId() + " has EUI " + _conf.printArray(t.getLorawan().getDevEui())); + }) + .doOnCompleted(cdl::countDown) + .doOnError(Throwable::printStackTrace) + .subscribe(); + + cdl.await(); + + } + +} diff --git a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java new file mode 100644 index 0000000..35cfc8e --- /dev/null +++ b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java @@ -0,0 +1,83 @@ +/* + * The MIT License + * + * Copyright (c) 2016 The Things Network + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.thethingsnetwork.samples.management; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import org.thethingsnetwork.account.sync.auth.grant.ApplicationPassword; +import org.thethingsnetwork.account.sync.auth.token.JsonWebToken; +import org.thethingsnetwork.management.HandlerApplication; +import org.thethingsnetwork.management.HandlerDevice; +import org.thethingsnetwork.management.sync.Discovery; +import org.thethingsnetwork.management.sync.Handler; + +/** + * + * @author Romain Cambier + */ +public class ManagementSync { + + public static void run(App.Config _conf) { + if (_conf.cliendId == null) { + throw new NullPointerException("missing cliendId"); + } + + if (_conf.clientSecret == null) { + throw new NullPointerException("missing clientSecret"); + } + + if (_conf.applicationId == null) { + throw new NullPointerException("missing applicationId"); + } + + if (_conf.applicationKey == null) { + throw new NullPointerException("missing applicationKey"); + } + + if (_conf.handlerId == null) { + throw new NullPointerException("missing handlerId"); + } + + ApplicationPassword tokenProvider = new ApplicationPassword(_conf.applicationId, _conf.applicationKey, _conf.cliendId, _conf.clientSecret); + + CountDownLatch cdl = new CountDownLatch(1); + + JsonWebToken token = tokenProvider.getToken(); + + Discovery discoveryServer = Discovery.getDefault(); + + Handler handler = discoveryServer.getHandler(token, _conf.handlerId); + + HandlerApplication application = handler.getApplication(_conf.applicationId); + + System.out.println("## HandlerApplication " + application.getAppId() + " has a decoder function being: \n" + application.getDecoder()); + System.out.println("## HandlerApplication " + application.getAppId() + " device list:"); + + List devices = handler.getDevices(application); + + for(HandlerDevice device:devices){ + System.out.println("\t HandlerDevice " + device.getDevId() + " has EUI " + _conf.printArray(device.getLorawan().getDevEui())); + } + } +} From df3cbf612c01cd05be7f1294381a00ddcc2d669b Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 9 Jan 2017 11:38:53 +0100 Subject: [PATCH 19/24] added javadoc for data-common --- .../data/common/Connection.java | 4 ++ .../data/common/Metadata.java | 63 +++++++++++++++++++ .../data/common/Subscribable.java | 2 +- .../common/events/AbstractEventHandler.java | 1 + .../data/common/events/ActivationHandler.java | 4 +- .../data/common/events/ConnectHandler.java | 1 + .../data/common/events/ErrorHandler.java | 1 + .../data/common/events/EventHandler.java | 6 +- .../data/common/events/UplinkHandler.java | 1 + .../common/messages/ActivationMessage.java | 30 +++++++-- .../data/common/messages/DataMessage.java | 2 +- .../data/common/messages/DownlinkMessage.java | 25 ++++++++ .../data/common/messages/RawMessage.java | 31 +++++++++ .../data/common/messages/UplinkMessage.java | 23 +++++++ 14 files changed, 182 insertions(+), 12 deletions(-) diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java index 27bcb9b..dcd9d2f 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java @@ -29,6 +29,10 @@ */ public interface Connection { + /** + * Return the underlying Connection Object + * @return the underlying Connection + */ public Object get(); } diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java index 6b80a83..b618534 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java @@ -44,30 +44,64 @@ private Metadata() { } + /** + * Get the RX (uplink) or TX (downlink) time of this packet + * + * @return the time as a String + */ public String getTime() { return time; } + /** + * Get the frequency of this packet + * + * @return the frequency, in MHz + */ public double getFrequency() { return frequency; } + /** + * Get the Modulation of this packet + * + * @return the modulation + */ public String getModulation() { return modulation; } + /** + * Get the data rate of this packet + * + * @return the data rate + */ public String getDataRate() { return dataRate; } + /** + * Get the bit rate of this packet + * + * @return the bit rate + */ public String getBitRate() { return bitRate; } + /** + * Get the coding rate of this packet + * + * @return the coding rate + */ public String getCodingRate() { return codingRate; } + /** + * Get the list of gateways that received this packet + * @return a List of Gateway + */ public List getGateways() { if (gateways == null) { return null; @@ -75,6 +109,7 @@ public List getGateways() { return Collections.unmodifiableList(gateways); } + public static class Gateway { private String id; @@ -89,30 +124,58 @@ private Gateway() { } + /** + * Get the Gateway ID as registered in TheThingsNetwork + * @return the gateway id + */ public String getId() { return id; } + /** + * Get the Gateway internal reception time + * @return the gateway internal reception time + */ public long getTimestamp() { return timestamp; } + /** + * Get the Gateway absolute reception time + * @return the gateway absolute reception time + */ public String getTime() { return time; } + /** + * Get the channel this packet was sent on + * @return the channel this packet was sent on + */ public int getChannel() { return channel; } + /** + * Get the RX rssi of this packet + * @return the RX rssi of this packet + */ public double getRssi() { return rssi; } + /** + * Get the RX snr of this packet + * @return the RX snr of this packet + */ public double getSnr() { return snr; } + /** + * Get the RF chain of this packet + * @return the RF chain of this packet + */ public int getRfChain() { return rfChain; } diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java index 38065db..3be01cc 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java @@ -24,7 +24,7 @@ package org.thethingsnetwork.data.common; /** - * + * @internal * @author Romain Cambier */ public interface Subscribable { diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java index 5bb3337..60aaff0 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java @@ -27,6 +27,7 @@ import org.thethingsnetwork.data.common.messages.RawMessage; /** + * Handler protoype for raw device events * * @author Romain Cambier */ diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java index 45ce1f0..f2c4ce0 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java @@ -23,11 +23,11 @@ */ package org.thethingsnetwork.data.common.events; -import org.thethingsnetwork.data.common.messages.ActivationMessage; import org.thethingsnetwork.data.common.Subscribable; +import org.thethingsnetwork.data.common.messages.ActivationMessage; /** - * + * Handler protoype for device activations * @author Romain Cambier */ public abstract class ActivationHandler implements EventHandler { diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java index 3b56a6a..aa10d5f 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java @@ -27,6 +27,7 @@ import org.thethingsnetwork.data.common.Subscribable; /** + * Handler protoype for dclient connection * * @author Romain Cambier */ diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java index d10d30a..3875ce9 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java @@ -26,6 +26,7 @@ import org.thethingsnetwork.data.common.Subscribable; /** + * Handler protoype for client errors * * @author Romain Cambier */ diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java index 0b54b75..6646f38 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java @@ -26,11 +26,11 @@ import org.thethingsnetwork.data.common.Subscribable; /** - * + * @internal * @author Romain Cambier */ public interface EventHandler { - + public void subscribe(Subscribable _client) throws Exception; - + } diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java index eadf45e..7e301d9 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java @@ -27,6 +27,7 @@ import org.thethingsnetwork.data.common.messages.DataMessage; /** + * Handler protoype for device uplink messages * * @author Romain Cambier */ diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java index 737374d..f4e7fec 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java @@ -26,6 +26,7 @@ import org.thethingsnetwork.data.common.Metadata; /** + * This is a wrapper for activation messages * * @author Romain Cambier */ @@ -35,26 +36,45 @@ public class ActivationMessage { private String devEui; private String devAddr; private Metadata metadata; - - private ActivationMessage(){ - + + private ActivationMessage() { + } + /** + * Get the LoraWan Application EUI + * + * @returnthe LoraWan Application EUI + */ public String getAppEui() { return appEui; } + /** + * Get the LoraWan Device EUI + * + * @return the LoraWan Device EUI + */ public String getDevEui() { return devEui; } + /** + * Get the LoraWan Device address + * + * @return the LoraWan Device address + */ public String getDevAddr() { return devAddr; } + /** + * Get the metadata of this uplink packet + * + * @return the metadata + */ public Metadata getMetadata() { return metadata; } - - + } diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java index 935fc36..26c146a 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java @@ -24,7 +24,7 @@ package org.thethingsnetwork.data.common.messages; /** - * + * Wrapper for any sort of uplink message * @author Romain Cambier */ public interface DataMessage { diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java index 2cc7e14..b88e8de 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java @@ -29,6 +29,7 @@ import java.util.Base64; /** + * Wrapper for a downlink message * * @author Romain Cambier */ @@ -39,16 +40,34 @@ public class DownlinkMessage { private String payloadRaw; private Object payloadFields; + /** + * Constructor for a base64-encoded payload + * + * @param _port the port to be used while encrypting the message + * @param _payload the actual base64 string + */ public DownlinkMessage(int _port, String _payload) { port = _port; payloadRaw = _payload; } + /** + * Constructor for a byte array + * + * @param _port the port to be used while encrypting the message + * @param _payload the actual data + */ public DownlinkMessage(int _port, byte[] _payload) { port = _port; payloadRaw = Base64.getEncoder().encodeToString(_payload); } + /** + * Constructor for a byte buffer + * + * @param _port the port to be used while encrypting the message + * @param _payload the actual data + */ public DownlinkMessage(int _port, ByteBuffer _payload) { port = _port; _payload.rewind(); @@ -57,6 +76,12 @@ public DownlinkMessage(int _port, ByteBuffer _payload) { payloadRaw = Base64.getEncoder().encodeToString(payload); } + /** + * Constructor for any kind of java object that will be json-serialized by jackson + * + * @param _port the port to be used while encrypting the message + * @param _payload the actual object + */ public DownlinkMessage(int _port, Object _payload) { port = _port; payloadFields = _payload; diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java index e9427c1..626b860 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java @@ -27,25 +27,56 @@ import org.thethingsnetwork.data.common.AbstractClient; /** + * Wrapper for a filtered message payload (ex: only one field of the decoded json) * * @author Romain Cambier */ public abstract class RawMessage implements DataMessage { + /** + * Get the payload as a String + * + * @return the payload as a String + */ public abstract String asString(); + /** + * Get the payload as an Integer + * + * @return the payload as an Integer + */ public int asInt() { return Integer.parseInt(asString()); } + /** + * Get the payload as a Double + * + * @return the payload as a Double + */ public double asDouble() { return Double.parseDouble(asString()); } + /** + * Get the payload as a Boolean + * + * @return the payload as a Boolean + */ public boolean asBoolean() { return Boolean.parseBoolean(asString()); } + /** + * Get the payload as a custom Object + * The custom object can be a default one as Boolean, Integer, Double, or String. + * In case it's something different, jackson will be used to parse the payload + * + * @param a Boolean, Integer, Double, String, or the custom user-provided class + * @param _class the type of object to deserialize the payload to. + * @return the payload as a custom Object + * @throws java.io.IOException in case the deserialization could not be done + */ public T as(Class _class) throws IOException { if (_class == null) { throw new NullPointerException(); diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java index bf22ebe..9ee0528 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java @@ -45,22 +45,45 @@ private UplinkMessage() { } + /** + * Get the encryption port + * + * @return the encryption port + */ public int getPort() { return port; } + /** + * Get the uplink frame counter + * + * @return the uplink frame counter + */ public int getCounter() { return counter; } + /** + * Get the raw payload + * + * @return the raw payload as a byte array + */ public byte[] getPayloadRaw() { return Base64.getDecoder().decode(payloadRaw); } + /** + * Get the payload fields. Only if you have a decoder function + * @return the payload fields as a Map where keys are strings, and values are any json-valid entity + */ public Map getPayloadFields() { return Collections.unmodifiableMap(payloadFields); } + /** + * Get the metadata of this uplink packet + * @return the metadata + */ public Metadata getMetadata() { return metadata; } From b35bf4047d48cd41b8de4a4e7d4a4b105da5fd5c Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 13 Feb 2017 09:34:50 +0100 Subject: [PATCH 20/24] javadoc for management --- .../management/HandlerApplication.java | 58 ++++++- .../management/HandlerDevice.java | 28 ++++ .../management/LorawanDevice.java | 157 ++++++++++++++++++ .../management/async/AsyncDiscovery.java | 44 +++++ .../management/async/AsyncHandler.java | 59 +++++++ .../management/sync/Discovery.java | 27 ++- .../management/sync/Handler.java | 59 +++++++ 7 files changed, 430 insertions(+), 2 deletions(-) diff --git a/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java b/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java index 4d60635..9939a7f 100644 --- a/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java +++ b/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java @@ -28,7 +28,7 @@ import rx.Subscriber; /** - * + * This class is a representation of a The Things Network application * @author Romain Cambier */ public class HandlerApplication { @@ -47,6 +47,12 @@ private HandlerApplication(String _appId, String _decoder, String _converter, St encoder = _encoder; } + /** + * Build a HandlerApplication instance from a grpc representation + * + * @param _proto The grpc representation + * @return An Observable HandlerApplication containing the HandlerApplication instance + */ public static Observable from(HandlerOuterClass.Application _proto) { return Observable @@ -67,6 +73,11 @@ public static Observable from(HandlerOuterClass.Application } + /** + * Convert this HandlerApplication instance to the grpc representation + * + * @return The grpc representation + */ public Observable toProto() { return Observable @@ -88,38 +99,83 @@ public Observable toProto() { } + /** + * Get the application id + * + * @return The application id + */ public String getAppId() { return appId; } + /** + * Get the application decoder function + * + * @return The applicationn decoder function + */ public String getDecoder() { return decoder; } + /** + * Get the application converter function + * + * @return The applicationn converter function + */ public String getConverter() { return converter; } + /** + * Get the application validator function + * + * @return The applicationn validator function + */ public String getValidator() { return validator; } + /** + * Get the application encoder function + * + * @return The applicationn encoder function + */ public String getEncoder() { return encoder; } + /** + * Set the application decoder function + * + * @param _decoder The applicationn decoder function + */ public void setDecoder(String _decoder) { decoder = _decoder; } + /** + * Set the application converter function + * + * @param _converter The converter function + */ public void setConverter(String _converter) { converter = _converter; } + /** + * Set the application validator function + * + * @param _validator The validator function + */ public void setValidator(String _validator) { validator = _validator; } + /** + * Set the application encoder function + * + * @param _encoder The encoder function + */ public void setEncoder(String _encoder) { encoder = _encoder; } diff --git a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java index adcb289..86a968b 100644 --- a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java @@ -29,6 +29,7 @@ import rx.Subscriber; /** + * This class is a representation of a The Things Network device * * @author Romain Cambier */ @@ -38,20 +39,42 @@ public class HandlerDevice { private final String devId; private final LorawanDevice lorawan; + /** + * Build a device from application id, device id, and lorawan data + * + * @param _appId The application id + * @param _devId The device id + * @param _lorawan The LoraWan data + */ public HandlerDevice(String _appId, String _devId, LorawanDevice _lorawan) { appId = _appId; devId = _devId; lorawan = _lorawan; } + /** + * Get the application id + * + * @return The application id + */ public String getAppId() { return appId; } + /** + * Get the device id + * + * @return The device id + */ public String getDevId() { return devId; } + /** + * Get the LoraWan data + * + * @return the LoraWan data + */ public LorawanDevice getLorawan() { return lorawan; } @@ -76,6 +99,11 @@ public static Observable from(HandlerOuterClass.Device _proto) { } + /** + * Convert this device to the grpc representation + * + * @return The grpc representation + */ public Observable toProto() { return lorawan.toProto() diff --git a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java index b2dfae6..4e95020 100644 --- a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java @@ -29,6 +29,7 @@ import rx.Subscriber; /** + * This class is a representation of a The Things Network LoraWan device * * @author Romain Cambier */ @@ -66,6 +67,16 @@ private LorawanDevice(byte[] _appEui, byte[] _devEui, String _appId, String _dev lastSeen = _lastSeen; } + /** + * Create OTAA (over the air activation) LoraWan data + * + * @param _appId The application id + * @param _devId The device id + * @param _appEui The application EUI + * @param _devEui The device EUI + * @param _appKey The application key + * @return The corresponding LoraWan data + */ public static LorawanDevice createOTAA(String _appId, String _devId, byte[] _appEui, byte[] _devEui, byte[] _appKey) { if (_appEui.length != 8) { throw new IllegalArgumentException("appEui should be 8 bytes long"); @@ -79,6 +90,20 @@ public static LorawanDevice createOTAA(String _appId, String _devId, byte[] _app return new LorawanDevice(_appEui, _devEui, _appId, _devId, null, null, null, _appKey, 0, 0, false, true, "otaa", 0); } + /** + * Create ABP (activation by personalization) LoraWan data + * + * @param _appId The application id + * @param _devId The device id + * @param _appEui The application EUI + * @param _devEui The device EUI + * @param _devAddr The device address + * @param _nwkSKey The network session key + * @param _appSKey The application session key + * @param _disableFCntCheck Whether if you want to disable fCnt check or not + * @param _uses32BitFCnt Whether to use 32 bits frame counters or not + * @return The corresponding LoraWan data + */ public static LorawanDevice createABP(String _appId, String _devId, byte[] _appEui, byte[] _devEui, byte[] _devAddr, byte[] _nwkSKey, byte[] _appSKey, boolean _disableFCntCheck, boolean _uses32BitFCnt) { if (_appEui.length != 8) { throw new IllegalArgumentException("appEui should be 8 bytes long"); @@ -98,6 +123,12 @@ public static LorawanDevice createABP(String _appId, String _devId, byte[] _appE return new LorawanDevice(_appEui, _devEui, _appId, _devId, _devAddr, _nwkSKey, _appSKey, null, 0, 0, _disableFCntCheck, _uses32BitFCnt, "abp", 0); } + /** + * Build a LorawanDevice instance from a grpc representation + * + * @param _proto The grpc representation + * @return An Observable LorawanDevice containing the LorawanDevice instance + */ public static Observable from(DeviceOuterClass.Device _proto) { return Observable @@ -126,6 +157,11 @@ public static Observable from(DeviceOuterClass.Device _proto) { }); } + /** + * Convert this device to the grpc representation + * + * @return The grpc representation + */ public Observable toProto() { return Observable @@ -156,10 +192,20 @@ public Observable toProto() { } + /** + * Get the application EUI + * + * @return the application EUI + */ public byte[] getAppEui() { return appEui; } + /** + * Set the application EUI + * + * @param _appEui the application EUI + */ public void setAppEui(byte[] _appEui) { if (_appEui.length != 8) { throw new IllegalArgumentException("appEui should be 8 bytes long"); @@ -167,10 +213,20 @@ public void setAppEui(byte[] _appEui) { appEui = _appEui; } + /** + * Get the device EUI + * + * @return The device EUI + */ public byte[] getDevEui() { return devEui; } + /** + * Set the device EUI + * + * @param _devEui the device EUI + */ public void setDevEui(byte[] _devEui) { if (_devEui.length != 8) { throw new IllegalArgumentException("devEui should be 8 bytes long"); @@ -178,18 +234,38 @@ public void setDevEui(byte[] _devEui) { devEui = _devEui; } + /** + * Get the application id + * + * @return The application id + */ public String getAppId() { return appId; } + /** + * Get the device id + * + * @return The device id + */ public String getDevId() { return devId; } + /** + * Get the device address + * + * @return The device address + */ public byte[] getDevAddr() { return devAddr; } + /** + * Set the device address + * + * @param _devAddr The device address + */ public void setDevAddr(byte[] _devAddr) { if (_devAddr.length != 4) { throw new IllegalArgumentException("devAddr should be 4 bytes long"); @@ -197,10 +273,20 @@ public void setDevAddr(byte[] _devAddr) { devAddr = _devAddr; } + /** + * Get the network session key + * + * @return The network session key + */ public byte[] getNwkSKey() { return nwkSKey; } + /** + * Set the network session key + * + * @param _nwkSKey The network session key + */ public void setNwkSKey(byte[] _nwkSKey) { if (_nwkSKey.length != 16) { throw new IllegalArgumentException("nwkSKey should be 16 bytes long"); @@ -208,10 +294,20 @@ public void setNwkSKey(byte[] _nwkSKey) { nwkSKey = _nwkSKey; } + /** + * Get the application session key + * + * @return The application session key + */ public byte[] getAppSKey() { return appSKey; } + /** + * Set the application session key + * + * @param _appSKey The application session key + */ public void setAppSKey(byte[] _appSKey) { if (_appSKey.length != 16) { throw new IllegalArgumentException("appSKey should be 16 bytes long"); @@ -219,10 +315,20 @@ public void setAppSKey(byte[] _appSKey) { appSKey = _appSKey; } + /** + * Get the application key + * + * @return The application key + */ public byte[] getAppKey() { return appKey; } + /** + * Set the application key + * + * @param _appKey The application key + */ public void setAppKey(byte[] _appKey) { if (_appKey.length != 16) { throw new IllegalArgumentException("appKey should be 16 bytes long"); @@ -230,46 +336,97 @@ public void setAppKey(byte[] _appKey) { appKey = _appKey; } + /** + * Get the uplink frame counter + * + * @return The uplink frame counter + */ public int getfCntUp() { return fCntUp; } + /** + * Get the downlink frame counter + * + * @return The downlink frame counter + */ public int getfCntDown() { return fCntDown; } + /** + * Check if fCnt check is enabled + * + * @return True if fCnt check is enabled + */ public boolean isDisableFCntCheck() { return disableFCntCheck; } + /** + * Enable/Disable fCnt check + * + * @param _disableFCntCheck True to enable, false to disable + */ public void setDisableFCntCheck(boolean _disableFCntCheck) { disableFCntCheck = _disableFCntCheck; } + /** + * Check if 32 bit frame counter are used + * + * @return True if 32 bit frame counter are used + */ public boolean isUses32BitFCnt() { return uses32BitFCnt; } + /** + * Enable/Disable 32 bit frame counter + * + * @param _uses32BitFCnt True to enable 32 bit frame counter + */ public void setUses32BitFCnt(boolean _uses32BitFCnt) { uses32BitFCnt = _uses32BitFCnt; } + /** + * Get the activation constraints + * + * @return The activation constraints + */ public String getActivationConstraints() { return activationConstraints; } + /** + * Set the activation constraints + * + * @param _activationConstraints The activation constraints + */ public void setActivationConstraints(String _activationConstraints) { activationConstraints = _activationConstraints; } + /** + * Get the last time device was seen + * + * @return The last time device was seen + */ public long getLastSeen() { return lastSeen; } + /** + * Reset uplink frame counter + */ public void resetFCntUp() { fCntUp = 0; } + /** + * Reset downlink frame counter + */ public void resetFCntDown() { fCntDown = 0; } diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java index f81b1da..7df60d8 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java @@ -35,12 +35,19 @@ import rx.schedulers.Schedulers; /** + * This class is an async wrapper for the The Things Network discovery service * * @author Romain Cambier */ public class AsyncDiscovery { + /** + * Main The Things Network discovery server host + */ public static final String HOST = "discovery.thethingsnetwork.org"; + /** + * Main The Things Network discovery server port + */ public static final int PORT = 1900; private final DiscoveryGrpc.DiscoveryFutureStub stub; @@ -49,6 +56,13 @@ private AsyncDiscovery(DiscoveryGrpc.DiscoveryFutureStub _stub) { stub = _stub; } + /** + * Build an AsyncDiscovery wrapper from Host and Port + * + * @param _host The server host + * @param _port The server port + * @return An Observable stream containing the newly built AsyncDiscovery wrapper + */ public static Observable from(String _host, int _port) { return Observable .create((Subscriber t) -> { @@ -66,16 +80,34 @@ public static Observable from(String _host, int _port) { }); } + /** + * Build an AsyncDiscovery wrapper using default servers + * + * @return An Observable stream containing the newly built AsyncDiscovery wrapper + */ public static Observable getDefault() { return from(HOST, PORT); } + /** + * Fetch discovery service for the specified handler + * + * @param _creds A valid authentication token + * @param _handlerId The handler id + * @return An Observable stream containing the AsyncHandler wrapper + */ public Observable getHandler(AsyncOAuth2Token _creds, String _handlerId) { return Observable .from(stub.get(GetRequest.newBuilder().setId(_handlerId).setServiceName(Services.HANDLER.name().toLowerCase()).build()), Schedulers.io()) .flatMap((DiscoveryOuterClass.Announcement t) -> from(_creds, t)); } + /** + * Fetch discovery service for all handlers + * + * @param _creds A valid authentication token + * @return An Observable stream containing the AsyncHandler wrappers + */ public Observable getHandlers(AsyncOAuth2Token _creds) { return Observable .from(stub.getAll(DiscoveryOuterClass.GetServiceRequest.newBuilder().setServiceName(Services.HANDLER.name().toLowerCase()).build()), Schedulers.io()) @@ -114,9 +146,21 @@ public Server(String _s) { } + /** + * List of known The Things Network services + */ public static enum Services { + /** + * Handler Service. Responsible of device management + */ HANDLER, + /** + * Broker Service. Responsible of data deduplication and Handler routing + */ BROKER, + /** + * Router Service. Responsible of global routing + */ ROUTER } } diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java index c48985e..d366ce9 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java @@ -45,6 +45,7 @@ import rx.schedulers.Schedulers; /** + * This class is an async wrapper for the The Things Network handler service * * @author Romain Cambier */ @@ -56,6 +57,15 @@ private AsyncHandler(ApplicationManagerGrpc.ApplicationManagerFutureStub _stub) stub = _stub; } + /** + * Build an AsyncHandler instance + * + * @param _credentials A valid authentication token + * @param _host The handler host + * @param _port The handler port + * @param _certificate The handler certificate + * @return An Observable stream containing the newly built AsyncHandler wrapper + */ public static Observable from(AsyncOAuth2Token _credentials, String _host, int _port, InputStream _certificate) { return Observable @@ -98,6 +108,12 @@ public void start(ClientCall.Listener responseListener, Metadata headers) } + /** + * Register an application to The Things Network + * + * @param _application the application to register + * @return An Observable stream containing the newly registered HandlerApplication + */ public Observable registerApplication(AbstractApplication _application) { return Observable .from(stub.registerApplication( @@ -109,11 +125,23 @@ public Observable registerApplication(AbstractApplication _a .flatMap((ignore) -> getApplication(_application.getId())); } + /** + * Get an application from the handler service + * + * @param _applicationId The id of the application + * @return An Observable stream containing the requested HandlerApplication + */ public Observable getApplication(String _applicationId) { return Observable.from(stub.getApplication(HandlerOuterClass.ApplicationIdentifier.newBuilder().setAppId(_applicationId).build()), Schedulers.io()) .flatMap(HandlerApplication::from); } + /** + * Update (or create) an application on the handler service + * + * @param _application The application (new or updated) + * @return An Observable stream containing the updated HandlerApplication + */ public Observable setApplication(HandlerApplication _application) { return _application .toProto() @@ -121,6 +149,12 @@ public Observable setApplication(HandlerApplication _applica .map((ignore) -> _application); } + /** + * Delete an application from the handler service + * + * @param _application The application + * @return An Observable stream containing the deleted HandlerApplication + */ public Observable deleteApplication(HandlerApplication _application) { return Observable .from(stub.deleteApplication( @@ -132,6 +166,12 @@ public Observable deleteApplication(HandlerApplication _appl .map((ignore) -> _application); } + /** + * Get all devices from the handler service + * + * @param _application The application to list devices of + * @return An Observable stream containing the HandlerDevice objects + */ public Observable getDevices(HandlerApplication _application) { return Observable .from(stub.getDevicesForApplication( @@ -144,6 +184,13 @@ public Observable getDevices(HandlerApplication _application) { .flatMap((HandlerOuterClass.Device t) -> HandlerDevice.from(t)); } + /** + * Get a device from the handler service + * + * @param _application The application containing the device + * @param _deviceId The device id + * @return An Observable stream containing the HandlerDevice + */ public Observable getDevice(HandlerApplication _application, String _deviceId) { return Observable .from(stub.getDevice( @@ -156,6 +203,12 @@ public Observable getDevice(HandlerApplication _application, Stri .flatMap((HandlerOuterClass.Device t) -> HandlerDevice.from(t)); } + /** + * Update (or create) a device on the handler service + * + * @param _device The device + * @return An Observable stream containing the updated HandlerDevice + */ public Observable setDevice(HandlerDevice _device) { return _device.toProto() .flatMap((HandlerOuterClass.Device tt) -> Observable @@ -164,6 +217,12 @@ public Observable setDevice(HandlerDevice _device) { } + /** + * Delete a device on the handler service + * + * @param _device The device + * @return An Observable stream containing the deleted HandlerDevice + */ public Observable deleteDevice(HandlerDevice _device) { return Observable .from(stub.deleteDevice( diff --git a/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java b/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java index 0816437..8036ccd 100644 --- a/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java +++ b/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java @@ -29,7 +29,7 @@ import org.thethingsnetwork.management.async.AsyncHandler; /** - * + * This class is a wrapper for the The Things Network discovery service * @author Romain Cambier */ public class Discovery { @@ -40,6 +40,13 @@ protected Discovery(AsyncDiscovery _wrap) { wrapped = _wrap; } + /** + * Build a Discovery wrapper from Host and Port + * + * @param _host The server host + * @param _port The server port + * @return The newly built Discovery wrapper + */ public static Discovery from(String _host, int _port) { return AsyncDiscovery.from(_host, _port) .map((AsyncDiscovery t) -> new Discovery(t)) @@ -47,10 +54,22 @@ public static Discovery from(String _host, int _port) { .single(); } + /** + * Build a Discovery wrapper using default servers + * + * @return The newly built Discovery wrapper + */ public static Discovery getDefault() { return from(AsyncDiscovery.HOST, AsyncDiscovery.PORT); } + /** + * Fetch discovery service for the specified handler + * + * @param _creds A valid authentication token + * @param _handlerId The handler id + * @return The requested Handler + */ public Handler getHandler(OAuth2Token _creds, String _handlerId) { return wrapped.getHandler(_creds.async(), _handlerId) .map((AsyncHandler t) -> new Handler(t)) @@ -58,6 +77,12 @@ public Handler getHandler(OAuth2Token _creds, String _handlerId) { .single(); } + /** + * Fetch discovery service for all handlers + * + * @param _creds A valid authentication token + * @return A list of the Handler wrappers + */ public List getHandlers(OAuth2Token _creds) { return wrapped.getHandlers(_creds.async()) .map((AsyncHandler t) -> new Handler(t)) diff --git a/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java b/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java index c3d1452..0243309 100644 --- a/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java +++ b/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java @@ -32,6 +32,7 @@ import org.thethingsnetwork.management.async.AsyncHandler; /** + * This class is a wrapper for the The Things Network handler service * * @author Romain Cambier */ @@ -43,6 +44,15 @@ protected Handler(AsyncHandler _wrap) { wrapped = _wrap; } + /** + * Build a Handler wrapper instance + * + * @param _credentials A valid authentication token + * @param _host The handler host + * @param _port The handler port + * @param _certificate The handler certificate + * @return The newly built Handler + */ public static Handler from(OAuth2Token _credentials, String _host, int _port, InputStream _certificate) { return AsyncHandler.from(_credentials.async(), _host, _port, _certificate) .map((AsyncHandler t) -> new Handler(t)) @@ -50,30 +60,60 @@ public static Handler from(OAuth2Token _credentials, String _host, int _port, In .single(); } + /** + * Register an application to The Things Network + * + * @param _application the application to register + * @return The newly registered HandlerApplication + */ public HandlerApplication registerApplication(AbstractApplication _application) { return wrapped.registerApplication(_application) .toBlocking() .single(); } + /** + * Get an application from the handler service + * + * @param _applicationId The id of the application + * @return The requested HandlerApplication + */ public HandlerApplication getApplication(String _applicationId) { return wrapped.getApplication(_applicationId) .toBlocking() .single(); } + /** + * Update (or create) an application on the handler service + * + * @param _application The application (new or updated) + * @return The updated HandlerApplication + */ public HandlerApplication setApplication(HandlerApplication _application) { return wrapped.setApplication(_application) .toBlocking() .single(); } + /** + * Delete an application from the handler service + * + * @param _application The application + * @return The deleted HandlerApplication + */ public HandlerApplication deleteApplication(HandlerApplication _application) { return wrapped.deleteApplication(_application) .toBlocking() .single(); } + /** + * Get all devices from the handler service + * + * @param _application The application to list devices of + * @return The List of HandlerDevice objects + */ public List getDevices(HandlerApplication _application) { return wrapped.getDevices(_application) .toList() @@ -81,12 +121,25 @@ public List getDevices(HandlerApplication _application) { .single(); } + /** + * Get a device from the handler service + * + * @param _application The application containing the device + * @param _deviceId The device id + * @return The HandlerDevice object + */ public HandlerDevice getDevice(HandlerApplication _application, String _deviceId) { return wrapped.getDevice(_application, _deviceId) .toBlocking() .single(); } + /** + * Update (or create) a device on the handler service + * + * @param _device The device + * @return The updated HandlerDevice + */ public HandlerDevice setDevice(HandlerDevice _device) { return wrapped.setDevice(_device) .toBlocking() @@ -94,6 +147,12 @@ public HandlerDevice setDevice(HandlerDevice _device) { } + /** + * Delete a device on the handler service + * + * @param _device The device + * @return The deleted HandlerDevice + */ public HandlerDevice deleteDevice(HandlerDevice _device) { return wrapped.deleteDevice(_device) .toBlocking() From 5e215f9a304593b9d1aa5f3935e45d4d01504a57 Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 13 Feb 2017 10:17:11 +0100 Subject: [PATCH 21/24] javadoc for account --- .../async/auth/token/AsyncJsonWebToken.java | 25 +++- .../async/auth/token/AsyncOAuth2Token.java | 26 +++- .../token/AsyncRenewableJsonWebToken.java | 34 ++++- .../account/common/AccessKey.java | 24 ++++ .../account/common/ApplicationRights.java | 2 +- .../account/common/Collaborator.java | 24 ++++ .../account/sync/Application.java | 121 ++++++++++++++++++ .../sync/auth/grant/ApplicationPassword.java | 27 +++- .../sync/auth/grant/AuthorizationCode.java | 31 ++++- .../account/sync/auth/token/JsonWebToken.java | 11 +- .../account/sync/auth/token/OAuth2Token.java | 32 ++++- .../auth/token/RenewableJsonWebToken.java | 13 ++ 12 files changed, 358 insertions(+), 12 deletions(-) diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java index 4615579..9839648 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java @@ -27,6 +27,7 @@ import rx.Observable; /** + * Async Json Web Token wrapper * * @author Romain Cambier */ @@ -36,6 +37,13 @@ public class AsyncJsonWebToken implements AsyncOAuth2Token { private long expiration; private final URI accountServer; + /** + * Build an instance + * + * @param _token The raw token + * @param _expiration The token expiration (millis) + * @param _accountServer The account server + */ public AsyncJsonWebToken(String _token, long _expiration, URI _accountServer) { if (_token == null) { throw new IllegalArgumentException("token can not be null"); @@ -61,7 +69,12 @@ public Observable refresh() { return Observable.error(new UnsupportedOperationException("Not supported.")); } - protected long getExpiration() { + /** + * Get the expiration + * + * @return The expiration + */ + public long getExpiration() { return expiration; } @@ -75,10 +88,20 @@ public String getToken() { return "Bearer " + token; } + /** + * Set the expiration + * + * @param _expiration The expiration + */ protected void setExpiration(long _expiration) { expiration = _expiration; } + /** + * Set the raw token + * + * @param _token The raw token + */ protected void setToken(String _token) { token = _token; } diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java index 5fd1c89..8eef2e0 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java @@ -27,21 +27,45 @@ import rx.Observable; /** - * + * Base interface of any async Oauth2 token * @author Romain Cambier */ public interface AsyncOAuth2Token { + /** + * Wether or not this token has a refresh method + * @return True if it has + */ public boolean hasRefresh(); + /** + * Refresh this token + * @return The refreshed token as an Observable stream + */ public Observable refresh(); + /** + * Whether this token has expired + * @return True if this token has expired + */ public boolean isExpired(); + /** + * Get the http token + * @return The http token + */ public String getToken(); + /** + * Get the raw token + * @return The raw token + */ public String getRawToken(); + /** + * Get the account server URI + * @return The account server URI + */ public URI getAccountServer(); } diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java index dc9a080..72676be 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java @@ -33,7 +33,7 @@ import rx.Subscriber; /** - * + * Async Renewable Json Web Token wrapper * @author Romain Cambier */ public class AsyncRenewableJsonWebToken extends AsyncJsonWebToken { @@ -41,6 +41,13 @@ public class AsyncRenewableJsonWebToken extends AsyncJsonWebToken { private String refreshToken; private final AsyncAuthorizationCode provider; + /** + * Create an instance + * @param _token The raw token + * @param _expiration The token expiration + * @param _refreshToken The refresh token + * @param _provider The token provider + */ public AsyncRenewableJsonWebToken(String _token, long _expiration, String _refreshToken, AsyncAuthorizationCode _provider) { super(_token, _expiration, _provider.getAccountServer()); if (_refreshToken == null) { @@ -58,10 +65,18 @@ public boolean hasRefresh() { return true; } + /** + * Set the refresh token + * @param _refreshToken The refresh token + */ protected void setRefreshToken(String _refreshToken) { refreshToken = _refreshToken; } + /** + * Get the refresh token + * @return The refresh token + */ public String getRefreshToken() { return refreshToken; } @@ -71,6 +86,11 @@ public Observable refresh() { return provider.refreshToken(this); } + /** + * Restrict this token to a finer claims list + * @param _claims The claims to restrict this token to + * @return A new AsyncRenewableJsonWebToken as an Observable stream + */ public Observable restrict(List _claims) { AsyncRenewableJsonWebToken that = this; return Observable @@ -115,10 +135,22 @@ public Observable refresh() { }); } + /** + * Restrict this token to a finer claims list + * @param _claims The claims to restrict this token to + * @return A new AsyncRenewableJsonWebToken as an Observable stream + */ public Observable restrict(String... _claims) { return restrict(Arrays.asList(_claims)); } + /** + * Refresh this token + * @param _refreshToken New refresh token + * @param _accessToken New access token + * @param _expiration New expiration + * @return The updated AsyncRenewableJsonWebToken + */ public AsyncRenewableJsonWebToken refresh(String _refreshToken, String _accessToken, long _expiration) { setRefreshToken(_refreshToken); setToken(_accessToken); diff --git a/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java index b79b260..5d1947d 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java @@ -38,23 +38,47 @@ public class AccessKey { private String key; private List rights; + /** + * Create an empty AccessKey. Only used by jackson. + */ public AccessKey() { } + /** + * Create a new AccessKey + * + * @param _name The key name + * @param _rights The key rights + */ public AccessKey(String _name, List _rights) { name = _name; rights = _rights; } + /** + * Get the key name + * + * @return The key name + */ public String getName() { return name; } + /** + * Get the key secret + * + * @return The key secret + */ public String getKey() { return key; } + /** + * Get the key rights + * + * @return The key rights + */ public List getRights() { return Collections.unmodifiableList(rights); } diff --git a/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java b/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java index dd96257..3f79bb1 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java @@ -30,7 +30,7 @@ * @author Romain Cambier */ public enum ApplicationRights { - + SETTINGS("settings"), DELETE("delete"), COLLABORATORS("collaborators"), diff --git a/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java b/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java index c7c2689..cbef8cc 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java @@ -38,24 +38,48 @@ public class Collaborator { private String email; private List rights; + /** + * Create an empty Collaborator. Used only by jackson + */ public Collaborator() { } + /** + * Create a new Collaborator + * + * @param _username The username of the Collaborator + * @param _rights The rights of the Collaborator + */ public Collaborator(String _username, List _rights) { username = _username; email = null; rights = _rights; } + /** + * Get the username + * + * @return The username + */ public String getUsername() { return username; } + /** + * Get the email address + * + * @return The email address + */ public String getEmail() { return email; } + /** + * Get the rights + * + * @return The rights + */ public List getRights() { return Collections.unmodifiableList(rights); } diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java index f84c87b..c556f97 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java @@ -32,6 +32,7 @@ import org.thethingsnetwork.account.sync.auth.token.OAuth2Token; /** + * This class is a wrapper for an TTN application. * * @author Romain Cambier */ @@ -39,6 +40,12 @@ public class Application implements AbstractApplication { private final AsyncApplication wrapped; + /** + * Create a new application + * + * @param _id the new application ID + * @param _name the new application name + */ public Application(String _id, String _name) { wrapped = new AsyncApplication(_id, _name); } @@ -47,6 +54,12 @@ private Application(AsyncApplication _wrap) { wrapped = _wrap; } + /** + * List all applications available with this token + * + * @param _creds the OAuth2Token to be used for authentication + * @return the list of Application + */ public static List findAll(OAuth2Token _creds) { return AsyncApplication.findAll(_creds.async()) .map((AsyncApplication t) -> new Application(t)) @@ -55,6 +68,13 @@ public static List findAll(OAuth2Token _creds) { .single(); } + /** + * Create an application + * + * @param _creds the OAuth2Token to be used for authentication + * @param _app the Application template + * @return the new Application + */ public static Application create(OAuth2Token _creds, AbstractApplication _app) { return AsyncApplication.create(_creds.async(), _app) .map((AsyncApplication t) -> new Application(t)) @@ -62,6 +82,13 @@ public static Application create(OAuth2Token _creds, AbstractApplication _app) { .single(); } + /** + * Fetch an application + * + * @param _creds the OAuth2Token to be used for authentication + * @param _id the application ID to fetch + * @return the Application + */ public static Application findOne(OAuth2Token _creds, String _id) { return AsyncApplication.findOne(_creds.async(), _id) .map((AsyncApplication t) -> new Application(t)) @@ -69,6 +96,11 @@ public static Application findOne(OAuth2Token _creds, String _id) { .singleOrDefault(null); } + /** + * Update this application + * + * @return the updated Application + */ public Application save() { return wrapped.save() .map((AsyncApplication t) -> this) @@ -76,6 +108,11 @@ public Application save() { .single(); } + /** + * Delete this application + * + * @return the updated Application + */ public Application delete() { return wrapped.delete() .map((AsyncApplication t) -> this) @@ -83,6 +120,11 @@ public Application delete() { .single(); } + /** + * List all EUIs of this application + * + * @return the EUIs of this Application + */ public List findAllEUIs() { return wrapped.findAllEUIs() .toList() @@ -90,12 +132,23 @@ public List findAllEUIs() { .single(); } + /** + * Create a random EUI on this application + * + * @return the new EUI + */ public String createEUI() { return wrapped.createEUI() .toBlocking() .single(); } + /** + * Create a defined EUI on this application + * + * @param _eui the new EUI + * @return the updated Application + */ public Application addEUI(String _eui) { return wrapped.addEUI(_eui) .map((i) -> this) @@ -103,6 +156,12 @@ public Application addEUI(String _eui) { .single(); } + /** + * Delete an EUI from this application + * + * @param _eui the EUI to be deleted + * @return the updated Application + */ public Application deleteEUI(String _eui) { return wrapped.deleteEUI(_eui) .map((i) -> this) @@ -110,6 +169,11 @@ public Application deleteEUI(String _eui) { .single(); } + /** + * List all collaborators of this application + * + * @return the list of Collaborator of this Application + */ public List getCollaborators() { return wrapped.getCollaborators() .toList() @@ -117,12 +181,24 @@ public List getCollaborators() { .single(); } + /** + * Fetch one collaborator from this application + * + * @param _username the username of the Collaborator + * @return the Collaborator + */ public Collaborator findOneCollaborator(String _username) { return wrapped.findOneCollaborator(_username) .toBlocking() .singleOrDefault(null); } + /** + * Add a collaborator to this application + * + * @param _collaborator the Collaborator to be added + * @return the updated Application + */ public Application addCollaborator(Collaborator _collaborator) { return wrapped.addCollaborator(_collaborator) .map((i) -> this) @@ -130,6 +206,12 @@ public Application addCollaborator(Collaborator _collaborator) { .single(); } + /** + * Remove a collaborator from this application + * + * @param _collaborator the Collaborator to be removed + * @return the updated Application + */ public Application removeCollaborator(Collaborator _collaborator) { return wrapped.removeCollaborator(_collaborator) .map((i) -> this) @@ -137,6 +219,11 @@ public Application removeCollaborator(Collaborator _collaborator) { .single(); } + /** + * List all access-keys of this application + * + * @return the list of AccessKey of this Application + */ public List getAccessKeys() { return wrapped.getAccessKeys() .toList() @@ -144,18 +231,36 @@ public List getAccessKeys() { .single(); } + /** + * Fetch one access-key of this application + * + * @param _keyname the name of the AccessKey + * @return the AccessKey + */ public AccessKey findOneAccessKey(String _keyname) { return wrapped.findOneAccessKey(_keyname) .toBlocking() .singleOrDefault(null); } + /** + * Add an access-key to this application + * + * @param _key the AccessKey template + * @return the new AccessKey + */ public AccessKey addAccessKey(AccessKey _key) { return wrapped.addAccessKey(_key) .toBlocking() .single(); } + /** + * Remove an access-key from this application + * + * @param _key the AccessKey + * @return the updated Application + */ public Application removeAccessKey(AccessKey _key) { return wrapped.removeAccessKey(_key) .map((i) -> this) @@ -163,6 +268,11 @@ public Application removeAccessKey(AccessKey _key) { .single(); } + /** + * Refresh this local application + * + * @return the updated Application + */ public Application refresh() { return wrapped.refresh() .map((AsyncApplication app) -> this) @@ -170,6 +280,11 @@ public Application refresh() { .single(); } + /** + * List all rights of this application and token + * + * @return the list of ApplicationRights of this Application + */ public List getRights() { return wrapped.getRights() .toList() @@ -177,6 +292,12 @@ public List getRights() { .single(); } + /** + * List all rights of the provided token on this application + * + * @param _creds the OAuth2Token to check right of + * @return the list of ApplicationRights of this Application + */ public List getRights(OAuth2Token _creds) { return wrapped.getRights(_creds.async()) .toList() diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java index 9fab26b..656e0b9 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java @@ -30,6 +30,7 @@ import org.thethingsnetwork.account.sync.auth.token.JsonWebToken; /** + * This token provider uses application credentials (id + access-key) to generate a token only usable for the owning application * * @author Romain Cambier */ @@ -37,14 +38,27 @@ public class ApplicationPassword extends GrantType { private final AsyncApplicationPassword wrapped; - public ApplicationPassword(AsyncApplicationPassword _wrapped) { - wrapped = _wrapped; - } - + /** + * Create an instance of this token provider using fully-customized settings + * + * @param _appId The application id + * @param _key The application access-key + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + * @param _accountServer The account server to be used + */ public ApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret, URI _accountServer) { wrapped = new AsyncApplicationPassword(_appId, _key, _clientId, _clientSecret, _accountServer); } + /** + * Create an instance of this token provider using default account server + * + * @param _appId The application id + * @param _key The application access-key + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + */ public ApplicationPassword(String _appId, String _key, String _clientId, String _clientSecret) { wrapped = new AsyncApplicationPassword(_appId, _key, _clientId, _clientSecret); } @@ -54,6 +68,11 @@ public URI getAccountServer() { return wrapped.getAccountServer(); } + /** + * Create a token using the settings provided in the constructor + * + * @return the JsonWebToken as an Observable stream + */ public JsonWebToken getToken() { return wrapped.getToken() .map((AsyncJsonWebToken t) -> new JsonWebToken(t)) diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java index 4b506bf..25157d2 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java @@ -31,17 +31,30 @@ import org.thethingsnetwork.account.sync.auth.token.RenewableJsonWebToken; /** - * + * This token provider uses authorization-code flow, meaning it requires user-interraction * @author Romain Cambier */ public class AuthorizationCode extends GrantType{ private final AsyncAuthorizationCode wrapped; + /** + * Create an instance of this token provider using fully-customized settings + * + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + * @param _accountServer The account server to be used + */ public AuthorizationCode(String _clientId, String _clientSecret, URI _accountServer) { wrapped = new AsyncAuthorizationCode(_clientId, _clientSecret, _accountServer); } + /** + * Create an instance of this token provider using default account server + * + * @param _clientId The client id you received from the account server + * @param _clientSecret The client secret you received from the account server + */ public AuthorizationCode(String _clientId, String _clientSecret) { wrapped = new AsyncAuthorizationCode(_clientId, _clientSecret); } @@ -51,10 +64,26 @@ public URI getAccountServer() { return wrapped.getAccountServer(); } + /** + * Generate an authorization endpoint to be sent to the user. + * + * Once the user will proceed to authorization (even in case of error) he will redirected to the provided URI, with some query parameters including the code in case of success, or an error if something went wrong + * + * Warning: The redirect URI has to be whitelisted in the account server ! + * + * @param _redirect The redirect URI where the user should be driven after authorization + * @return The HttpUrl where the user should go to access the authorization form + */ public HttpUrl buildAuthorizationURL(URI _redirect) { return wrapped.buildAuthorizationURL(_redirect); } + /** + * Request a token from an authorization-code after successfull authorization + * + * @param _authorizationCode the authorization-code generated by the account server + * @return the RenewableJsonWebToken + */ public RenewableJsonWebToken getToken(String _authorizationCode) { return wrapped.getToken(_authorizationCode) .map((AsyncRenewableJsonWebToken t) -> new RenewableJsonWebToken(t)) diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java index 98b39ed..5269622 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java @@ -27,7 +27,7 @@ import org.thethingsnetwork.account.async.auth.token.AsyncJsonWebToken; /** - * + * Json Web Token wrapper * @author Romain Cambier */ public class JsonWebToken implements OAuth2Token { @@ -42,6 +42,15 @@ public JsonWebToken(AsyncJsonWebToken _wrap) { public boolean hasRefresh() { return wrapped.hasRefresh(); } + + /** + * Get the expiration + * + * @return The expiration + */ + protected long getExpiration() { + return wrapped.getExpiration(); + } @Override public JsonWebToken refresh() { diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java index 91e3745..dbc3664 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java @@ -32,18 +32,46 @@ */ public interface OAuth2Token { + /** + * Wether or not this token has a refresh method + * @return True if it has + */ public boolean hasRefresh(); - public T refresh(); + /** + * Refresh this token + * @return The refreshed token + */ + public OAuth2Token refresh(); + /** + * Whether this token has expired + * @return True if this token has expired + */ public boolean isExpired(); + /** + * Get the http token + * @return The http token + */ public String getToken(); + /** + * Get the raw token + * @return The raw token + */ public String getRawToken(); + /** + * Get the account server URI + * @return The account server URI + */ public URI getAccountServer(); - public T async(); + /** + * Get the wrapped async token + * @return The wrapped async token + */ + public AsyncOAuth2Token async(); } diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java index 6a94fa5..4df0187 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java @@ -29,6 +29,7 @@ import org.thethingsnetwork.account.async.auth.token.AsyncRenewableJsonWebToken; /** + * Renewable Json Web Token wrapper * * @author Romain Cambier */ @@ -74,6 +75,12 @@ public URI getAccountServer() { return wrapped.getAccountServer(); } + /** + * Restrict this token to a finer claims list + * + * @param _claims The claims to restrict this token to + * @return A new RenewableJsonWebToken + */ public RenewableJsonWebToken restrict(List _claims) { return wrapped.restrict(_claims) .map((AsyncRenewableJsonWebToken t) -> new RenewableJsonWebToken(t)) @@ -81,6 +88,12 @@ public RenewableJsonWebToken restrict(List _claims) { .single(); } + /** + * Restrict this token to a finer claims list + * + * @param _claims The claims to restrict this token to + * @return A new RenewableJsonWebToken + */ public RenewableJsonWebToken restrict(String... _claims) { return restrict(Arrays.asList(_claims)); } From 073a624c1b146e0eebeb42c6327245012a92d3de Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 13 Feb 2017 10:24:47 +0100 Subject: [PATCH 22/24] javadoc fixes --- .../thethingsnetwork/account/common/AbstractApplication.java | 2 ++ .../java/org/thethingsnetwork/data/common/Subscribable.java | 1 - .../org/thethingsnetwork/data/common/events/EventHandler.java | 1 - .../data/common/messages/ActivationMessage.java | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java index 85f8eb9..64b2cc3 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java @@ -28,6 +28,7 @@ /** * * @author Romain Cambier + * @param internal */ @JsonIgnoreProperties(ignoreUnknown = true) public interface AbstractApplication { @@ -61,6 +62,7 @@ public interface AbstractApplication { /** * Update the AsyncOAuth2Token to be used by this application wrapper + * @param internal * @param _creds the new AsyncOAuth2Token to be used */ public void updateCredentials(R _creds); diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java index 3be01cc..0a43150 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java @@ -24,7 +24,6 @@ package org.thethingsnetwork.data.common; /** - * @internal * @author Romain Cambier */ public interface Subscribable { diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java index 6646f38..25cc912 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java @@ -26,7 +26,6 @@ import org.thethingsnetwork.data.common.Subscribable; /** - * @internal * @author Romain Cambier */ public interface EventHandler { diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java index f4e7fec..4478ac3 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java @@ -44,7 +44,7 @@ private ActivationMessage() { /** * Get the LoraWan Application EUI * - * @returnthe LoraWan Application EUI + * @return the LoraWan Application EUI */ public String getAppEui() { return appEui; From 219bfa18ad0aab9dd3f6824d9c6293b67c7e2fa8 Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 13 Feb 2017 10:32:55 +0100 Subject: [PATCH 23/24] fixed a method typo --- .../src/main/java/org/thethingsnetwork/data/mqtt/Client.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java b/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java index d256d09..8c04551 100644 --- a/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java +++ b/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java @@ -298,7 +298,7 @@ public void deliveryComplete(IMqttDeliveryToken token) { private static final String WILDCARD_PATH = "#"; @Override - public void subscibe(String[] _key) throws Exception { + public void subscribe(String[] _key) throws Exception { StringJoiner sj = new StringJoiner("/"); for (String key : _key) { sj.add(key); From f1f5a4981dde5622d0f365b2fc1aa2106860356a Mon Sep 17 00:00:00 2001 From: cambierr Date: Mon, 13 Feb 2017 10:40:03 +0100 Subject: [PATCH 24/24] updated copyright from 2016 to 2017 --- .../org/thethingsnetwork/account/async/AsyncApplication.java | 2 +- .../account/async/auth/grant/AsyncApplicationPassword.java | 2 +- .../account/async/auth/grant/AsyncAuthorizationCode.java | 2 +- .../account/async/auth/token/AsyncJsonWebToken.java | 2 +- .../account/async/auth/token/AsyncOAuth2Token.java | 2 +- .../account/async/auth/token/AsyncRenewableJsonWebToken.java | 2 +- .../thethingsnetwork/account/common/AbstractApplication.java | 2 +- .../java/org/thethingsnetwork/account/common/AccessKey.java | 2 +- .../org/thethingsnetwork/account/common/ApplicationRights.java | 2 +- .../java/org/thethingsnetwork/account/common/Collaborator.java | 2 +- .../java/org/thethingsnetwork/account/common/GrantType.java | 2 +- .../java/org/thethingsnetwork/account/sync/Application.java | 2 +- .../account/sync/auth/grant/ApplicationPassword.java | 2 +- .../account/sync/auth/grant/AuthorizationCode.java | 2 +- .../thethingsnetwork/account/sync/auth/token/JsonWebToken.java | 2 +- .../thethingsnetwork/account/sync/auth/token/OAuth2Token.java | 2 +- .../account/sync/auth/token/RenewableJsonWebToken.java | 2 +- .../java/org/thethingsnetwork/account/util/HttpException.java | 2 +- .../java/org/thethingsnetwork/account/util/HttpRequest.java | 2 +- .../src/main/java/org/thethingsnetwork/data/amqp/Client.java | 2 +- .../java/org/thethingsnetwork/data/common/AbstractClient.java | 2 +- .../main/java/org/thethingsnetwork/data/common/Connection.java | 2 +- .../main/java/org/thethingsnetwork/data/common/Metadata.java | 2 +- .../java/org/thethingsnetwork/data/common/Subscribable.java | 2 +- .../main/java/org/thethingsnetwork/data/common/TriConsumer.java | 2 +- .../data/common/events/AbstractEventHandler.java | 2 +- .../thethingsnetwork/data/common/events/ActivationHandler.java | 2 +- .../org/thethingsnetwork/data/common/events/ConnectHandler.java | 2 +- .../org/thethingsnetwork/data/common/events/ErrorHandler.java | 2 +- .../org/thethingsnetwork/data/common/events/EventHandler.java | 2 +- .../org/thethingsnetwork/data/common/events/UplinkHandler.java | 2 +- .../data/common/messages/ActivationMessage.java | 2 +- .../org/thethingsnetwork/data/common/messages/DataMessage.java | 2 +- .../thethingsnetwork/data/common/messages/DownlinkMessage.java | 2 +- .../org/thethingsnetwork/data/common/messages/RawMessage.java | 2 +- .../thethingsnetwork/data/common/messages/UplinkMessage.java | 2 +- .../src/main/java/org/thethingsnetwork/data/mqtt/Client.java | 2 +- .../org/thethingsnetwork/management/HandlerApplication.java | 2 +- .../java/org/thethingsnetwork/management/HandlerDevice.java | 2 +- .../java/org/thethingsnetwork/management/LorawanDevice.java | 2 +- .../org/thethingsnetwork/management/async/AsyncDiscovery.java | 2 +- .../org/thethingsnetwork/management/async/AsyncHandler.java | 2 +- .../java/org/thethingsnetwork/management/sync/Discovery.java | 2 +- .../main/java/org/thethingsnetwork/management/sync/Handler.java | 2 +- .../src/main/java/org/thethingsnetwork/samples/account/App.java | 2 +- .../samples/account/ApplicationPasswordAsync.java | 2 +- .../samples/account/ApplicationPasswordSync.java | 2 +- .../samples/account/AuthorizationCodeAsync.java | 2 +- .../thethingsnetwork/samples/account/AuthorizationCodeSync.java | 2 +- .../src/main/java/org/thethingsnetwork/samples/amqp/App.java | 2 +- .../main/java/org/thethingsnetwork/samples/management/App.java | 2 +- .../thethingsnetwork/samples/management/ManagementAsync.java | 2 +- .../org/thethingsnetwork/samples/management/ManagementSync.java | 2 +- .../src/main/java/org/thethingsnetwork/samples/mqtt/App.java | 2 +- 54 files changed, 54 insertions(+), 54 deletions(-) diff --git a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java index a4d30dd..a62ea0b 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/AsyncApplication.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java index b205bbb..cb60cae 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncApplicationPassword.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java index 8d7d222..305182a 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/grant/AsyncAuthorizationCode.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java index 9839648..a4c0a23 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncJsonWebToken.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java index 8eef2e0..824b880 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncOAuth2Token.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java index 72676be..479dae0 100644 --- a/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/async/auth/token/AsyncRenewableJsonWebToken.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java index 64b2cc3..71e2ca1 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AbstractApplication.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java index 5d1947d..e4569e4 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/AccessKey.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java b/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java index 3f79bb1..73ff7b7 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/ApplicationRights.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java b/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java index cbef8cc..55ee28c 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/Collaborator.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/common/GrantType.java b/account/src/main/java/org/thethingsnetwork/account/common/GrantType.java index 8042c31..d4fcdd4 100644 --- a/account/src/main/java/org/thethingsnetwork/account/common/GrantType.java +++ b/account/src/main/java/org/thethingsnetwork/account/common/GrantType.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java index c556f97..749ac93 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/Application.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/Application.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java index 656e0b9..d480d33 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/ApplicationPassword.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java index 25157d2..7d97afc 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/grant/AuthorizationCode.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java index 5269622..8f200d9 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/JsonWebToken.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java index dbc3664..2966b75 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/OAuth2Token.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java index 4df0187..a93a961 100644 --- a/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java +++ b/account/src/main/java/org/thethingsnetwork/account/sync/auth/token/RenewableJsonWebToken.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/util/HttpException.java b/account/src/main/java/org/thethingsnetwork/account/util/HttpException.java index a1f95ee..9416403 100644 --- a/account/src/main/java/org/thethingsnetwork/account/util/HttpException.java +++ b/account/src/main/java/org/thethingsnetwork/account/util/HttpException.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java index fe9e0b8..25945e8 100644 --- a/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java +++ b/account/src/main/java/org/thethingsnetwork/account/util/HttpRequest.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java b/data/data-amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java index 8b15e30..77a52be 100644 --- a/data/data-amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java +++ b/data/data-amqp/src/main/java/org/thethingsnetwork/data/amqp/Client.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java index 8072201..733bdd9 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/AbstractClient.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java index dcd9d2f..f2a5a39 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Connection.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java index b618534..e853967 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Metadata.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java index 2807eb8..f5998fe 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/Subscribable.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java index 605d9b8..1d27bd2 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/TriConsumer.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java index 8dcb201..22c1e02 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/AbstractEventHandler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java index 2e847f9..a4a260c 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ActivationHandler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java index aa10d5f..460d31c 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ConnectHandler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java index 3875ce9..8cc3b41 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/ErrorHandler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java index 25cc912..b010f67 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/EventHandler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java index e053ff9..8c32207 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/events/UplinkHandler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java index 4478ac3..ff87522 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/ActivationMessage.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java index 26c146a..643bcad 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DataMessage.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java index b88e8de..edfbd02 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/DownlinkMessage.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java index 626b860..561a407 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/RawMessage.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java index 9ee0528..73a332c 100644 --- a/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java +++ b/data/data-common/src/main/java/org/thethingsnetwork/data/common/messages/UplinkMessage.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java b/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java index 8c04551..9335384 100644 --- a/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java +++ b/data/data-mqtt/src/main/java/org/thethingsnetwork/data/mqtt/Client.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java b/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java index 9939a7f..d6905df 100644 --- a/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java +++ b/management/src/main/java/org/thethingsnetwork/management/HandlerApplication.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java index 86a968b..821a97b 100644 --- a/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/HandlerDevice.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java index 4e95020..6e07bce 100644 --- a/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java +++ b/management/src/main/java/org/thethingsnetwork/management/LorawanDevice.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java index 7df60d8..c347894 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncDiscovery.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java index d366ce9..a73e151 100644 --- a/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java +++ b/management/src/main/java/org/thethingsnetwork/management/async/AsyncHandler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java b/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java index 8036ccd..e51bc58 100644 --- a/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java +++ b/management/src/main/java/org/thethingsnetwork/management/sync/Discovery.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java b/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java index 0243309..016d534 100644 --- a/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java +++ b/management/src/main/java/org/thethingsnetwork/management/sync/Handler.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java index d9a0333..832efd3 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/App.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java index 52329fd..e62c6f8 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordAsync.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java index 83efc6f..0540e67 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/ApplicationPasswordSync.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java index 6f461bd..0c23a91 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeAsync.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java index adaa378..a4db894 100644 --- a/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java +++ b/samples/samples-account/src/main/java/org/thethingsnetwork/samples/account/AuthorizationCodeSync.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java b/samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java index 3ec9d59..1b4547b 100644 --- a/samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java +++ b/samples/samples-amqp/src/main/java/org/thethingsnetwork/samples/amqp/App.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java index 7bb7a07..0a116e5 100644 --- a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java +++ b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/App.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java index b43751c..50e3238 100644 --- a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java +++ b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementAsync.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java index 35cfc8e..271b80d 100644 --- a/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java +++ b/samples/samples-management/src/main/java/org/thethingsnetwork/samples/management/ManagementSync.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/samples/samples-mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java b/samples/samples-mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java index 2929d6a..55285e6 100644 --- a/samples/samples-mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java +++ b/samples/samples-mqtt/src/main/java/org/thethingsnetwork/samples/mqtt/App.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 The Things Network + * Copyright (c) 2017 The Things Network * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal