[Edgent-374] [COMMENTS?] IotGateway [ci-skip]
Add IotGateway
Add IotDevice.{getDeviceType(),getDeviceId(),CMD_DEVICE}
These IotDevice changes break existing IotDevice implementations but in
practice this won't be a problem - its highly unlikely any IotDevice
implementations exist outside of this repository (and adapting is
trivial). "default" can't be used due to support for Java7/Android.
Other schemes are possible that avoid this but they don't model things
as well (an IotDevice really does have an Id), introduce even more types
(e.g., a IotGatewayConnectedDevice), and/or are less convenient to use.
e.g., those new IotDevice methods could be migrated to IotGateway -
IotGateway.getDeviceId(IotDevice).
Project: http://git-wip-us.apache.org/repos/asf/incubator-edgent/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-edgent/commit/82862367
Tree: http://git-wip-us.apache.org/repos/asf/incubator-edgent/tree/82862367
Diff: http://git-wip-us.apache.org/repos/asf/incubator-edgent/diff/82862367
Branch: refs/heads/master
Commit: 82862367b238013f164c06ba7982ebf6a4492cf7
Parents: 2d94ce0
Author: Dale LaBossiere <[email protected]>
Authored: Wed Feb 1 15:39:48 2017 -0500
Committer: Dale LaBossiere <[email protected]>
Committed: Fri Feb 24 21:53:40 2017 -0500
----------------------------------------------------------------------
.../apache/edgent/connectors/iot/IotDevice.java | 41 ++++++-
.../edgent/connectors/iot/IotGateway.java | 122 +++++++++++++++++++
2 files changed, 162 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/82862367/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotDevice.java
----------------------------------------------------------------------
diff --git
a/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotDevice.java
b/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotDevice.java
index 920561d..046bc95 100644
---
a/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotDevice.java
+++
b/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotDevice.java
@@ -29,6 +29,22 @@ import com.google.gson.JsonObject;
/**
* Generic Internet of Things device connector.
+ * <p>
+ * IotDevice characteristics:
+ * <ul>
+ * <li>{@code IotDevice.getDeviceTypeId()} returns an opaque value whose form
+ * is the domain of an IoT connector implementation.</li>
+ * <li>{@code IotDevice.getDeviceId()} returns an opaque value whose form
+ * is the domain of an IoT connector implementation.
+ * The value is unique for a particular a logical device.
+ * <li>{@code IotDevice.equals()} returns true if two IotDevice instances are
+ * for the same logical device, false otherwise.</li>
+ * <li>{@code IotDevice.hashCode()} returns the same value for all IotDevice
instances
+ * for the same logical device.</li>
+ * <li>{@code IotDevice} may be used as a {@link
org.apache.edgent.topology.TWindow TWindow} partition key.</li>
+ * </ul>
+ *
+ * @see IotGateway
*/
public interface IotDevice extends TopologyElement {
@@ -36,6 +52,20 @@ public interface IotDevice extends TopologyElement {
* Device event and command identifiers starting with {@value} are
reserved for use by Edgent.
*/
String RESERVED_ID_PREFIX = "edgent";
+
+ /**
+ * Get the device's opaque device type identifier.
+ * TODO remove the "default" - avoids compilation errors while discussing
this.
+ * @return
+ */
+ public default String getDeviceType() { return "a-device-type-id"; }
+
+ /**
+ * Get the device's unique opaque device identifier.
+ * TODO remove the "default" - avoids compilation errors while discussing
this.
+ * @return
+ */
+ public default String getDeviceId() { return "a-device-id"; }
/**
* Publish a stream's tuples as device events.
@@ -106,12 +136,21 @@ public interface IotDevice extends TopologyElement {
* @see #commands(String...)
*/
String CMD_PAYLOAD = "payload";
+ /**
+ * Device identifier key.
+ * Key is {@value}.
+ * The value is the result of {@link #getDeviceId()}.
+ *
+ * @see #commands(String...)
+ */
+ String CMD_DEVICE = "device";
/**
* Create a stream of device commands as JSON objects.
* Each command sent to the device matching {@code commands} will result
in a tuple
* on the stream. The JSON object has these keys:
* <UL>
+ * <LI>{@link #CMD_DEVICE device} - Command's opaque target device's id
String.
* <LI>{@link #CMD_ID command} - Command identifier as a String</LI>
* <LI>{@link #CMD_TS tsms} - Timestamp of the command in milliseconds
since the 1970/1/1 epoch.</LI>
* <LI>{@link #CMD_FORMAT format} - Format of the command as a String</LI>
@@ -125,7 +164,7 @@ public interface IotDevice extends TopologyElement {
*
*
* @param commands Command identifiers to include. If no command
identifiers are provided then the
- * stream will contain all device commands.
+ * stream will contain all of this IotDevice's device commands.
* @return Stream containing device commands.
*/
TStream<JsonObject> commands(String... commands);
http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/82862367/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotGateway.java
----------------------------------------------------------------------
diff --git
a/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotGateway.java
b/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotGateway.java
new file mode 100644
index 0000000..d714d74
--- /dev/null
+++
b/connectors/iot/src/main/java/org/apache/edgent/connectors/iot/IotGateway.java
@@ -0,0 +1,122 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.edgent.connectors.iot;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.edgent.topology.TStream;
+
+import com.google.gson.JsonObject;
+
+/**
+ * A generic IoT Gateway device connector.
+ * <p>
+ * An IoT Gateway device is a conduit for a collection of IoT devices
+ * that lack direct connection to the enterprise IoT hub.
+ * <p>
+ * The IoT Gateway device is an {@link IotDevice}. Events can be published
+ * that are from the gateway device and commands can be received that are
targeted for it
+ * using the IotGateway's {@code events()} and {@code commands()}.
+ * <p>
+ * Use {@link #getIotDevice(Map)} to get an IotDevice for a connected device.
+ * The name/value pairs in the map are IotGateway implementation defined
values.
+ * Refer to the IotGateway implementation for details.
+ * Events can be published that are from that device and commands can be
+ * received for that are targeted for that device using the connected device's
IotDevice
+ * {@code events()} and {@code commands()).
+ *
+ * @see IotDevice
+ */
+public interface IotGateway extends IotDevice {
+
+ /**
+ * Get an {@link IotDevice} for a connected device.
+ * @param deviceIdAttrs IotGateway implementation specific attributes
+ * that identify a connected device.
+ * @return
+ */
+ public IotDevice getIotDevice(Map<String,String> deviceIdAttrs);
+
+ /**
+ * Get an {@link IotDevice} for a connected device.
+ * @param deviceId a value from {@link IotDevice#getDeviceId()}.
+ * @return
+ */
+ public IotDevice getIotDevice(String deviceId);
+
+ /**
+ * Create a stream of device commands as JSON objects.
+ * Each command sent to one of the specified devices matching {@code
commands} will
+ * result in a tuple on the stream. The JSON object has these keys:
+ * <UL>
+ * <LI>{@link IotDevice#CMD_DEVICE device} - Command's target device's
opaque id String.
+ * <LI>{@link IotDevice#CMD_ID command} - Command identifier as a String</LI>
+ * <LI>{@link IotDevice#CMD_TS tsms} - Timestamp of the command in
milliseconds since the 1970/1/1 epoch.</LI>
+ * <LI>{@link IotDevice#CMD_FORMAT format} - Format of the command as a
String</LI>
+ * <LI>{@link IotDevice#CMD_PAYLOAD payload} - Payload of the command
+ * <UL>
+ * <LI>If {@code format} is {@code json} then {@code payload} is JSON</LI>
+ * <LI>Otherwise {@code payload} is String</LI>
+ * </UL>
+ * </LI>
+ * </UL>
+ * <P>
+ * This is logically equivalent to a union of a collection of individual
IotDevice specific
+ * command streams but enables an IotGateway implementation to implement it
more efficiently.
+ *
+ * @param devices
+ * Only return commands for the specified connected devices
+ * @param commands Command identifiers to include. If no command identifiers
are provided then the
+ * stream will contain all device commands for the specified devices.
+ * @return Stream containing device commands.
+ */
+ TStream<JsonObject> commands(Collection<IotDevice> devices, String...
commands);
+
+ /**
+ * Create a stream of device commands as JSON objects.
+ * Each command sent to connected devices of type {@code deviceTypeId}
matching {@code commands}
+ * will result in a tuple on the stream. The JSON object has these keys:
+ * <UL>
+ * <LI>{@link IotDevice#CMD_DEVICE device} - Command's target device's
opaque id String.
+ * <LI>{@link IotDevice#CMD_ID command} - Command identifier as a String</LI>
+ * <LI>{@link IotDevice#CMD_TS tsms} - Timestamp of the command in
milliseconds since the 1970/1/1 epoch.</LI>
+ * <LI>{@link IotDevice#CMD_FORMAT format} - Format of the command as a
String</LI>
+ * <LI>{@link IotDevice#CMD_PAYLOAD payload} - Payload of the command
+ * <UL>
+ * <LI>If {@code format} is {@code json} then {@code payload} is JSON</LI>
+ * <LI>Otherwise {@code payload} is String</LI>
+ * </UL>
+ * </LI>
+ * </UL>
+ * <P>
+ * An IoT connector implementation may throw
+ * {@link java.lang.UnsupportedOperationException
UnsupportedOperationException}
+ * if it does not support this capability. See the implementation's
documentation.
+ *
+ * @param deviceTypeId
+ * Only return commands for connected devices with the specified
+ * device type id value (a value from {@link
IotDevice#getDeviceType()}).
+ * @param commands Command identifiers to include. If no command identifiers
are provided then the
+ * stream will contain all device commands for devices with the specified
device type id.
+ * @return Stream containing device commands.
+ */
+ TStream<JsonObject> commandsForType(String deviceTypeId, String... commands);
+}