Java
- Prerequisites
- Environment setup
- Basic API overview
- Client state
- Platform comparison
- ExecutorContext configuration
This guide explains how to start using the Kaa Java SDK for your IoT applications. It describes the environment setup, basic API, and provides comparison between desktop and Android versions of the Kaa Java SDK. The Kaa Java SDK should be preferred if you want to run your application on a variety of comparatively powerful platforms, or if you plan on developing an Android application.
You can find auto-generated docs for Core Kaa Java SDK here with desktop flavor covered here, and Android here.
Prerequisites
- Your favorite text editor or IDE
- JDK 1.7 or higher
Environment setup
To set up your Java SDK environment:
-
Generate endpoint SDK for target platform ‘Java’.
-
Add the generated
.jar
file to the classpath by using appropriate build tools. For example, you can create thelib
folder and put there the generated.jar
file.
<repositories>
<repository>
<id>local-maven-repo</id>
<url>file:///${project.basedir}/lib</url>
</repository>
</repositories>
...
<dependency>
<groupId>org.kaaproject.kaa.client</groupId>
<artifactId>client-java-desktop</artifactId>
<version>${build-version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/kaa-java-ep-sdk-LVcpSA4q5BiErcm10Zg86TSGL9s.jar</systemPath>
</dependency>
dependencies {
compile files('./lib/kaa-java-ep-sdk-LVcpSA4q5BiErcm10Zg86TSGL9s.jar')
}
- Add the following dependencies to enable logging.
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.7'
compile group: 'ch.qos.logback', name: 'logback-core', version: '1.1.2'
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.2'
After completing the configurations, you can start writing your application.
Basic API overview
First, you have to create an instance of KaaClient
.
The Kaa SDK provides you with the Kaa
class factory, which should be used for creating new instances of the Kaa client.
See the following code example.
KaaClient client = Kaa.newClient(new DesktopKaaPlatformContext(), new SimpleKaaClientStateListener(), true);
KaaClient client = Kaa.newClient(new AndroidKaaPlatformContext(), new SimpleKaaClientStateListener(), true);
The newClient()
static method receives three mandatory arguments – the platform-specific context, the implementation of the client state listener interface and the boolean argument that specifies whether to generate a public/private key pair automatically.
The first argument can be either DesktopKaaPlatformContext
for Java desktop or AndroidKaaPlatformContext
for Android applications.
In this example, the second argument is the default implementation of KaaClientStateListener
– SimpleKaaClientStateListener
, which is solely used to log the client state changes.
As to the third argument: when it is set to false, an existing pre-generated public/private key pair is used; when true, a new public/private key pair is auto-generated if there is none.
You can configure properties and ExecutorContext
of DesktopKaaPlatformContext
with help of its constructors.
DesktopKaaPlatformContext
uses FlexibleExecutorContext
implementation of ExecutorContext
by default.
You can change it by calling corresponding the constructor with a specific ExecutorContext
implementation.
FlexibleExecutorContext
has four thread groups, responsible for life cycle, callbacks, API, and scheduling.
Each of these groups is implemented as separate thread pool (using ThreadPoolExecutor
or its subclass).
Each of them has minimum and maximum threads amount and maximum thread idle time.
By default minimum threads amount for all these groups is zero, maximum threads amount is almost not limited (it set to Integer.MAX_VALUE
) and maximum idle time is 100 milliseconds.
You can call the corresponding constructor to limit maximum threads amount or idle time (minimum threads amount is always zero).
For scheduled thread groups, you can change only its minimum threads amount.
It is recommended to use the builder to construct the FlexibleExecutorContext
instance with custom parameters.
The other ExecutorContext
implementation which goes with Kaa is SimpleExecutorContext
.
Its minimum threads amount is 1 for each group.
And its maximum threads amount is also limited to 1 by default but can be changed with a proper constructor (see example below).
Here are some examples for using a non-empty constructor and using builder.
KaaClientProperties properties = new KaaClientProperties();
properties.put(CUSTOM_PROPERTY_NAME, CUSTOM_PROPERTY_VALUE);
DesktopKaaPlatformContext desktopKaaPlatformContext = new DesktopKaaPlatformContext(properties,
CUSTOM_MAX_LIFE_CYCLE_THREADS, CUSTOM_MAX_API_THREADS,
CUSTOM_MAX_CALLBACK_THREADS, CUSTOM_MIN_SCHEDULED_THREADS
); // If you have no properties to set, just pass null instead of first constructor's argument
KaaClient client = Kaa.newClient(desktopKaaPlatformContext, new SimpleKaaClientStateListener(), true);
ExecutorContext executor = new SimpleExecutorContext(
CUSTOM_MAX_LIFE_CYCLE_THREADS, CUSTOM_MAX_API_THREADS,
CUSTOM_MAX_CALLBACK_THREADS, CUSTOM_MIN_SCHEDULED_THREADS
);
DesktopKaaPlatformContext desktopKaaPlatformContext = new DesktopKaaPlatformContext(null, executor);
KaaClient client = Kaa.newClient(desktopKaaPlatformContext, new SimpleKaaClientStateListener(), true);
ExecutorContext executorContext = new FlexibleExecutorContext.FlexibleExecutorContextBuilder()
.setMaxLifeCycleThreads(CUSTOM_MAX_LIFE_CYCLE_THREADS)
.setMaxLifeCycleThreadsIdleMilliseconds(CUSTOM_MAX_LIFECYCLE_THREADS_IDLE_MILLISECONDS)
.setMaxApiThreads(CUSTOM_MAX_API_THREADS)
.setMaxApiThreadsIdleMilliseconds(CUSTOM_MAX_API_THREADS_IDLE_MILLISECONDS)
.setMaxCallbackThreads(CUSTOM_MAX_CALLBACK_THREADS)
.setMaxCallbackThreadsIdleMilliseconds(CUSTOM_MAX_CALLBACK_THREADS_IDLE_MILLISECONDS)
.setMinScheduledThreads(CUSTOM_MIN_SCHEDULED_THREADS)
.build();
DesktopKaaPlatformContext desktopKaaPlatformContext = new DesktopKaaPlatformContext(null, executorContext);
KaaClient client = Kaa.newClient(desktopKaaPlatformContext, new SimpleKaaClientStateListener(), true);
Whenever a new instance of the Kaa client is created, the start()
method is invoked to start the client operation and communication with the server.
Starting from this point, you can use any features provided by the Kaa platform, such as data collection, notifications, etc., in your application code.
When you no longer need the client, you can call the stop()
method to release resources and stop the client communication with the server.
Client state
When the Kaa client starts for the first time, it generates a private/public key pair and saves those keys in the key.private
and key.public
files accordingly.
These keys are used to maintain secure communication with the server.
The Kaa client also creates the state.properties
file that is used to persist the parameters that handle the client state during its communication with the server.
In the case of a Java desktop application, all these files are created by default in the working directory.
However, you can specify a different folder by using KaaClientProperties
.
For that purpose, set the path to the new folder by using the setWorkingDirectory()
method and then pass the client properties instance as an argument for the DesktopKaaPlatformContext
constructor.
Platform comparison
The only difference between the Android client and the Java desktop client is the implementation of the KaaPlatformContext
class.
The following table illustrates key differences between them.
Method | Desktop | Android | Description |
---|---|---|---|
createHttpClient |
Same | Same | Creates an HTTP client that is used in HTTP Kaa data channel to send responses to the server. |
createPersistentStorage |
Uses file storage | Uses Android internal storage | Persists the client state. |
getBase64 |
Uses Apache Base64 | Uses Android Base64 | Encodes/decodes data to be sent over network without losses, e.g. an endpoint key hash. |
createConnectivityChecker |
Same | Same | Checks network connection. |
getExecutorContext |
Same | Same | Creates instances of the ExecutorService class for SDK internal usage. |
getProperties |
Same | Same | Returns KaaClientProperties that contains important information about the client SDK. |
needToCheckClientState |
Returns true | Returns false | Set off/on to check feasibility of the transition between the life cycle states. |
ExecutorContext configuration
Both AndroidKaaPlatformContext
and DesktopKaaPlatformContext
allow you to specify ExecutorContext
.
The ExecutorContext
class provides implementation and configuration of the ExecutorService
class, which is used to run internal KaaClient
tasks.
The following table provides ExecutorService
implementations.
ExecutorService | Responsibilities |
---|---|
LifeCycleExecutor | Handles KaaClient lifecycle events (Start/Stop/Pause/Resume), processes callbacks from KaaClientStateListener . |
ApiExecutor | Processes the client’s calls to the server. One example is persisting log records into an internal log storage and enqueuing them for further forwarding to the server. |
CallbackExecutor | Handles events from the server and callbacks from listeners: AttachEndpointToUserCallback ConfigurationListener DetachEndpointFromUserCallback FindEventListenersCallback LogDeliveryListener NotificationListener NotificationTopicListListener OnAttachEndpointOperationCallback OnDetachEndpointOperationCallback UserAttachCallback |
ScheduledExecutor | Handles log forwarding to the server, runs failover and bootstrap tasks. |
Available ExecutorService implementations
SimpleExecutorContext — this implementation provides one java.util.concurrent.ScheduledExecutorService
for ScheduledExecutor
and three separate instances of java.util.concurrent.ExecutorService
for LifeCycleExecutor
, ApiExecutor
, and CallbackExecutor
.
The ExecutorService
instances contain a fixed number of threads in the pool.
SimpleExecutorContext
with one thread for each ExecutorService
is a default ExecutorContext
implementation used by KaaClient
.
To configure SimpleExecutorContext
, use the following instruction.
int threadsCount = 2;
ExecutorContext executorContext = new SimpleExecutorContext(threadsCount, threadsCount, threadsCount, threadsCount);
DesktopKaaPlatformContext desktopKaaPlatformContext = new DesktopKaaPlatformContext(new KaaClientProperties(), executorContext);
KaaClient kaaClient = Kaa.newClient(desktopKaaPlatformContext, new SimpleKaaClientStateListener(), true);
android.content.Context context = this; //to be specified by implementor
int threadsCount = 2;
ExecutorContext executorContext = new SimpleExecutorContext(threadsCount, threadsCount, threadsCount, threadsCount);
AndroidKaaPlatformContext androidKaaPlatformContext = new AndroidKaaPlatformContext(context, new KaaClientProperties(), executorContext);
KaaClient kaaClient = Kaa.newClient(androidKaaPlatformContext, new SimpleKaaClientStateListener(), true);
SingleThreadExecutorContext — this implementation shares single java.util.concurrent.ScheduledExecutorService
with one thread in the pool for LifeCycleExecutor
, ApiExecutor
, CallbackExecutor
, and ScheduledExecutor
.
NOTE: Avoid running any blocking or long running tasks within listeners passed to
KaaClient
. Make sure thatExecutorContext
is properly configured.