Invoking REST APIs in Java

Overview

While it is possible to use REST APIs as URLs in a Web browser, a more powerful use of
REST comes from programmatic access to the Cloud data store. In this section,
we will demonstrate how to write a Java application to both send and receive
data using REST APIs.

This tutorial assumes you are using Eurotech’s “Sandbox”
broker, which is used for customers with development systems, and uses Web URLs
starting with: “https://api-sandbox.everyware-cloud.com/v2/”.
If you are using the Production broker, you will have a different URL, which
should be substituted in place of the URLs described in this document.

Import
REST Client Project

In Eclipse, select File | Import if you have not already
imported the “edc-rest” example project. Select “General | Existing Projects
into Workspace,” then click Next. Click Browse for the root
directory, and browse to the workspace location of the cloud examples that were
downloaded in the Eclipse setup section. Select the “edc-rest” project folder,
but do not select the checkbox “Copy projects into workspace” (the
projects are already in the workspace location). (If you wish, you may import
all projects, but this tutorial will only discuss the REST client.) You may
add the project to a working set if desired. Then click Finish.

You should now have the “edc-rest” project in your
workspace, and it should not show any build errors.

NOTE: If you delete the project out of the workspace
later, you should not “Delete project contents on disk.” This is
because we have used the Maven install procedures to setup the projects
directly into your Eclipse workspace location. If you do delete the contents
on disk, you would need to create a new workspace and re-download the source
code from Eurotech’s software repository, as described in Setting up Eclipse Environment for Java.

Set Cloud Client Variables

Toward the top of the code example, there are several
variables noted with comments, which are specific to your Cloud user account.
These variables need to be modified according to your Cloud account
credentials, so the REST client can connect properly. See the section Accessing your Cloud Account to set up an
account in Everyware Cloud.

In the sample code, set the following variables with the
proper settings of your Cloud broker account, and a valid TEST_EMAIL address at
which you can receive e-mails. The e-mail sent from the Cloud as a result of
the REST rule will come from edc-alerts@eurotech.com,
in case your e-mail filter needs to be configured. Then save changes in the
sample application.

Using Java REST Application

The sample Java application tests several REST API calls to
demonstrate what can be accomplished with the APIs through program calls.
After going through this tutorial, you can modify the Java code to understand
more fully how the client application works, and to send different data to the
broker.

Before running this sample application, it is recommended (although
not required) that you have previously run an MQTT Client application (such as
the EDC Java client or C++ client) on this account. This will
publish data and metrics to the account, which can then be queried using REST.

Starting Cloud Connection

After the client variables have been modified, make a
connection to the Cloud by selecting the Run menu, and the option “Run” or “Run
as...Java Application”. You can also select the green Run button in the Launch toolbar.

If the variables are not set correctly, there will be an
error in the console:

Exception in thread "main" java.lang.Exception:

Unable to connect to the cloud -- check your
URL, username, and password in a browser to make sure you can log in.

URL:
https://api-sandbox.everyware-cloud.com/v2/accounts.xml

at
com.eurotech.cloud.examples.EdcRestExample.main(EdcRestExample.java:82)

Reading Data using REST

List Accounts

Assuming you have a successful connection to the broker, the
next step in the sample application is to invoke a REST
API to read account data from the Eurotech Cloud data store. The following
examples are specific to the example code provided here, but you should see
similar kinds of data returned.

First, the Account name is acquired. Note that the
“accounts.xml” is simply added as part of the URL in the Web client resource. Note
that the elements in the URL path are case-sensitive.

Your account name should be displayed in the Console window:

String
apiPath = "accounts.xml";

WebResource
apisWeb = client.resource(API_URL).path(apiPath);

AccountsResult
result = apisWeb.get(AccountsResult.class);

List<Account> accounts = result.getAccounts();

##############

Beginning test of listAccounts()

Accounts.size(): 1

Account name: myEdcAccount

List Devices

The next REST API to be called gives a list
of devices, which should be displayed in the Console window:

List Metrics

The next REST API to be called lists
the metrics that have been published on a specified topic, and displays
them in the Console window. In this case, the “metrics/searchByTopic” is added
to the URL, but then the “topic” query parameter is also added before invoking
the API.

Publish and Store Data with REST

The next section of the sample application uses REST
APIs to create a rule. The rule looks for a published message on a given
topic, and upon matching the topic, it takes two actions: sends an e-mail to a
specified e-mail account, and publishes a new message back to the Cloud using
MQTT. Then it uses an API to publish a message on the given topic, causing the
rule to be triggered, stores another message directly into the message archive using
a store API, and then reads back all messages thus created. Finally, the rule
that was created earlier is deleted.

The following sections describe these actions in a little
more detail and give an example Console output of the sample application.

Create Rule Using REST API

In the Cloud Web console, rules can be created through the
user interface. However, the REST APIs allow all aspects of the Cloud account
to be managed from a different application, apart from the Web console.

First, the Java application uses the createRule() method to
create the basic rule, including the query statement. This is the same
Statement as described in the Console user
interface, and uses the Esper
syntax. Note that when coding the query statement in Java, double
quotes " need to be escaped by using a leading
backslash \ character.

However, to add an MQTT or REST action to a rule, the format
is a little different. With these actions, the list of metrics and values to
include in the action are selected in the Web console using a tabular list.
When using this action in Java, the parameter argument takes the form of a JSON
statement. One easy way to code this is to create the rule in the Web console
first. Then use a Web browser to query the rules API.
This will show the proper form of the JSON statement for the ‘metrics’
parameter, which can then be copied into the Java code. Again, any double
quotes " need to be escaped by using a leading
backslash \ character.

Publish Using REST API

Next, the Java application calls the restPublish() method.
This invokes a REST
API to publish a message on a given topic. The createPayload() method
builds a payload with several metrics of different data types, including the
metric named ‘pub_double_metric’. The ‘publish’ resource of the ‘messages’ API
is invoked to publish the message.

Here it is worthwhile to note the use of the ErrorBean(). If
there is an error in an API call, the ErrorBean() class can be used to output
additional diagnostic information on the cause of the API exception.

This published message, once received in the Cloud account,
triggers the actions contained in the rule that we created earlier. The e-mail
address specified in the variable TEST_EMAIL should receive a message sent
automatically from the Cloud, and a new message with topic “$account/RulesAssistant/rule/test”
will be published into the Cloud account.

Store Data
Using REST API

The Java application then calls the restStore() method,
which invokes a REST
API to store a message directly into the database. An EdcPayload() is
created and added to the EdcMessage(). The ‘store’ resource of the ‘messages’
API is invoked to store the message. The createPayload() method builds a
payload with several metrics of different data types, including the metric
named ‘api_double_metric’.

Update Rule Using REST API

The updateRule() method is called, which invokes the REST
API to update a rule. Originally, the rule was created using the HTTP POST
operation. In this case, the rule is retrieved from the existing set of rules
and the e-mail address is changed to the second test e-mail (TEST_EMAIL2).
Then the updated rule is saved using the “/rules/{ruleId}.xml” API resource and
the HTTP PUT operation. Note that it would have been easier to use the rule ID
created earlier in the program, but this example illustrates searching for the
rule by name, which doesn’t require any prior knowledge of the rule ID.

Read
Recent Messages

We have just published a message using REST, which in turn
triggered a rule that published a new message. We have also stored a message
directly to the message archive using REST. Therefore, the sample application
has caused three new messages to be added to the data store. The next method,
restRead(), reads back all messages created in the last 30 seconds, and
displays them in the Eclipse console window. This uses the listMessages()
method, already discussed above, to read back messages published in the
previous 30 seconds:

listMessages("", 0, 30);

##############

Beginning test of restRead()

Waiting several seconds, to make
sure all published messages have reached the account.

Note: if you experiment with the sample application by
trying to create other Rules definitions, you can comment out the call to
deleteRule(), so that you can go into the Everyware Cloud Web console to
troubleshoot the rule query or its actions. However, the sample application
will then be unable to add the rule because one already exists with the same
name. You should manually delete the rule using the Cloud Web console, and
then you can successfully re-run the Java application.