Skip to content

Commit b7a1b36

Browse files
Java binding implementation and tests.
1 parent 217bf4e commit b7a1b36

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+6651
-181
lines changed

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ c/common/tools/macro_utils_h_generator/macro_utils_h_generator.exe
187187
**/java/**/*.iml
188188
**/java/**/*dependency-reduced-pom.xml
189189
tools/jenkins-cli.jar
190+
*.class
191+
*.jar
192+
**/target/
193+
*.iml
190194

191195
# Node.js
192196
**/.settings/
@@ -199,7 +203,7 @@ typings/**
199203

200204
# ignore cmake build folder
201205
.cmake/**
202-
build/**
206+
*build/**
203207

204208
# ignore Atom Editor files
205209
.atom-build.json

CMakeLists.txt

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
#Copyright (c) Microsoft. All rights reserved.
2+
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
#this is CMakeLists.txt for root
15
cmake_minimum_required(VERSION 2.8.11)
26
project(azure_iot_gateway_sdk)
37

48
#the following variables are project-wide and can be used with cmake-gui
59
option(run_e2e_tests "set run_e2e_tests to ON to run e2e tests (default is OFF) [if possible, they are always build]" OFF)
610
option(install_executables "should cmake run cmake's install function (that includes dynamic link libraries) [it does for yocto]" OFF)
11+
option(enable_java_binding "set enable_java_binding to ON to enable building of Java binding (default is OFF)" OFF)
712

813
option(run_as_a_service "Flags that we have the goal of running gateway as a service for samples and OS that supports it." OFF)
914

@@ -99,4 +104,6 @@ include_directories(${GW_INC})
99104

100105
add_subdirectory(modules)
101106

102-
add_subdirectory(samples)
107+
add_subdirectory(samples)
108+
109+
add_subdirectory(bindings)

bindings/CMakeLists.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#Copyright (c) Microsoft. All rights reserved.
2+
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
cmake_minimum_required(VERSION 2.8.11)
5+
#this is CMakeLists for the bindings
6+
7+
if(${enable_java_binding})
8+
add_subdirectory(java)
9+
endif()

bindings/java/CMakeLists.txt

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#Copyright (c) Microsoft. All rights reserved.
2+
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
cmake_minimum_required(VERSION 2.8.11)
5+
#this is CMakeLists for java binding
6+
7+
# Check if the environment variables NODE_INCLUDE and NODE_LIB exist
8+
if(
9+
(NOT (DEFINED ENV{JAVA_HOME}))
10+
)
11+
message(FATAL_ERROR "Environment variable JAVA_HOME is not defined. Please define "
12+
"JAVA_HOME to point to the location of the JDK.")
13+
endif()
14+
15+
set(java_module_host_manager_sources
16+
./src/java_module_host_manager.c
17+
)
18+
19+
set(java_module_host_manager_headers
20+
./inc/java_module_host_manager.h
21+
)
22+
23+
set(java_module_host_sources
24+
./src/java_module_host.c
25+
${java_module_host_manager_sources}
26+
)
27+
28+
set(java_module_host_headers
29+
./inc/message_bus_proxy.h
30+
./inc/java_module_host_common.h
31+
./inc/java_module_host.h
32+
${java_module_host_manager_headers}
33+
)
34+
35+
set(java_module_host_static_sources
36+
${java_module_host_sources}
37+
)
38+
39+
set(java_module_host_static_headers
40+
${java_module_host_headers}
41+
)
42+
43+
set(java_module_host_hl_sources
44+
./src/java_module_host_hl.c
45+
)
46+
47+
set(java_module_host_hl_headers
48+
./inc/message_bus_proxy.h
49+
./inc/java_module_host_hl.h
50+
)
51+
52+
set(java_module_host_hl_static_sources
53+
${java_module_host_hl_sources}
54+
)
55+
56+
set(java_module_host_hl_static_headers
57+
${java_module_host_hl_headers}
58+
)
59+
60+
if(WIN32)
61+
set(java_include_dirs
62+
$ENV{JAVA_HOME}/include
63+
$ENV{JAVA_HOME}/include/win32
64+
)
65+
set(java_link_dirs
66+
$ENV{JAVA_HOME}/lib
67+
$ENV{JAVA_HOME}/jre/bin/server
68+
)
69+
set(java_libs
70+
$ENV{JAVA_HOME}/lib/jvm.lib
71+
)
72+
elseif(LINUX)
73+
set(java_include_dirs
74+
$ENV{JAVA_HOME}/include
75+
$ENV{JAVA_HOME}/include/linux
76+
)
77+
set(java_link_dirs
78+
$ENV{JAVA_HOME}/jre/lib/amd64/server
79+
)
80+
set(java_libs
81+
$ENV{JAVA_HOME}/jre/lib/amd64/server/libjvm.so
82+
)
83+
endif()
84+
85+
set(LIBS ${java_libs} gateway)
86+
87+
include_directories(./inc ${IOTHUB_CLIENT_INC_FOLDER})
88+
include_directories(${GW_INC})
89+
include_directories(${java_include_dirs})
90+
link_directories(${java_link_dirs})
91+
92+
#this builds the java_module_host dynamic library
93+
add_library(java_module_host MODULE ${java_module_host_headers} ${java_module_host_sources})
94+
target_link_libraries(java_module_host ${LIBS})
95+
96+
#this build the java_module_host static library
97+
add_library(java_module_host_static ${java_module_host_static_headers} ${java_module_host_static_sources})
98+
target_compile_definitions(java_module_host_static PRIVATE BUILD_MODULE_TYPE_STATIC)
99+
target_link_libraries(java_module_host_static ${LIBS})
100+
101+
#this builds the java_module_host_hl dynamic library (by default it uses java_module_host linked statically)
102+
add_library(java_module_host_hl MODULE ${java_module_host_hl_headers} ${java_module_host_hl_sources})
103+
target_link_libraries(java_module_host_hl java_module_host_static ${LIBS})
104+
105+
#this builds the java_module_host_hl static library (by default it uses the java_module_host linked statically)
106+
add_library(java_module_host_hl_static ${java_module_host_hl_static_headers} ${java_module_host_hl_static_sources})
107+
target_compile_definitions(java_module_host_hl_static PRIVATE BUILD_MODULE_TYPE_STATIC)
108+
target_link_libraries(java_module_host_hl_static java_module_host_static ${LIBS})
109+
110+
linkSharedUtil(java_module_host)
111+
linkSharedUtil(java_module_host_static)
112+
linkSharedUtil(java_module_host_hl)
113+
linkSharedUtil(java_module_host_hl_static)
114+
115+
add_module_to_solution(java_module_host)
116+
117+
add_subdirectory(tests)
118+
119+
if(install_executables)
120+
install(TARGETS java_module_host LIBRARY DESTINATION lib)
121+
install(TARGETS java_module_host_hl LIBRARY DESTINATION lib)
122+
endif()

bindings/java/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#Java Binding
2+
3+
This document provides everything one might need to use and understand the Java Binding mechanism used by the **Microsoft Azure IoT Gateway SDK**.
4+
5+
##Contents
6+
7+
1. [**Dev box setup** - steps necessary to build modules in Java and run samples](../../doc/java_devbox_setup.md)
8+
2. [**High Level Design** - detailed description of the Java binding mechanism](devdoc/java_binding_hld.md)
9+
3. [**How-To Guide** - guide on how to write your own Java modules](../../doc/java_how_to.md)

bindings/java/devdoc/Design.png

-13.3 KB
Binary file not shown.

bindings/java/devdoc/Design2.png

-20.7 KB
Binary file not shown.

bindings/java/devdoc/HLD1.png

15.5 KB
Loading

bindings/java/devdoc/HLD2.png

23.9 KB
Loading

bindings/java/devdoc/java_binding_hld.md

+21-52
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ JVM will interact with the native gateway core.
1111
Design
1212
------
1313

14-
![](Design.png)
14+
![](HLD1.png)
1515

1616
Java Module Host
1717
----------------
@@ -21,7 +21,8 @@ The **Java Module Host** is a C module that
2121
1. Creates the JVM (Java Virtual Machine) the first time a Java module is
2222
attempting to connect to the gateway.
2323

24-
2. Brokers calls **to** the Java module (create, destroy, receive).
24+
2. Brokers calls **to** the Java module (create, destroy, receive) and
25+
facilitates publishing **from** the Java module to the native Message Bus.
2526

2627
Because [JNI](http://docs.oracle.com/javase/8/docs/technotes/guides/jni/) (Java
2728
Native Interface) only allows one JVM instance per process, the **Java Module
@@ -30,14 +31,15 @@ Subsequent attempts to load additional Java modules will load and run those
3031
modules in the same JVM that was originally created. The JSON configuration for
3132
this module will be similar to the configuration for the Node Module Host:
3233

33-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ json
34+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ json
3435
{
3536
"modules": [
3637
{
3738
"module name": "java_poller",
38-
"module path": "/path/to/java_module_host.so|.dll",
39+
"module path": "/path/to/java_module_host_hl.so|.dll",
3940
"args": {
4041
"class_path": "/path/to/relevant/class/files",
42+
"library_path": "/path/to/dir/with/java_module_host_hl.so|.dll"
4143
"class_name": "Poller",
4244
"args": {
4345
"frequency": 30
@@ -57,35 +59,6 @@ this module will be similar to the configuration for the Node Module Host:
5759
}
5860
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5961

60-
or:
61-
62-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ json
63-
{
64-
"modules": [
65-
{
66-
"module name": "java_poller",
67-
"module path": "/path/to/java_module_host.so|.dll",
68-
"tags": ["java"],
69-
"args": {
70-
"class_path": "/path/to/relevant/class/files",
71-
"class_name": "Poller",
72-
"args": {
73-
"frequency": 30
74-
}
75-
}
76-
}
77-
]
78-
}
79-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
80-
81-
*You might have noticed a tags section. When processing the input JSON
82-
configuration file, the Gateway SDK will insert everything within the JSON
83-
object for the specified tag within the tags array into the args section for the
84-
corresponding module (please see \_\_\_\_ for more detailed guidance on
85-
constructing a JSON configuration).*
86-
87-
 
88-
8962
As usual, the `module path` specifies the path to the DLL/SO that implements the
9063
**Java Module Host**. The `args.class_path` specifies the path to the directory
9164
where all necessary Java class files are located, `args.class_name` is the name
@@ -101,20 +74,19 @@ The **Java Module Host** will handle calling into the gateway module written in
10174
Java when necessary, therefore each module written in Java must implement the
10275
same `IGatewayModule` interface shown below:
10376

104-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ java
77+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ java
10578
public interface IGatewayModule {
10679

10780
/**
10881
* The create method is called by the subclass constructor when the native
10982
* Gateway creates the Module. The constructor
11083
* should save both the {@code moduleAddr} and {@code bus} parameters.
11184
*
112-
* @param moduleAddr The address of the native module pointer
11385
* @param bus The {@link MessageBus} to which this Module belongs
11486
* @param configuration The configuration for this module represented as a JSON
11587
* string
11688
*/
117-
void create(long moduleAddr, MessageBus bus, String configuration);
89+
void create(MessageBus bus, String configuration);
11890

11991
/**
12092
* The destroy method is called on a {@link GatewayModule} before it is about
@@ -134,9 +106,9 @@ public interface IGatewayModule {
134106
* The destroy() and receive() methods are guaranteed to not be called
135107
* simultaneously.
136108
*
137-
* @param buffer The message content
109+
* @param source The message content
138110
*/
139-
void receive(byte[] buffer);
111+
void receive(byte[] source);
140112
}
141113
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142114

@@ -163,20 +135,19 @@ gateway, it:
163135
- Constructs a `MessageBus` Java object using the `MESSAGE_BUS_HANDLE`.
164136

165137
- Finds the module’s class with the name specified by the `args.class_name`,
166-
invokes the constructor passing in the `MODULE_HANDLE`, `MessageBus` object,
167-
the JSON args string for that module, and creates the Java module.
138+
invokes the constructor passing in the `MessageBus` object and the JSON args
139+
string for that module, and creates the Java module.
168140

169-
- Gets a global reference to the newly created `GatewayModule` object to be saved by
170-
the `JAVA_MODULE_HOST_HANDLE`.
141+
- Gets a global reference to the newly created `GatewayModule` object to be
142+
saved by the `JAVA_MODULE_HOST_HANDLE`.
171143

172144
### Module\_Receive
173145

174146
When the **Java Module Host**’s `Module_Receive` function is invoked by the
175147
gateway, it:
176148

177149
- Serializes the `MESSAGE_HANDLE` content and properties and invokes the
178-
`receive` method implemented by the Java module with the `MODULE_HANDLE` and
179-
the serialized message.
150+
`receive` method implemented by the Java module with the serialized message.
180151

181152
### Module\_Destroy
182153

@@ -194,12 +165,10 @@ gateway, it:
194165
Communication **FROM** the Java module
195166
--------------------------------------
196167

197-
As previously mentioned, the **Java Module Host** will only handle communication
198-
from the native gateway process **to** the Java module. In order to communicate
199-
**from** the Java module to the native gateway process, the `MessageBus` class
200-
must be used. The `MessageBus` class provides a method to publish messages onto
201-
the native Message Bus and loads a dynamic library that implements expected
202-
functions for publishing onto the native Message Bus. So, the above diagram
203-
should look a bit more like this:
168+
In order to communicate **from** the Java module to the native gateway process,
169+
the `MessageBus` class must be used. The `MessageBus` class provides a method to
170+
publish messages onto the native Message Bus and loads a dynamic library that
171+
implements expected functions for publishing onto the native Message Bus. So,
172+
the above diagram should look a bit more like this:
204173

205-
![](Design2.png)
174+
![](HLD2.png)

bindings/java/devdoc/requirements_docs/com/microsoft/azure/gateway/messaging/message_requirements.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ public byte[] toByteArray();
4141
```
4242
**SRS_JAVA_MESSAGE_14_004: [** The function shall serialize the Message content and properties according to the specification in [message.h](../../../../../../../../../core/devdoc/message_requirements.md) **]**
4343

44-
**SRS_JAVA_MESSAGE_14_005: [** The function shall return `null` if the Message could not be serialized. **]**
44+
**SRS_JAVA_MESSAGE_14_005: [** The function shall return throw an IOException if the Message could not be serialized. **]**

0 commit comments

Comments
 (0)