[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 <dlab...@us.ibm.com> Authored: Wed Feb 1 15:39:48 2017 -0500 Committer: Dale LaBossiere <dlab...@us.ibm.com> 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); +}