Skip to content
This repository has been archived by the owner on Jul 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #58 from sathipal/master
Browse files Browse the repository at this point in the history
Custom message support, fix for #50, #45 and removed historian APIs
  • Loading branch information
Lokesh K Haralakatta authored Sep 6, 2016
2 parents c3553d8 + efc8c71 commit d4d5b71
Show file tree
Hide file tree
Showing 26 changed files with 983 additions and 884 deletions.
72 changes: 0 additions & 72 deletions docs/java_cli_for_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -480,78 +480,6 @@ Refer to the Problem Determination section of the `IBM Watson IoT Platform API <

----

Historical Event Retrieval
----------------------------------
Application can use this operation to view events from all devices, view events from a device type or to view events for a specific device.

Refer to the Historical Event Retrieval section of the `IBM Watson IoT Platform API <https://docs.internetofthings.ibmcloud.com/swagger/v0002.html>`__ for information about the list of query parameters, the request & response model and http status code.

View events from all devices
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Method getHistoricalEvents() can be used to view events across all devices registered to the organization.

.. code:: java
JsonElement response = apiClient.getHistoricalEvents();
The response will contain more parameters and application needs to retrieve the JSON element *events* from the response to get the array of events returned. Other parameters in the response are required to make further call, for example, the *_bookmark* element can be used to page through results. Issue the first request without specifying a bookmark, then take the bookmark returned in the response and provide it on the request for the next page. Repeat until the end of the result set indicated by the absence of a bookmark. Each request must use exactly the same values for the other parameters, or the results are undefined.

In order to pass the *_bookmark* or any other condition, the overloaded method must be used. The overloaded method takes the parameters in the form of org.apache.http.message.BasicNameValuePair as shown below,

.. code:: java
parameters.add(new BasicNameValuePair("evt_type", "blink"));
parameters.add(new BasicNameValuePair("start", "1445420849839"));
JsonElement response = this.apiClient.getHistoricalEvents(parameters);
The above snippet returns the events which are of type *blink* and received after time *1445420849839*.

View events from a device type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Method getHistoricalEvents() can be used to view events from all the devices of a particular device type.

.. code:: java
JsonElement response = this.apiClient.getHistoricalEvents(iotsample-ardunio);
The response will contain more parameters and application needs to retrieve the JSON element *events* from the response to get the array of events returned. As mentioned in the *view events from all devices* section, the overloaded method can be used to control the output.

.. code:: java
parameters.add(new BasicNameValuePair("evt_type", "blink"));
parameters.add(new BasicNameValuePair("summarize", "{cpu,mem}"));
parameters.add(new BasicNameValuePair("summarize_type", "avg"));
JsonElement response = this.apiClient.getHistoricalEvents("iotsample-ardunio", parameters);
The above snippet returns the events which are of device type *iotsample-ardunio*, event type *blink* and aggregates the fields *cpu* & *mem* and computes the average.

View events from a device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Method getHistoricalEvents() can be used to view events from a specific device.

.. code:: java
JsonElement response = this.apiClient.getHistoricalEvents(iotsample-ardunio, ardunio01);
The response will contain more parameters and application needs to retrieve the JSON element *events* from the response to get the array of events returned. As mentioned in the *view events from all devices* section, the overloaded method can be used to control the output.

.. code:: java
parameters.add(new BasicNameValuePair("evt_type", "blink"));
parameters.add(new BasicNameValuePair("summarize", "{cpu,mem}"));
parameters.add(new BasicNameValuePair("summarize_type", "avg"));
JsonElement response = apiClient.getHistoricalEvents("iotsample-ardunio", "ardunio01", parameters);
The above snippet returns the events which are of device *ardunio01*, event type *blink* and aggregates the fields *cpu* & *mem* and computes the average.

----

Device Management request operations
----------------------------------------------------

Expand Down
34 changes: 32 additions & 2 deletions docs/java_cli_for_applications.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ The constructor builds the client instance, and accepts a Properties object cont
* auth-token - API key token (required if auth-method is “apikey”).
* clean-session - true or false (required only if you want to connect the application in durable subscription. By default the clean-session is set to true).
* shared-subscription - true or false (required only if shared subscription needs to be enabled)
* WebSocket - true or false (default is false, required if you want to connect the device using websockets)
* Secure - true or false (default is true and recommended)
* MaxInflightMessages - Sets the maximum number of inflight messages for the connection (default value is 100)

**Note**: One must set shared-subscription to true to build scalable applications which will load balance messages across multiple instances of the application. Refer to the `scalable applications section <https://docs.internetofthings.ibmcloud.com/applications/mqtt.html#/scalable-applications#scalable-applications>`__ for more information about the load balancing.

Expand Down Expand Up @@ -163,7 +166,7 @@ To process the events received by your subscriptions you need to register an eve
* event.deviceId - string
* event.event - string
* event.format - string
* event.data - dict
* event.data - Object
* event.timestamp - datetime

A sample implementation of the Event callback,
Expand Down Expand Up @@ -206,7 +209,7 @@ A sample implementation of the Event callback,
try {
e = evtQueue.take();
// In this example, we just output the event
System.out.println("Event:: " + e.getDeviceId() + ":" + e.getEvent() + ":" + e.getPayload());
System.out.println("Event:: " + e.getDeviceId() + ":" + e.getEvent() + ":" + e.getData());
} catch (InterruptedException e1) {
// Ignore the Interuppted exception, retry
continue;
Expand Down Expand Up @@ -353,6 +356,27 @@ Applications can publish events as if they originated from a Device.
// publish the event on behalf of device
myClient.publishEvent(deviceType, deviceId, "blink", event);
Events can be published in different formats, like JSON, String, Binary and etc.. By default the library publishes the event in JSON format, but one can specify the data in different formats. For example, to publish data in String format use the following code snippet (Note that the payload must be in String format),

.. code:: java
myClient.connect();
String data = "cpu:"+60;
status = myClient.publishEvent("load", data, "text", 2);
Any XML data can be converted to String and published as follows,

.. code:: java
status = myClient.publishEvent("load", xmlConvertedString, "xml", 2);
Similarly to publish events in binary format, use the byte array as shown below,

.. code:: java
myClient.connect();
byte[] cpuLoad = new byte[] {60, 35, 30, 25};
status = myClient.publishEvent("blink", cpuLoad , "binary", 1);
----

Publishing commands to devices
Expand All @@ -371,6 +395,12 @@ Applications can publish commands to connected devices.
//Registered flow allows 0, 1 and 2 QoS
myAppClient.publishCommand(deviceType, deviceId, "stop", data);
Similar to events, the commands can be published in different formats, like JSON, String, Binary as well. By default the library publishes the commands in JSON format, but one can specify the data in different formats. For example, to publish command in String format use the following code snippet (Note that the payload must be in String format),

.. code:: java
myClient.connect();
myAppClient.publishCommand(deviceType, deviceId, "stop", "rotation:0", "text", 1);
----

Examples
Expand Down
35 changes: 33 additions & 2 deletions docs/java_cli_for_devices.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ The constructor builds the client instance, and accepts a Properties object cont
* auth-method - Method of authentication (This is an optional field, needed only for registered flow and the only value currently supported is "token").
* auth-token - API key token (This is an optional field, needed only for registered flow).
* clean-session - true or false (required only if you want to connect the application in durable subscription. By default the clean-session is set to true).
* WebSocket - true or false (default is false, required if you want to connect the device using websockets)
* Secure - true or false (default is true and recommended)
* MaxInflightMessages - Sets the maximum number of inflight messages for the connection (default value is 100)

**Note:** One must set clean-session to false to connect the device in durable subscription. Refer to `Subscription Buffers and Clean Session <https://docs.internetofthings.ibmcloud.com/reference/mqtt/index.html#/subscription-buffers-and-clean-session#subscription-buffers-and-clean-session>`__ for more information about the clean session.

Expand Down Expand Up @@ -215,9 +218,9 @@ Publishing events
-------------------------------------------------------------------------------
Events are the mechanism by which devices publish data to the Watson IoT Platform. The device controls the content of the event and assigns a name for each event it sends.
When an event is received by the IBM IoT Foundation the credentials of the connection on which the event was received are used to determine from which device the event was sent. With this architecture it is impossible for a device to impersonate another device.
When an event is received by the Watson IoT Platform, the credentials of the connection on which the event was received are used to determine from which device the event was sent. With this architecture it is impossible for a device to impersonate another device.
Events can be published at any of the three `quality of service levels <https://docs.internetofthings.ibmcloud.com/messaging/mqtt.html#/>` defined by the MQTT protocol. By default events will be published as qos level 0.
Events can be published at any of the three `quality of service levels <https://docs.internetofthings.ibmcloud.com/messaging/mqtt.html#/>` defined by the MQTT protocol. By default events will be published as qos level 0 and with JSON format.
Publish event using default quality of service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -256,6 +259,34 @@ Events can be published at higher MQTT quality of servive levels, but these even
----
Publish event using custom format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Events can be published in different formats, like JSON, String, Binary and etc.. By default, the library publishes the event in JSON format, but one can specify the data in different formats. For example, to publish data in String format use the following code snippet,(Note that the type of the payload must be in String format)
.. code:: java
myClient.connect();
String data = "cpu:"+getProcessCpuLoad();
status = myClient.publishEvent("load", data, "text", 2);
Any XML data can be converted to String and published as follows,
.. code:: java
status = myClient.publishEvent("load", xmlConvertedString, "xml", 2);
Similarly, to publish events in binary format, use the byte array as shown below,
.. code:: java
myClient.connect();
byte[] cpuLoad = new byte[] {30, 35, 30, 25};
status = myClient.publishEvent("blink", cpuLoad , "binary", 1);
----
Publish event using HTTP(s)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Apart from MQTT, the devices can publish events to IBM Watson IoT Platform using HTTP(s) by following 3 simple steps,
Expand Down
59 changes: 55 additions & 4 deletions docs/java_cli_for_gateway.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ The constructor builds the Gateway client instance, and accepts a Properties obj
* auth-method - Method of authentication (The only value currently supported is "token").
* auth-token - API key token.
* clean-session - true or false (required only if you want to connect the Gateway in durable subscription. By default the clean-session is set to true).
* WebSocket - true or false (default is false, required if you want to connect the device using websockets)
* Secure - true or false (default is true and recommended)
* MaxInflightMessages - Sets the maximum number of inflight messages for the connection (default value is 100)

**Note:** One must set clean-session to false to connect the Gateway in durable subscription. Refer to `Subscription Buffers and Clean Session <https://docs.internetofthings.ibmcloud.com/reference/mqtt/index.html#/subscription-buffers-and-clean-session#subscription-buffers-and-clean-session>`__ for more information about the clean session.

Expand Down Expand Up @@ -166,7 +169,31 @@ Events can be published at higher MQTT quality of service levels, but these even
gwClient.publishGatewayEvent("status", event, 2);
Publish Gateway event using custom format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Events can be published in different formats, like JSON, String, Binary and etc.. By default, the library publishes the event in JSON format, but one can specify the data in different formats. For example, to publish data in String format use the following code snippet,(Note that the type of the payload must be String)

.. code:: java
gwClient.connect();
String data = "cpu:"+getProcessCpuLoad();
boolean status = gwClient.publishGatewayEvent("load", data, "text", 2);
Any XML data can be converted to String and published as follows,

.. code:: java
status = gwClient.publishGatewayEvent("load", xmlConvertedString, "xml", 2);
Similarly, to publish events in binary format, use the byte array as shown below,

.. code:: java
gwClient.connect();
byte[] cpuLoad = new byte[] {30, 35, 30, 25};
status = gwClient.publishGatewayEvent("blink", cpuLoad , "binary", 1);
Publishing events from devices
-------------------------------------------------------------------------------

Expand All @@ -187,6 +214,30 @@ The Gateway can publish events on behalf of any device connected via the Gateway
One can use the overloaded publishDeviceEvent() method to publish the device event in the desired quality of service. Refer to `MQTT Connectivity for Gateways <https://docs.internetofthings.ibmcloud.com/gateways/mqtt.html>`__ documentation to know more about the topic structure used.

Publish device event using custom format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Similar to gateway Events, the device events can be published in different formats as well. By default, the library publishes the event in JSON format, but one can specify the data in different formats. For example, to publish data in String format use the following code snippet, (Note that the type of the payload must be String)

.. code:: java
gwClient.connect();
String data = "cpu:"+getProcessCpuLoad();
boolean status = gwClient.publishDeviceEvent(deviceType, deviceId, "load", data, "text", 2);
Any XML data can be converted to String and published as follows,

.. code:: java
status = gwClient.publishDeviceEvent(deviceType, deviceId, "load", xmlConvertedString, "xml", 2);
Similarly, to publish events in binary format, use the byte array as shown below,

.. code:: java
gwClient.connect();
byte[] cpuLoad = new byte[] {30, 35, 30, 25};
status = gwClient.publishDeviceEvent(deviceType, deviceId, "blink", cpuLoad , "binary", 1);
----


Expand All @@ -205,8 +256,8 @@ To process specific commands you need to register a command callback method. The

* deviceType - The device type for which the command is received.
* deviceId - The device id for which the command is received, Could be the Gateway or any device connected via the Gateway.
* payload - The command payload.
* format - The format of the command payload, currently only JSON format is supported in the Java Client Library.
* data - The command payload.
* format - The format of the command payload, JSON, binary, text and etc..
* command - The name of the command.
* timestamp - The org.joda.time.DateTime when the command is sent.

Expand All @@ -228,7 +279,7 @@ A sample implementation of the Command callback is shown below,
public void run() {
while(true) {
Command cmd = queue.take();
System.out.println("Command " + cmd.getPayload());
System.out.println("Command " + cmd.getData());
// code to process the command
}
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.ibm.messaging</groupId>
<artifactId>watson-iot</artifactId>
<version>0.1.4</version>
<version>0.2.1</version>
<packaging>jar</packaging>
<name>ibm-messaging/iot-java</name>
<description>IBM Watson IoT client library to simplify device/gateway/application interactions with the IoT Platform</description>
Expand Down
15 changes: 7 additions & 8 deletions src/main/java/com/ibm/iotf/client/AbstractClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ public abstract class AbstractClient {
// Supported only for DM ManagedClient
protected MqttClient mqttClient = null;
protected MemoryPersistence persistence = null;

protected static final boolean newFormat;

static {
newFormat = Boolean.parseBoolean(System.getProperty("com.ibm.iotf.enableCustomFormat", "true"));
}

/**
* Note that this class does not have a default constructor <br>
Expand Down Expand Up @@ -672,14 +678,7 @@ protected static int publishEventsThroughHttps(String organization,
br = new BufferedReader(new InputStreamReader(System.in));

// Create the payload message in Json format
JsonObject message = new JsonObject();

String timestamp = ISO8601_DATE_FORMAT.format(new Date());
message.addProperty("ts", timestamp);

JsonElement dataElement = gson.toJsonTree(payload);
message.add("d", dataElement);

JsonObject message = (JsonObject) gson.toJsonTree(payload);
StringEntity input = new StringEntity(message.toString(), StandardCharsets.UTF_8);

// Create the Http post request
Expand Down
Loading

0 comments on commit d4d5b71

Please sign in to comment.