IOT-2773 Add Introspection to Java
authorGeorge Nash <george.nash@intel.com>
Wed, 4 Oct 2017 23:36:35 +0000 (16:36 -0700)
committerRick Bell <richard.s.bell@intel.com>
Fri, 6 Oct 2017 16:19:11 +0000 (16:19 +0000)
This adds the ability to register the introspection file
to java applications.

The client_open callback function is miss named as
JniOcSecurity. This should probably be renamed
JniOcPersistantStorage or something similar.

The class was not renamed to avoid causing an
unforseen bug due to name change.

Bug: https://jira.iotivity.org/browse/IOT-2773
Change-Id: Ifd19ee4c4bfa91e6596d64976008b8d471e4f87a
Signed-off-by: George Nash <george.nash@intel.com>
12 files changed:
java/examples-java/simpleserver/SConscript
java/examples-java/simpleserver/src/main/assets/light_introspection.dat [new file with mode: 0644]
java/examples-java/simpleserver/src/main/assets/light_introspection.json [new file with mode: 0644]
java/examples-java/simpleserver/src/main/java/org/iotivity/base/examples/SimpleServer.java
java/iotivity-android/src/main/java/org/iotivity/base/OcPlatform.java
java/iotivity-android/src/main/java/org/iotivity/base/PlatformConfig.java
java/iotivity-java/src/main/java/org/iotivity/base/OcPlatform.java
java/iotivity-java/src/main/java/org/iotivity/base/PlatformConfig.java
java/jni/JniOcPlatform.cpp
java/jni/JniOcPlatform.h
java/jni/JniOcSecurity.cpp
java/jni/JniOcSecurity.h

index 60fd0f812b94962a4f799dcf20dff6037346aad0..ebf769368aa01f853d2b8de4e1d7ecbd91002573 100644 (file)
@@ -34,3 +34,4 @@ example_jar = jdk_env.Jar(target='simpleserver.jar',
 jdk_env.Install("../..", example_jar)
 if jdk_env.get('SECURED') == '1':
     jdk_env.Install(target="../..", source=['src/main/assets/oic_svr_db_server.dat'])
+    jdk_env.Install(target="../..", source=['src/main/assets/light_introspection.dat'])
diff --git a/java/examples-java/simpleserver/src/main/assets/light_introspection.dat b/java/examples-java/simpleserver/src/main/assets/light_introspection.dat
new file mode 100644 (file)
index 0000000..5bafcf8
--- /dev/null
@@ -0,0 +1 @@
+¿gswaggerc2.0dinfo¿etitleqmy_example_devicegversionqmy device versionÿgschemes\9fdhttpÿhconsumes\9fpapplication/jsonÿhproduces\9fpapplication/jsonÿepaths¿g/switch¿cget¿jparameters\9f¿dnamebifbinequerykdescription`denum\9fhoic.if.aooic.if.baselineÿdtypefstringÿÿiresponses¿c200¿kdescription`fschema¿d$refx\1a#/definitions/BinarySwitchÿÿÿÿdpost¿jparameters\9f¿dnamebifbinequerykdescription`denum\9fhoic.if.aooic.if.baselineÿdtypefstringÿ¿dnamedbodybindbodyhrequiredôfschema¿d$refx\1a#/definitions/BinarySwitchÿÿÿiresponses¿c200¿kdescription`fschema¿d$refx\1a#/definitions/BinarySwitchÿÿÿÿÿk/brightness¿cget¿jparameters\9f¿dnamebifbinequerykdescription`denum\9fhoic.if.aooic.if.baselineÿdtypefstringÿÿiresponses¿c200¿kdescription`fschema¿d$refx\18#/definitions/Brightnessÿÿÿÿdpost¿jparameters\9f¿dnamebifbinequerykdescription`denum\9fhoic.if.aooic.if.baselineÿdtypefstringÿ¿dnamedbodybindbodyhrequiredôfschema¿d$refx\18#/definitions/Brightnessÿÿÿiresponses¿c200¿kdescription`fschema¿d$refx\18#/definitions/Brightnessÿÿÿÿÿÿkdefinitions¿lBinarySwitch¿dtypefobjecthrequired\9fbidÿjproperties¿evalue¿dtypegbooleankdescriptiontStatus of the switchÿbrt¿dtypeearrayeitems\9f¿dtypefstringimaxLength\18@ÿÿhminItems\ 1kdescriptionmResource TypehreadOnlyõgdefault\9fsoic.r.switch.binaryÿÿbif¿dtypeearraykdescriptionx,The interface set supported by this resourcehreadOnlyõeitems¿dtypefstringdenum\9fooic.if.baselinehoic.if.aÿÿÿap¿dtypegintegerkdescriptionx-Bitmap indicating observable and discoverablehreadOnlyõÿan¿dtypefstringkdescriptionx\1dFriendly name of the resourcehreadOnlyõÿbid¿dtypefstringkdescriptionx%Instance ID of this specific resourcehreadOnlyõÿerange¿dtypeearraykdescriptionx&The valid range for the value PropertyhreadOnlyõhminItems\ 2hmaxItems\ 2eitems¿dtypefnumberÿÿÿÿjBrightness¿dtypefobjecthrequired\9fbidÿjproperties¿ibrighness¿dtypegintegerkdescriptionx*Current sensed or set value for Brightnessÿbrt¿dtypeearrayeitems\9f¿dtypefstringimaxLength\18@ÿÿhminItems\ 1kdescriptionmResource TypehreadOnlyõgdefault\9fvoic.r.light.brightnessÿÿbif¿dtypeearraykdescriptionx,The interface set supported by this resourcehreadOnlyõeitems¿dtypefstringdenum\9fooic.if.baselinehoic.if.aÿÿÿap¿dtypegintegerkdescriptionx-Bitmap indicating observable and discoverablehreadOnlyõÿan¿dtypefstringkdescriptionx\1dFriendly name of the resourcehreadOnlyõÿbid¿dtypefstringkdescriptionx%Instance ID of this specific resourcehreadOnlyõÿerange¿dtypeearraykdescriptionx&The valid range for the value PropertyhreadOnlyõhminItems\ 2hmaxItems\ 2eitems¿dtypefnumberÿÿÿÿÿÿ
\ No newline at end of file
diff --git a/java/examples-java/simpleserver/src/main/assets/light_introspection.json b/java/examples-java/simpleserver/src/main/assets/light_introspection.json
new file mode 100644 (file)
index 0000000..baab37f
--- /dev/null
@@ -0,0 +1,272 @@
+{\r
+    "swagger": "2.0",\r
+    "info": {\r
+      "title": "my_example_device",\r
+      "version": "my device version"\r
+    },\r
+\r
+\r
+    "schemes": [\r
+        "http"\r
+    ],\r
+    "consumes": [\r
+        "application/json"\r
+    ],\r
+    "produces": [\r
+        "application/json"\r
+    ],\r
+    "paths": {\r
+       "/switch": {\r
+\r
+          "get": {\r
+\r
+\r
+            "parameters": [\r
+               {\r
+                 "name": "if",\r
+                 "in": "query",\r
+                 "description": "",\r
+                 "enum": [ "oic.if.a","oic.if.baseline" ],\r
+\r
+                 "type": "string"\r
+                }\r
+            ],\r
+            "responses": {\r
+              "200" : {\r
+                  "description" : "",\r
+                  "schema" :\r
+                  {\r
+                    "$ref": "#/definitions/BinarySwitch"\r
+                  }\r
+               }\r
+            }\r
+\r
+           },\r
+\r
+          "post": {\r
+\r
+\r
+            "parameters": [\r
+               {\r
+                 "name": "if",\r
+                 "in": "query",\r
+                 "description": "",\r
+                 "enum": [ "oic.if.a","oic.if.baseline" ],\r
+\r
+                 "type": "string"\r
+                }\r
+                 ,{\r
+                  "name": "body",\r
+                  "in": "body",\r
+                  "required": false,\r
+                   "schema" :\r
+                  {\r
+                    "$ref": "#/definitions/BinarySwitch"\r
+                  }\r
+\r
+                }\r
+            ],\r
+            "responses": {\r
+              "200" : {\r
+                  "description" : "",\r
+                   "schema" :\r
+                  {\r
+                    "$ref": "#/definitions/BinarySwitch"\r
+                  }\r
+\r
+               }\r
+            }\r
+          }\r
+        },\r
+       "/brightness": {\r
+\r
+          "get": {\r
+\r
+\r
+            "parameters": [\r
+               {\r
+                 "name": "if",\r
+                 "in": "query",\r
+                 "description": "",\r
+                 "enum": [ "oic.if.a","oic.if.baseline" ],\r
+\r
+                 "type": "string"\r
+                }\r
+            ],\r
+            "responses": {\r
+              "200" : {\r
+                  "description" : "",\r
+                 "schema" :\r
+                  {\r
+                    "$ref": "#/definitions/Brightness"\r
+                  }\r
+               }\r
+            }\r
+\r
+           },\r
+\r
+          "post": {\r
+\r
+\r
+            "parameters": [\r
+               {\r
+                 "name": "if",\r
+                 "in": "query",\r
+                 "description": "",\r
+                 "enum": [ "oic.if.a","oic.if.baseline" ],\r
+\r
+                 "type": "string"\r
+                }\r
+                 ,{\r
+                  "name": "body",\r
+                  "in": "body",\r
+                  "required": false,\r
+                 "schema" :\r
+                  {\r
+                    "$ref": "#/definitions/Brightness"\r
+                  }\r
+                }\r
+            ],\r
+            "responses": {\r
+              "200" : {\r
+                  "description" : "",\r
+                 "schema" :\r
+                  {\r
+                    "$ref": "#/definitions/Brightness"\r
+                  }\r
+\r
+               }\r
+            }\r
+\r
+          }\r
+        }\r
+    },\r
+    "definitions":\r
+    {\r
+        "BinarySwitch": {\r
+           "type": "object",\r
+           "required": [\r
+             "id"\r
+           ],\r
+           "properties":  {\r
+               "value": {\r
+                  "type": "boolean",\r
+                  "description": "Status of the switch"\r
+                },\r
+                "rt": {\r
+                "type": "array",\r
+                "items" : [\r
+                  {\r
+                    "type" : "string",\r
+                    "maxLength": 64\r
+                  }\r
+                ],\r
+                "minItems" : 1,\r
+                "description": "Resource Type",\r
+                "readOnly" : true,\r
+                "default" : [ "oic.r.switch.binary" ]\r
+                },\r
+                "if": {\r
+                    "type": "array",\r
+                    "description": "The interface set supported by this resource",\r
+                    "readOnly" : true,\r
+                    "items": {\r
+                        "type": "string",\r
+                        "enum": [\r
+                            "oic.if.baseline",\r
+                            "oic.if.a"\r
+                        ]\r
+                    }\r
+                },\r
+                "p": {\r
+                    "type": "integer",\r
+                    "description": "Bitmap indicating observable and discoverable",\r
+                    "readOnly" : true\r
+                },\r
+                "n": {\r
+                    "type": "string",\r
+                    "description": "Friendly name of the resource",\r
+                    "readOnly" : true\r
+                },\r
+                "id": {\r
+                    "type": "string",\r
+                    "description": "Instance ID of this specific resource",\r
+                    "readOnly" : true\r
+                },\r
+                "range": {\r
+                    "type": "array",\r
+                    "description": "The valid range for the value Property",\r
+                    "readOnly" : true,\r
+                    "minItems": 2,\r
+                    "maxItems": 2,\r
+                    "items": {\r
+                        "type": "number"\r
+                    }\r
+                }\r
+            }\r
+        },\r
+        "Brightness": {\r
+           "type": "object",\r
+           "required": [\r
+             "id"\r
+           ],\r
+           "properties":  {\r
+               "brighness": {\r
+                  "type": "integer",\r
+                  "description": "Current sensed or set value for Brightness"\r
+                },\r
+                "rt": {\r
+                "type": "array",\r
+                "items" : [\r
+                  {\r
+                    "type" : "string",\r
+                    "maxLength": 64\r
+                  }\r
+                ],\r
+                "minItems" : 1,\r
+                "description": "Resource Type",\r
+                "readOnly" : true,\r
+                "default" : [ "oic.r.light.brightness" ]\r
+                },\r
+                "if": {\r
+                    "type": "array",\r
+                    "description": "The interface set supported by this resource",\r
+                    "readOnly" : true,\r
+                    "items": {\r
+                        "type": "string",\r
+                        "enum": [\r
+                            "oic.if.baseline",\r
+                            "oic.if.a"\r
+                        ]\r
+                    }\r
+                },\r
+                "p": {\r
+                    "type": "integer",\r
+                    "description": "Bitmap indicating observable and discoverable",\r
+                    "readOnly" : true\r
+                },\r
+                "n": {\r
+                    "type": "string",\r
+                    "description": "Friendly name of the resource",\r
+                    "readOnly" : true\r
+                },\r
+                "id": {\r
+                    "type": "string",\r
+                    "description": "Instance ID of this specific resource",\r
+                    "readOnly" : true\r
+                },\r
+                "range": {\r
+                    "type": "array",\r
+                    "description": "The valid range for the value Property",\r
+                    "readOnly" : true,\r
+                    "minItems": 2,\r
+                    "maxItems": 2,\r
+                    "items": {\r
+                        "type": "number"\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+}\r
index e84d678588cc016a9ad84b4ac87c39394165901d..b766ff166780709a04115568fc59ed2fed5a12e4 100644 (file)
@@ -63,7 +63,8 @@ public class SimpleServer {
                 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
                 0,         // Uses randomly available port
                 QualityOfService.LOW,
-                path + "/oic_svr_db_server.dat"
+                path + "/oic_svr_db_server.dat",
+                path + "/light_introspection.dat"
         );
 
         msg("Configuring platform.");
index af4464e57d843d59321e48d5de5965aa53063070..8c2cd6a7c1ed72125984cbfefdecdacb3d193357 100644 (file)
@@ -103,6 +103,7 @@ public final class OcPlatform {
                     platformConfig.getPort(),
                     platformConfig.getQualityOfService().getValue(),
                     platformConfig.getSvrDbPath(),
+                    platformConfig.getIntrospectionPath(),
                     platformConfig.getAvailableTransportType()
             );
 
@@ -122,6 +123,7 @@ public final class OcPlatform {
                                          int port,
                                          int qualityOfService,
                                          String dbPath,
+                                         String introspectionPath,
                                          int transport);
 
     /**
index d1cab3d8833d0c7e577e884374cca40200fd07e8..26c4a43ac3a3305ef4dcfacf96165b97f2fd896d 100644 (file)
@@ -38,7 +38,40 @@ public class PlatformConfig {
     private QualityOfService mQualityOfService;
     private String mSvrDbPath; //TODO: Instead of SVRDB file, it should be Persistent Storage.
                               //this is only for 0.9.2
+    private String mIntrospectPath;
     private int mTransportType;
+
+    /**
+     * @param serviceType        indicate IN_PROC or OUT_OF_PROC
+     * @param modeType           indicate whether we want to do server, client or both
+     * @param ipAddress          ip address of server
+     *                           if you specify 0.0.0.0 : it listens on any interface
+     * @param port               port of server
+     *                           if you specifiy 0 : next available random port is used
+     *                           if you specify 5683 : client discovery can work even if they don't
+     *                           specify port
+     * @param qualityOfService   quality of service
+     * @param dbPath             Persistant storage file for SVR Database.
+     * @param introspectionPath  Persistant storage file for introspection data.
+     */
+    public PlatformConfig(
+                          ServiceType serviceType,
+                          ModeType modeType,
+                          String ipAddress,
+                          int port,
+                          QualityOfService qualityOfService,
+                          String dbPath,
+                          String introspectionPath) {
+        this.mServiceType = serviceType;
+        this.mModeType = modeType;
+        this.mIpAddress = ipAddress;
+        this.mPort = port;
+        this.mQualityOfService = qualityOfService;
+        this.mSvrDbPath = dbPath;
+        this.mIntrospectPath = introspectionPath;
+        this.mTransportType = 0;
+    }
+
     /**
      * @param activity         app activity
      * @param context          app context
@@ -168,6 +201,10 @@ public class PlatformConfig {
         return mSvrDbPath;
     }
 
+    public String getIntrospectionPath() {
+        return mIntrospectPath;
+    }
+
     public Activity getActivity() {
         return mActivity;
     }
index b00b93ece088370aaf591a4333a2f236bed05840..4739ddaae2e9c229c5232d41714f1c1c414ada78 100644 (file)
@@ -97,6 +97,7 @@ public final class OcPlatform {
                     platformConfig.getPort(),
                     platformConfig.getQualityOfService().getValue(),
                     platformConfig.getSvrDbPath(),
+                    platformConfig.getIntrospectionPath(),
                     platformConfig.getAvailableTransportType()
             );
 
@@ -116,6 +117,7 @@ public final class OcPlatform {
                                          int port,
                                          int qualityOfService,
                                          String dbPath,
+                                         String introspectionPath,
                                          int transport);
 
     /**
index 8d06aae0801640ca139306938516dba1001cecb6..99e655a9ddcf37278ffb361c5f148df7f144dc5d 100644 (file)
@@ -35,7 +35,40 @@ public class PlatformConfig {
     private QualityOfService mQualityOfService;
     private String mSvrDbPath; //TODO: Instead of SVRDB file, it should be Persistent Storage.
                               //this is only for 0.9.2
+    private String mIntrospectPath;
     private int mTransportType;
+
+    /**
+     * @param serviceType        indicate IN_PROC or OUT_OF_PROC
+     * @param modeType           indicate whether we want to do server, client or both
+     * @param ipAddress          ip address of server
+     *                           if you specify 0.0.0.0 : it listens on any interface
+     * @param port               port of server
+     *                           if you specifiy 0 : next available random port is used
+     *                           if you specify 5683 : client discovery can work even if they don't
+     *                           specify port
+     * @param qualityOfService   quality of service
+     * @param dbPath             Persistant storage file for SVR Database.
+     * @param introspectionPath  Persistant storage file for introspection data.
+     */
+    public PlatformConfig(
+                          ServiceType serviceType,
+                          ModeType modeType,
+                          String ipAddress,
+                          int port,
+                          QualityOfService qualityOfService,
+                          String dbPath,
+                          String introspectionPath) {
+        this.mServiceType = serviceType;
+        this.mModeType = modeType;
+        this.mIpAddress = ipAddress;
+        this.mPort = port;
+        this.mQualityOfService = qualityOfService;
+        this.mSvrDbPath = dbPath;
+        this.mIntrospectPath = introspectionPath;
+        this.mTransportType = 0;
+    }
+
     /**
      * @param serviceType      indicate IN_PROC or OUT_OF_PROC
      * @param modeType         indicate whether we want to do server, client or both
@@ -109,6 +142,10 @@ public class PlatformConfig {
         return mSvrDbPath;
     }
 
+    public String getIntrospectionPath() {
+        return mIntrospectPath;
+    }
+    
     public void setAvailableTransportType(EnumSet<OcConnectivityType> type) {
         for (OcConnectivityType connType : OcConnectivityType.values()) {
             if (type.contains(connType))
index 799f1b35492d7602a7012e619f3fc03603ec8b78..94c426bb3dbeac914e832e59e697fcfadba2540c 100644 (file)
@@ -471,17 +471,18 @@ void RemoveOnObserveListener(JNIEnv* env, jobject jListener)
 /*
 * Class:     org_iotivity_base_OcPlatform
 * Method:    configure
-* Signature: (IILjava/lang/String;IILjava/lang/String;I)V
+* Signature: (IILjava/lang/String;IILjava/lang/String;Ljava/lang/String;I)V
 */
 JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
 (JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort,
- jint jQOS, jstring jDbPath, jint jTransport)
+ jint jQOS, jstring jDbPath, jstring jIntrospectionPath, jint jTransport)
 {
     OC_UNUSED(clazz);
     LOGI("OcPlatform_configure");
 
     std::string ipAddress;
     std::string dbfile;
+    std::string introspectionfile;
     if (jIpAddress)
     {
         ipAddress = env->GetStringUTFChars(jIpAddress, nullptr);
@@ -491,6 +492,11 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
         dbfile = env->GetStringUTFChars(jDbPath, nullptr);
         JniOcSecurity::StoreDbPath(dbfile);
     }
+    if (jIntrospectionPath)
+    {
+        introspectionfile = env->GetStringUTFChars(jIntrospectionPath, nullptr);
+        JniOcSecurity::StoreIntrospection(introspectionfile);
+    }
     uint16_t port = 0;
     if (jPort > 0)
     {
index 17f741e67b3e475fe9af4dceaadc4d3f72a0900d..a3362b7ded015ce34e0a27a24839ed926b400b41 100644 (file)
@@ -70,10 +70,10 @@ extern "C" {
     /*
     * Class:     org_iotivity_base_OcPlatform
     * Method:    configure
-    * Signature: (IILjava/lang/String;IILjava/lang/String;I)V
+    * Signature: (IILjava/lang/String;IILjava/lang/String;Ljava/lang/String;I)V
     */
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
-        (JNIEnv *, jclass, jint, jint, jstring, jint, jint, jstring, jint);
+        (JNIEnv *, jclass, jint, jint, jstring, jint, jint, jstring, jstring, jint);
 
     /*
     * Class:     org_iotivity_base_OcPlatform
index a0d8dae3e7863acd667796eb8c622b458ddf650b..3c8222f9b2f67b88199e95b676918e678a651d6e 100644 (file)
@@ -36,17 +36,23 @@ namespace OC {
         return s_dbPath;
     }
 
+    string& JniOcSecurity::store_introspection()
+    {
+        static string s_introspectionPath;
+        return s_introspectionPath;
+    }
     void JniOcSecurity::StoreDbPath(const string &path)
     {
         store_path() = path;
     }
 
+    void JniOcSecurity::StoreIntrospection(const string &path)
+    {
+        store_introspection() = path;
+    }
+
     OCPersistentStorage* JniOcSecurity::getOCPersistentStorage()
     {
-        if (store_path().empty())
-        {
-            return nullptr;
-        }
         static OCPersistentStorage s_ps { &JniOcSecurity::client_open, fread,
             fwrite, fclose, unlink };
         return &s_ps;
@@ -54,11 +60,16 @@ namespace OC {
 
     FILE* JniOcSecurity::client_open(const char *path, const char *mode)
     {
-        if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME))
+        if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME) && !store_path().empty())
         {
             LOGI("Opening SVR Database file '%s' with mode '%s'\n", store_path().c_str(), mode);
             return fopen(store_path().c_str(), mode); 
         }
+        else if (0 == strcmp(path, OC_INTROSPECTION_FILE_NAME) && !store_introspection().empty())
+        {
+            LOGI("Opening introspection file '%s' with mode '%s'\n", store_path().c_str(), mode);
+            return fopen(store_introspection().c_str(), mode);
+        }
         else
         {
             return fopen(path, mode);
index 6afbd77fc8df5a4cb93d131e8a27b14a7d9a5b27..c52de2d93a6e4b68c2c145abb85bf4eb670d98ee 100644 (file)
@@ -38,7 +38,9 @@ namespace OC
             static FILE* client_open(const char*, const char*);
         public:
             static std::string& store_path(void);
+            static std::string& store_introspection();
             static void StoreDbPath(const std::string&);
+            static void StoreIntrospection(const std::string&);
             static OCPersistentStorage* getOCPersistentStorage(void);
     };
 }