Reputation: 113
Is there any mechanism or method or steps to detect the endpoint(KAA SDK) connectivity to the KAA server from the application.
If no, then how can we identifies failure devices through remotely?? or How can we identifies devices that are not able to communicate with the KAA Server after deploying devices in the field??
How one can achieve this requirement to unlock the power of IOT??
Upvotes: 4
Views: 918
Reputation: 2516
If your endpoint will meet some problems connecting to Kaa server a "failover" will happen.
So you must define your own failover strategy and set it for your Kaa client. Every time failover happens strategy's onFialover()
method will be called.
Below you can see the code example for the Java SDK.
import org.kaaproject.kaa.client.DesktopKaaPlatformContext;
import org.kaaproject.kaa.client.Kaa;
import org.kaaproject.kaa.client.KaaClient;
import org.kaaproject.kaa.client.SimpleKaaClientStateListener;
import org.kaaproject.kaa.client.channel.failover.FailoverDecision;
import org.kaaproject.kaa.client.channel.failover.FailoverStatus;
import org.kaaproject.kaa.client.channel.failover.strategies.DefaultFailoverStrategy;
import org.kaaproject.kaa.client.exceptions.KaaRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* A demo application that shows how to use the Kaa credentials API.
*/
public class CredentialsDemo {
private static final Logger LOG = LoggerFactory.getLogger(CredentialsDemo.class);
private static KaaClient kaaClient;
public static void main(String[] args) throws InterruptedException, IOException {
LOG.info("Demo application started");
try {
// Create a Kaa client and add a startup listener
kaaClient = Kaa.newClient(new DesktopKaaPlatformContext(), new SimpleKaaClientStateListener() {
@Override
public void onStarted() {
super.onStarted();
LOG.info("Kaa client started");
}
}, true);
kaaClient.setFailoverStrategy(new CustomFailoverStrategy());
kaaClient.start();
// ... Do some work ...
LOG.info("Stopping application.");
kaaClient.stop();
} catch (KaaRuntimeException e) {
LOG.info("Cannot connect to server - no credentials found.");
LOG.info("Stopping application.");
}
}
// Give a possibility to manage device behavior when it loses connection
// or has other problems dealing with Kaa server.
private static class CustomFailoverStrategy extends DefaultFailoverStrategy {
@Override
public FailoverDecision onFailover(FailoverStatus failoverStatus) {
LOG.info("Failover happen. Failover type: " + failoverStatus);
// See enum DefaultFailoverStrategy from package org.kaaproject.kaa.client.channel.failover
// to list all possible values
switch (failoverStatus) {
case CURRENT_BOOTSTRAP_SERVER_NA:
LOG.info("Current Bootstrap server is not available. Trying connect to another one.");
// ... Do some recovery, send notification messages, etc. ...
// Trying to connect to another bootstrap node one-by-one every 5 seconds
return new FailoverDecision(FailoverDecision.FailoverAction.USE_NEXT_BOOTSTRAP, 5L, TimeUnit.SECONDS);
default:
return super.onFailover(failoverStatus);
}
}
}
}
UPDATED (2016/10/28)
From the server side you can check endpoint credentials status as shown in method checkCredentialsStatus()
in code below. The status IN_USE
shows that endpoint has at least one successful connection attempt.
Unfortunately in current Kaa version there are no ways to directly check if endpoint is connected to server or not. I describe them after code example.
package org.kaaproject.kaa.examples.credentials.kaa;
import org.kaaproject.kaa.common.dto.ApplicationDto;
import org.kaaproject.kaa.common.dto.admin.AuthResultDto;
import org.kaaproject.kaa.common.dto.credentials.CredentialsStatus;
import org.kaaproject.kaa.examples.credentials.utils.IOUtils;
import org.kaaproject.kaa.server.common.admin.AdminClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class KaaAdminManager {
private static final Logger LOG = LoggerFactory.getLogger(KaaAdminManager.class);
private static final int DEFAULT_KAA_PORT = 8080;
private static final String APPLICATION_NAME = "Credentials demo";
public String tenantAdminUsername = "admin";
public String tenantAdminPassword = "admin123";
private AdminClient adminClient;
public KaaAdminManager(String sandboxIp) {
this.adminClient = new AdminClient(sandboxIp, DEFAULT_KAA_PORT);
}
// ...
/**
* Check credentials status for getting information
* @return credential status
*/
public void checkCredentialsStatus() {
LOG.info("Enter endpoint ID:");
// Reads endpoint ID (aka "endpoint key hash") from user input
String endpointId = IOUtils.getUserInput().trim();
LOG.info("Getting credentials status...");
try {
ApplicationDto app = getApplicationByName(APPLICATION_NAME);
String appToken = app.getApplicationToken();
// CredentialsStatus can be: AVAILABLE, IN_USE, REVOKED
// if endpoint is not found on Kaa server, exception will be thrown
CredentialsStatus status = adminClient.getCredentialsStatus(appToken, endpointId);
LOG.info("Credentials for endpoint ID = {} are now in status: {}", endpointId, status.toString());
} catch (Exception e) {
LOG.error("Get credentials status for endpoint ID = {} failed. Error: {}", endpointId, e.getMessage());
}
}
/**
* Get application object by specified application name
*/
private ApplicationDto getApplicationByName(String applicationName) {
checkAuthorizationAndLogin();
try {
List<ApplicationDto> applications = adminClient.getApplications();
for (ApplicationDto application : applications) {
if (application.getName().trim().equals(applicationName)) {
return application;
}
}
} catch (Exception e) {
LOG.error("Exception has occurred: " + e.getMessage());
}
return null;
}
/**
* Checks authorization and log in
*/
private void checkAuthorizationAndLogin() {
if (!checkAuth()) {
adminClient.login(tenantAdminUsername, tenantAdminPassword);
}
}
/**
* Do authorization check
* @return true if user is authorized, false otherwise
*/
private boolean checkAuth() {
AuthResultDto.Result authResult = null;
try {
authResult = adminClient.checkAuth().getAuthResult();
} catch (Exception e) {
LOG.error("Exception has occurred: " + e.getMessage());
}
return authResult == AuthResultDto.Result.OK;
}
}
You can see an more examples of using AdminClient
in class KaaAdminManager in Credentials Demo Application from Kaa sample-apps project on GitHub.
Knowing workarounds
* To make effective use of Kaa Data Collection feature, you must add such metadata in settings of selected Log appender (in Kaa Admin UI): "Endpoint key hash" (the same as "Endpoint ID"), "Timestamp". This will automatically add needed fields to every log record received from endpoints.
Upvotes: 5
Reputation: 26
I'm new to Kaa myself and unsure whether there is a method to determine that directly in the SDK, but a work-around is that you could have an extra endpoint from which you periodically send an event to all the other endpoints and expect a reply. When an endpoint does not reply, you know there's a problem.
Upvotes: 0