Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/release/v1.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ikulikov committed Apr 27, 2016
2 parents 32baccf + 35ab5e4 commit d4cf95d
Show file tree
Hide file tree
Showing 180 changed files with 1,397 additions and 1,272 deletions.
2 changes: 1 addition & 1 deletion activationdemo/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.kaaproject.kaa</groupId>
<version>1.2.1</version>
<version>1.3.0</version>
<artifactId>examples</artifactId>
</parent>
<groupId>org.kaaproject.kaa.examples</groupId>
Expand Down
34 changes: 27 additions & 7 deletions activationdemo/resources/projects.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,43 @@
<description>Endpoint activation application that demonstrates Kaa’s server profiling, grouping, and configuration management capabilities</description>
<details>
<![CDATA[
This Endpoint activation app demonstrates the use of server-side endpoint profile feature. It allows to activate/deactivate device based on the endpoint ID using Kaa REST API.
This Endpoint activation app demonstrates the use of server-side endpoint profile and device management features. It allows to activate/deactivate device based on the endpoint ID and work with endpoint credentials using Kaa REST API.
<h2>Installation</h2>
Download the jar file to your desktop by clicking the "Binary" button on the left. Make sure that you have Java runtime installed. Application can run in two modes: client and admin. The mode is specified by command line arguments.<br/>
Download the jar file to your desktop by clicking the "Binary" button on the left. Make sure that you have Java runtime installed. Application can run in three modes: client, admin and developer. The mode is specified by command line arguments.<br/>
To run in the "admin" mode, use the following command in the console:
<pre>
$ java -jar ActivationDemo.jar admin ipAddress
$ java -jar ActivationDemo.jar admin [ipAddress] [port]
Example:
$ java -jar ActivationDemo.jar admin localhost 8080
</pre>
Where ipAddress is the address of the Kaa node, where the administrative REST API is deployed.<br/><br/>
To run in the "client" mode, use the following command in the console:
<pre>
$ java -jar ActivationDemo.jar client
</pre>
To run in the "developer" mode, use the following command in the console:
<pre>
$ java -jar ActivationDemo.jar developer [ipAddress] [port]
</pre>
<h2>Playing around</h2>
Make sure that the Kaa Sandbox is up and running. When using the "Activation Demo" app in "admin" mode you will be able
to activate/deactivate any endoint associated with Activation app. Endpoint activation and deactivation are performed by updating server profile using REST API.<br/><br/>
"Activation Demo" app in "client" mode creates and registers one Kaa endpoint (per application instance). In this mode app displays the current state of the endpoint (active or inactive). Once the activation/deactivation is performed via the "admin" application, your endpoint will be served with the new configuration data according to the server-side endpoint profile change.<br/><br/>
Make sure that the Kaa Sandbox is up and running.
"Activation Demo" consists of the next modes:
1) In "admin" mode you will be able to do credentials provisioning (Device Management feature), revocation and registration. Before using "developer" or "client" mode, you need to create and register endpoint credentials via Kaa REST API.
Run app with the next command:
<pre>
$ java -jar ActivationDemo.jar admin [kaa_hostname] 8080
</pre>
Then choose the first menu item by typing "1" and pressing "Enter".
Exit from application by typing "3" and pressing "Enter".
Now credentials was created and registered in Kaa. Corresponding "key.private" and "key.public" files are created.
Starting from now, you can use other modes.
2) In "developer" mode you will be able
to activate/deactivate any endpoint associated with Activation app. Endpoint activation and deactivation are performed by updating server profile using REST API.<br/><br/>
"Activation Demo" app in "client" mode creates and registers one Kaa endpoint (per application instance). In this mode app displays the current state of the endpoint (active or inactive). Once the activation/deactivation is performed via the "developer" application, your endpoint will be served with the new configuration data according to the server-side endpoint profile change.<br/>
<br/>
To understand better how this app works, you should navigate to the Kaa server administrative interface by clicking the "Administrative console" link at the top of your Sandbox window. Log in as a tenant developer (devuser / devuser123 by default), and go to the "Activation demo" application. Select "Schemas"->"Server-side EP profile". The app uses one schema version, which contains one value: "active" (boolean). The Kaa server uses this value to filter endpoints by their profile contents. Server-side endpoint profiles can be updated either via Admin Console, or via the REST API (which is done by the "Activation app" in the "admin" mode)<br/><br/>
Expand All @@ -52,7 +72,7 @@ Finally, it's time to see what determines the configuration data. Go to the "End
The endpoints are put into either "Active device group" or "Inactive device group" depending on the "active" variable value in the server profile. See the corresponding profile filters in the group details window. Each endpoint group defines its own configuration (active or inactive) - and when the server-side profile for some EP is changed, the EP is moved from one group to another and this results in updated configuration being pushed by the server to the corresponding EP.<br/><br/>
Please note that all features of the <a href="https://docs.kaaproject.org/display/KAA/Administration+UI+guide">Administrative UI</a> are also supported via the <a href="https://docs.kaaproject.org/display/KAA/Admin+REST+API">REST API</a>.
Please note that all features of the <a href="http://docs.kaaproject.org/display/KAA/Administration+UI+guide">Administrative UI</a> are also supported via the <a href="http://docs.kaaproject.org/display/KAA/Admin+REST+API">REST API</a>.
<h2>What's next?</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,20 @@

package org.kaaproject.kaa.demo.activation;

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.*;
import org.kaaproject.kaa.client.channel.IPTransportInfo;
import org.kaaproject.kaa.client.configuration.base.ConfigurationListener;
import org.kaaproject.kaa.client.configuration.base.SimpleConfigurationStorage;
import org.kaaproject.kaa.client.profile.ProfileContainer;
import org.kaaproject.kaa.common.TransportType;
import org.kaaproject.kaa.common.dto.EndpointGroupDto;
import org.kaaproject.kaa.common.dto.EndpointProfileDto;
import org.kaaproject.kaa.demo.activation.model.DeviceState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.kaaproject.kaa.demo.activation.utils.AdminClientManager;
import org.kaaproject.kaa.demo.activation.utils.Utils;
import org.kaaproject.kaa.schema.system.EmptyData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Base64;
import java.util.HashMap;
Expand All @@ -54,29 +53,42 @@ public static void main(String[] args) throws InterruptedException {
LOG.info("Possible options:");
LOG.info(" java -jar ActivationDemo.jar client");
LOG.info(" java -jar ActivationDemo.jar admin host [port]");
LOG.info(" java -jar ActivationDemo.jar developer host [port]");
return;
}

String mode = args[0];
switch (mode) {
case "admin":
if (args.length < 2) {
}
if (args.length == 2) {
AdminClientManager.init(args[1]);
} else if (args.length == 3) {
AdminClientManager.init(args[1], Integer.valueOf(args[2]));
} else {
LOG.info("ip/host is not specified or address is invalid");
return;
}
useAdminClient();
break;
case "client":
useKaaClient();
break;
default:
LOG.info("Invalid parameters. Please specify 'client' or 'admin'");
case "developer":
if (args.length < 2) {
}
if (args.length == 2) {
AdminClientManager.init(args[1]);
} else if (args.length == 3) {
AdminClientManager.init(args[1], Integer.valueOf(args[2]));
} else {
LOG.info("ip/host is not specified or address is invalid");
return;
}
useDeveloperClient();
break;
case "admin":
if (args.length < 2) {
}
if (args.length == 2) {
AdminClientManager.init(args[1], AdminClientManager.UserType.TENANT_ADMIN);
} else if (args.length == 3) {
AdminClientManager.init(args[1], Integer.valueOf(args[2]), AdminClientManager.UserType.TENANT_ADMIN);
} else {
LOG.info("ip/host is not specified or address is invalid");
return;
}
useAdminClient();
case "client":
useKaaClient();
break;
default:
LOG.info("Invalid parameters. Please specify 'client' or 'admin' or 'developer'");

}
}
Expand All @@ -100,7 +112,12 @@ public void onStarted() {
LOG.info("Device state: " + (config.getActive() ? "active" : "inactive"));
}
});

kaaClient.setProfileContainer(new ProfileContainer() {
@Override
public EmptyData getProfile() {
return new EmptyData();
}
});
/*
* Persist configuration in a local storage to avoid downloading it each
* time the Kaa client is started.
Expand All @@ -112,6 +129,7 @@ public void onStarted() {
* it is updated.
*/
kaaClient.addConfigurationListener(new ConfigurationListener() {
@Override
public void onConfigurationUpdate(DeviceType deviceType) {
LOG.info("Configuration was updated. New device state: " + (deviceType.getActive() ? "active" : "inactive"));
}
Expand All @@ -130,14 +148,35 @@ public void onConfigurationUpdate(DeviceType deviceType) {
kaaClient.stop();
}

private static void useAdminClient() {
private static void useAdminClient(){
LOG.info("Choose action by entering corresponding number:");
while (true){
LOG.info("\n1. Generate and provision endpoint credentials.\n2. Revoke endpoint " +
"credentials\n3. Exit");
switch(Utils.getUserInput()){
case "1":
generateAndProvisionKeys();
break;
case "2":
revokeCredentials();
break;
default:
System.exit(0);
}
}
}

private static void useDeveloperClient() {

Map<String, EndpointProfileDto> endpointProfiles = retrieveEndpointProfiles();
if (endpointProfiles.isEmpty()) {
LOG.info("There is no endpoints registered!");
return;
}
printAllEndpointProfiles(endpointProfiles);



for (;;) {
LOG.info("Specify endpoint profile id# you want to activate/deactivate or print 'exit' to exit");
String userInput = Utils.getUserInput();
Expand All @@ -156,6 +195,20 @@ private static void useAdminClient() {
}
}

private static void generateAndProvisionKeys(){
AdminClientManager clientManager = AdminClientManager.instance();
LOG.info("Going to generate and provision credentials");
clientManager.provideCredentials(APPLICATION_NAME, clientManager.generateKeyPair().getPublic().getEncoded());
}

private static void revokeCredentials(){
AdminClientManager clientManager = AdminClientManager.instance();
LOG.info("Enter ID of credentials that needs to be revoked:");
String credentialsId = Utils.getUserInput();
LOG.info("Going to revoke credentials");
clientManager.revokeCredentials(APPLICATION_NAME, credentialsId);
}

/**
* Retrieve all endpoint profiles associated with activation application
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,38 @@

import org.kaaproject.kaa.common.dto.*;
import org.kaaproject.kaa.common.dto.admin.AuthResultDto;
import org.kaaproject.kaa.common.dto.credentials.CredentialsDto;
import org.kaaproject.kaa.common.endpoint.security.KeyUtil;
import org.kaaproject.kaa.demo.activation.model.DeviceState;
import org.kaaproject.kaa.server.common.admin.AdminClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.security.KeyPair;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class AdminClientManager {

private static final Logger LOG = LoggerFactory.getLogger(AdminClientManager.class);

private static final String TENANT_DEV_USERNAME = "devuser";
private static final String TENANT_DEV_PASSWORD = "devuser123";

private static final String TENANT_ADMIN_USERNAME = "admin";
private static final String TENANT_ADMIN_PASSWORD = "admin123";

private static final String DEFAULT_LIMIT = "20";
private static final String DEFAULT_OFFSET = "0";
private static final int KAA_PORT = 8080;

private AdminClient adminClient;
private static AdminClientManager instance;
private UserType userType;

private AdminClientManager(String host, int port) {
private AdminClientManager(String host, int port, UserType userType) {
this.userType = userType;
adminClient = new AdminClient(host, port);
}

Expand All @@ -46,7 +58,15 @@ public static void init(String host) {
}

public static void init(String host, int port) {
instance = new AdminClientManager(host, port);
instance = new AdminClientManager(host, port, UserType.TENANT_DEVELOPER);
}

public static void init(String host, UserType userType){
init(host, KAA_PORT, userType);
}

public static void init(String host, int port, UserType userType){
instance = new AdminClientManager(host, port, userType);
}

public static AdminClientManager instance() {
Expand All @@ -56,6 +76,30 @@ public static AdminClientManager instance() {
return instance;
}

/**
* Generate public and private key pair
*
* @return Generated KeyPair
*/
public KeyPair generateKeyPair(){
return KeyUtil.generateKeyPair("./key.private", "./key.public");
}

public void provideCredentials(String applicationName, byte[] publicKey){
CredentialsDto credentialsDto = adminClient.provisionCredentials(getApplicationByName(applicationName).getApplicationToken(),
publicKey);
adminClient.provisionRegistration(getApplicationByName(applicationName).getApplicationToken(), credentialsDto
.getId(), 1, DeviceState.toJsonString(true));
LOG.debug("APP TOKEN: {}", getApplicationByName(applicationName).getApplicationToken());
LOG.info("Credentials with ID={} are now in status: {}", credentialsDto.getId(), credentialsDto.getStatus());
}

public void revokeCredentials(String applicationName, String credentialsId){
LOG.debug("APP TOKEN: {}", getApplicationByName(applicationName).getApplicationToken());
adminClient.revokeCredentials(getApplicationByName(applicationName).getApplicationToken(), credentialsId);
LOG.info("Credentials revoked.");
}

/**
* Do authorization check
*
Expand All @@ -76,7 +120,11 @@ public boolean checkAuth() {
*/
public void checkAuthorizationAndLogin() {
if (!checkAuth()) {
adminClient.login(TENANT_DEV_USERNAME, TENANT_DEV_PASSWORD);
if(UserType.TENANT_ADMIN.equals(userType)){
adminClient.login(TENANT_ADMIN_USERNAME, TENANT_ADMIN_PASSWORD);
}else {
adminClient.login(TENANT_DEV_USERNAME, TENANT_DEV_PASSWORD);
}
}
}

Expand Down Expand Up @@ -127,18 +175,18 @@ public ApplicationDto getApplicationByName(String applicationName) {
}

/**
* Get all endpoint groups associated with given application Id
* Get all endpoint groups associated with given application Token
*
* @param applicationId
* the application Id
* @param applicationToken
* the application Token
* @return list of endpoint groups
*/
public List<EndpointGroupDto> getEndpointGroups(String applicationId) {
public List<EndpointGroupDto> getEndpointGroups(String applicationToken) {
checkAuthorizationAndLogin();

List<EndpointGroupDto> endpointGroups = null;
try {
endpointGroups = adminClient.getEndpointGroups(applicationId);
endpointGroups = adminClient.getEndpointGroupsByAppToken(applicationToken);
} catch (Exception e) {
LOG.error("Exception has occurred: " + e.getMessage());
}
Expand Down Expand Up @@ -179,7 +227,7 @@ public List<EndpointGroupDto> getEndpointGroupsByApplicationName(String applicat
return null;
}

return getEndpointGroups(applicationDto.getId());
return getEndpointGroups(applicationDto.getApplicationToken());
}

/**
Expand All @@ -204,4 +252,9 @@ public Map<String, EndpointProfileDto> getEndpointProfiles(List<EndpointGroupDto
return endpointProfiles;
}

public enum UserType {
TENANT_ADMIN,
TENANT_DEVELOPER
}

}
Loading

0 comments on commit d4cf95d

Please sign in to comment.