Skip to content

Commit c54d283

Browse files
Changes to java for changes to gateway core.
1 parent 3b7c04b commit c54d283

File tree

23 files changed

+182
-63
lines changed

23 files changed

+182
-63
lines changed

bindings/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ endif()
99

1010
if(${enable_java_binding})
1111
add_subdirectory(java)
12+
endif()
1213

1314
if(${enable_nodejs_binding})
1415
add_subdirectory(nodejs)

bindings/java/devdoc/java_binding_hld.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,12 @@ public interface IGatewayModule {
8282
* Gateway creates the Module. The constructor
8383
* should save both the {@code moduleAddr} and {@code bus} parameters.
8484
*
85+
* @param moduleAddr The address of the native module pointer
8586
* @param bus The {@link MessageBus} to which this Module belongs
8687
* @param configuration The configuration for this module represented as a JSON
8788
* string
8889
*/
89-
void create(MessageBus bus, String configuration);
90+
void create(long moduleAddr, MessageBus bus, String configuration);
9091

9192
/**
9293
* The destroy method is called on a {@link GatewayModule} before it is about
@@ -135,8 +136,9 @@ gateway, it:
135136
- Constructs a `MessageBus` Java object using the `MESSAGE_BUS_HANDLE`.
136137

137138
- Finds the module’s class with the name specified by the `args.class_name`,
138-
invokes the constructor passing in the `MessageBus` object and the JSON args
139-
string for that module, and creates the Java module.
139+
invokes the constructor passing in the native `MODULE_HANDLE` address,
140+
the `MessageBus` object and the JSON args string for that module, and
141+
creates the Java module.
140142

141143
- Gets a global reference to the newly created `GatewayModule` object to be
142144
saved by the `JAVA_MODULE_HOST_HANDLE`.
@@ -168,7 +170,7 @@ Communication **FROM** the Java module
168170
In order to communicate **from** the Java module to the native gateway process,
169171
the `MessageBus` class must be used. The `MessageBus` class provides a method to
170172
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:
173+
implements the functions for publishing onto the native message bus. So,the
174+
above diagram should look a bit more like this:
173175

174176
![](HLD2.png)

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ public final class Message implements Serializable{
1616

1717
private String content;
1818

19-
public Message(String content, Map<String, String> properties);
20-
public Message(String content);
19+
public Message(byte[] content, Map<String, String> properties);
2120
public Message(byte[] serializedMessage);
2221
public Map<String, String> getProperties();
2322
public String getContent();
@@ -27,7 +26,7 @@ public final class Message implements Serializable{
2726

2827
## Message
2928
```java
30-
public Message(byte[] serializedMessage | String content[, Map<String, String> properties]);
29+
public Message(byte[] serializedMessage | byte[] content, Map<String, String> properties);
3130
```
3231
**SRS_JAVA_MESSAGE_14_001: [** The constructor shall create a Message object by deserializing the byte array. **]**
3332

bindings/java/devdoc/requirements_docs/java_module_host_hl_requirements.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ This JSON object will be the `"args"` section of the Gateway JSON configuration
3535
"module path": "/path/to/java_module_host_hl.so|.dll",
3636
"args": {
3737
"class_path": "/path/to/relevant/class/files",
38-
"library_path": "/path/to/dir/with/java_module_host_hl.so|.dll",
38+
"library_path": "/path/to/dir/with/java_module_host.so|.dll",
3939
"class_name": "Poller",
4040
"args": {
4141
"frequency": 30

bindings/java/devdoc/requirements_docs/java_module_host_requirements.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void JavaModuleHost_Receive(MODULE_HANDLE module, MESSAGE_HANDLE message)
164164
JNIEXPORT jint JNICALL Java_com_microsoft_azure_gateway_core_MessageBus_publishMessage(JNIEnv *env, jobject MessageBus, jlong addr, jbyteArray message);
165165
```
166166

167-
**SRS_JAVA_MODULE_HOST_14_025: [** This function shall use convert the `jbyteArray message` into an `unsigned char` array. **]**
167+
**SRS_JAVA_MODULE_HOST_14_025: [** This function shall convert the `jbyteArray message` into an `unsigned char` array. **]**
168168

169169
**SRS_JAVA_MODULE_HOST_14_026: [** This function shall use the serialized message in a call to `Message_Create`. **]**
170170

bindings/java/gateway-java-binding/pom.xml

+21-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
</dependency>
2727
<dependency>
2828
<groupId>junit</groupId>
29-
<artifactId>junit-dep</artifactId>
30-
<version>4.11</version>
29+
<artifactId>junit</artifactId>
30+
<version>4.12</version>
3131
<scope>test</scope>
3232
</dependency>
3333
<dependency>
@@ -40,6 +40,25 @@
4040

4141
<build>
4242
<plugins>
43+
<plugin>
44+
<groupId>org.apache.maven.plugins</groupId>
45+
<artifactId>maven-compiler-plugin</artifactId>
46+
<version>3.3</version>
47+
<configuration>
48+
<source>1.6</source>
49+
<target>1.6</target>
50+
</configuration>
51+
</plugin>
52+
<plugin>
53+
<groupId>org.apache.maven.plugins</groupId>
54+
<artifactId>maven-surefire-plugin</artifactId>
55+
<version>2.19.1</version>
56+
<configuration>
57+
<argLine>
58+
-Dfile.encoding=UTF-8 -javaagent:${settings.localRepository}/org/jmockit/jmockit/1.22/jmockit-1.22.jar
59+
</argLine>
60+
</configuration>
61+
</plugin>
4362
<plugin>
4463
<groupId>org.apache.maven.plugins</groupId>
4564
<artifactId>maven-source-plugin</artifactId>

bindings/java/gateway-java-binding/src/main/java/com/microsoft/azure/gateway/core/GatewayModule.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public abstract class GatewayModule implements IGatewayModule{
1616
public abstract void receive(Message message);
1717
public abstract void destroy();
1818

19+
/** The address of the native module pointer */
20+
private long _addr;
21+
1922
/** The {@link MessageBus} to which this module belongs */
2023
private MessageBus bus;
2124

@@ -26,20 +29,24 @@ public abstract class GatewayModule implements IGatewayModule{
2629
* Constructs a {@link GatewayModule} from the provided address and {@link MessageBus}. A {@link GatewayModule} should always call this super
2730
* constructor before any module-specific constructor code.
2831
*
32+
* The {@code address} parameter must be passed to the super constructor but can be ignored by the module-implementor when writing a module implementation.
33+
*
34+
* @param address The address of the native module pointer.
2935
* @param bus The {@link MessageBus} to which this module belongs
3036
* @param configuration The module-specific configuration
3137
*/
32-
public GatewayModule(MessageBus bus, String configuration){
38+
public GatewayModule(long address, MessageBus bus, String configuration){
3339
/*Codes_SRS_JAVA_GATEWAY_MODULE_14_002: [ If address or bus is null the constructor shall throw an IllegalArgumentException. ]*/
34-
if(bus == null){
40+
if(address == 0 || bus == null){
3541
throw new IllegalArgumentException("Address is invalid or MessageBus is null.");
3642
}
3743

3844
/*Codes_SRS_JAVA_GATEWAY_MODULE_14_001: [ The constructor shall save address, bus, and configuration into class variables. ]*/
39-
this.create(bus, configuration);
45+
this.create(address, bus, configuration);
4046
}
4147

42-
public void create(MessageBus bus, String configuration){
48+
public void create(long moduleAddr, MessageBus bus, String configuration){
49+
this._addr = moduleAddr;
4350
this.bus = bus;
4451
this.configuration = configuration;
4552
}
@@ -48,6 +55,10 @@ public void receive(byte[] serializedMessage){
4855
this.receive(new Message(serializedMessage));
4956
}
5057

58+
public int publish(Message message) throws IOException {
59+
return this.bus.publishMessage(message, this._addr);
60+
}
61+
5162
//Public getter methods
5263

5364
final public MessageBus getMessageBus(){

bindings/java/gateway-java-binding/src/main/java/com/microsoft/azure/gateway/core/IGatewayModule.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ public interface IGatewayModule {
1010
* The create method is called by the subclass constructor when the native Gateway creates the Module. The constructor
1111
* should save the {@code bus} parameter.
1212
*
13+
* @param moduleAddr The address of the native module pointer
1314
* @param bus The {@link MessageBus} to which this Module belongs
1415
* @param configuration The configuration for this module represented as a JSON string
1516
*/
16-
void create(MessageBus bus, String configuration);
17+
void create(long moduleAddr, MessageBus bus, String configuration);
1718

1819
/**
1920
* The receive method is called on a {@link GatewayModule} whenever it receives a message.

bindings/java/gateway-java-binding/src/main/java/com/microsoft/azure/gateway/core/MessageBus.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,20 @@ public class MessageBus {
2121
* function to publish the provided {@link Message} onto the MessageBus.
2222
*
2323
* @param busAddr The address of the pointer to the native MessageBus.
24+
* @param moduleAddr The address of the pointer to the native Module.
2425
* @param message The serialized {@link Message} to be published.
2526
* @return 0 on success, non-zero otherwise.
2627
*/
27-
private native int publishMessage(long busAddr, byte[] message);
28+
private native int publishMessage(long busAddr, long moduleAddr, byte[] message);
2829

2930
private long _busAddr;
3031

3132
public MessageBus(long addr){
3233
this._busAddr = addr;
3334
}
3435

35-
public int publishMessage(Message message) throws IOException {
36-
return this.publishMessage(this._busAddr, message.toByteArray());
36+
public int publishMessage(Message message, long moduleAddr) throws IOException {
37+
return this.publishMessage(this._busAddr, moduleAddr, message.toByteArray());
3738
}
3839

3940
public long getAddress(){

bindings/java/gateway-java-binding/src/test/java/tests/unit/com/microsoft/azure/gateway/core/GatewayModuleTest.java

+18-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.microsoft.azure.gateway.core.GatewayModule;
88
import com.microsoft.azure.gateway.core.MessageBus;
99
import com.microsoft.azure.gateway.messaging.Message;
10+
import mockit.Deencapsulation;
1011
import mockit.Mocked;
1112
import org.junit.Test;
1213

@@ -17,27 +18,37 @@ public class GatewayModuleTest {
1718
@Mocked(stubOutClassInitialization = true)
1819
protected MessageBus mockBus;
1920

20-
/*Codes_SRS_JAVA_GATEWAY_MODULE_14_001: [ The constructor shall save address, bus, and configuration into class variables. ]*/
21+
/*Tests_SRS_JAVA_GATEWAY_MODULE_14_001: [ The constructor shall save address, bus, and configuration into class variables. ]*/
2122
@Test
2223
public void constructorSavesAllDataSuccess(){
2324
long address = 0x12345678;
2425
String configuration = "\"test-configuration\"";
2526

26-
GatewayModule module = new TestModule(mockBus, configuration);
27+
GatewayModule module = new TestModule(address, mockBus, configuration);
2728

2829
MessageBus expectedBus = module.getMessageBus();
30+
long expectedAddress = Deencapsulation.getField(module, "_addr");
2931
String expectedConfiguration = module.getConfiguration();
3032

3133
assertEquals(mockBus, expectedBus);
34+
assertEquals(address, expectedAddress);
3235
assertEquals(configuration, expectedConfiguration);
3336
}
3437

35-
/*Codes_SRS_JAVA_GATEWAY_MODULE_14_002: [ If address or bus is null the constructor shall throw an IllegalArgumentException. ]*/
38+
/*Tests_SRS_JAVA_GATEWAY_MODULE_14_002: [ If address or bus is null the constructor shall throw an IllegalArgumentException. ]*/
3639
@Test(expected = IllegalArgumentException.class)
3740
public void constructorThrowsExceptionForNullMessageBus(){
3841
long address = 0x12345678;
3942

40-
GatewayModule module = new TestModule(null, null);
43+
GatewayModule module = new TestModule(address, null, null);
44+
}
45+
46+
/*Tests_SRS_JAVA_GATEWAY_MODULE_14_002: [ If address or bus is null the constructor shall throw an IllegalArgumentException. ]*/
47+
@Test(expected = IllegalArgumentException.class)
48+
public void constructorThrowsExceptionForNullMessageAddr(){
49+
long address = 0;
50+
51+
GatewayModule module = new TestModule(0, mockBus, null);
4152
}
4253

4354
public class TestModule extends GatewayModule{
@@ -46,11 +57,12 @@ public class TestModule extends GatewayModule{
4657
* Constructs a {@link GatewayModule} from the provided address and {@link MessageBus}. A {@link GatewayModule} should always call this super
4758
* constructor before any module-specific constructor code.
4859
*
60+
* @param address The address of the native module pointer
4961
* @param bus The {@link MessageBus} to which this module belongs
5062
* @param configuration The module-specific configuration
5163
*/
52-
public TestModule(MessageBus bus, String configuration) {
53-
super(bus, configuration);
64+
public TestModule(long address, MessageBus bus, String configuration) {
65+
super(address, bus, configuration);
5466
}
5567

5668
@Override

bindings/java/gateway-java-binding/src/test/java/tests/unit/com/microsoft/azure/gateway/messaging/MessageTest.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ public class MessageTest {
3737
0x00, 0x00, 0x00, 0x02, /*2 message content size*/
3838
'3', '4'
3939
};
40+
41+
public byte[] validMessagePropertySwap =
42+
{
43+
(byte) 0xA1, 0x60, /*header*/
44+
0x00, 0x00, 0x00, 64, /*size of this array*/
45+
0x00, 0x00, 0x00, 0x02, /*two properties*/
46+
'A', 'z','u','r','e',' ','I','o','T',' ','G','a','t','e','w','a','y',' ','i','s','\0','a','w','e','s','o','m','e','\0',
47+
'B','l','e','e','d','i','n','g','E','d','g','e','\0','r','o','c','k','s','\0',
48+
0x00, 0x00, 0x00, 0x02, /*2 message content size*/
49+
'3', '4'
50+
};
4051

4152
/*Tests_SRS_JAVA_MESSAGE_14_003: [ The constructor shall save the message content and properties map. ]*/
4253
@Test
@@ -241,7 +252,7 @@ public void toByteArraySerializesMessageSuccess() throws IOException {
241252

242253
byte[] actualByteArray = m.toByteArray();
243254

244-
assertTrue(Arrays.equals(validMessage, actualByteArray));
255+
assertTrue(Arrays.equals(validMessage, actualByteArray) || Arrays.equals(validMessagePropertySwap, actualByteArray));
245256
}
246257

247258
/*Tests_SRS_JAVA_MESSAGE_14_005: [ The function shall return throw an IOException if the Message could not be serialized. ]*/

bindings/java/inc/Java_module_host_common.h bindings/java/inc/java_module_host_common.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#define MODULE_DESTROY_DESCRIPTOR "()V"
1212
#define MODULE_RECEIVE_DESCRIPTOR "([B)V"
1313
#define MESSAGE_BUS_CONSTRUCTOR_DESCRIPTOR "(J)V"
14-
#define MODULE_CONSTRUCTOR_DESCRIPTOR "(Lcom/microsoft/azure/gateway/core/MessageBus;Ljava/lang/String;)V"
14+
#define MODULE_CONSTRUCTOR_DESCRIPTOR "(JLcom/microsoft/azure/gateway/core/MessageBus;Ljava/lang/String;)V"
1515
#define DEBUG_PORT_DEFAULT 9876
1616

1717
#endif /*JAVA_MODULE_HOST_COMMON_H*/

bindings/java/inc/message_bus_proxy.h

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindings/java/src/java_module_host.c

+11-5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ typedef signed char jbyte;
6464
#define JNIFunc(jptr, call, ...) (*(jptr))->call(jptr, ##__VA_ARGS__)
6565
#endif
6666

67+
/* We currently have a dependency on Java 1.6, in case the user doesn't have Java 1.8 this will define the symbol so this will be able to compile.*/
68+
#ifndef JNI_VERSION_1_8
69+
#define JNI_VERSION_1_8 0x00010008
70+
#endif
71+
6772
typedef struct JAVA_MODULE_HANDLE_DATA_TAG
6873
{
6974
JavaVM* jvm;
@@ -232,7 +237,7 @@ static MODULE_HANDLE JavaModuleHost_Create(MESSAGE_BUS_HANDLE bus, const void* c
232237
}
233238
else
234239
{
235-
jobject jModule_object = NewObjectInternal(result->env, jModule_class, jModule_constructor, 2, jMessageBus_object, jModule_configuration);
240+
jobject jModule_object = NewObjectInternal(result->env, jModule_class, jModule_constructor, 3, (jlong)result, jMessageBus_object, jModule_configuration);
236241
exception = JNIFunc(result->env, ExceptionOccurred);
237242
if (jModule_object == NULL || exception)
238243
{
@@ -354,7 +359,7 @@ static void JavaModuleHost_Receive(MODULE_HANDLE module, MESSAGE_HANDLE message)
354359
}
355360
else
356361
{
357-
/*SRS_JAVA_MODULE_HOST_14_042: [This function shall attach the JVM to the current thread.]*/
362+
/*Codes_SRS_JAVA_MODULE_HOST_14_042: [This function shall attach the JVM to the current thread.]*/
358363
jint jni_result = JNIFunc(moduleHandle->jvm, AttachCurrentThread, (void**)(&(moduleHandle->env)), NULL);
359364

360365
if (jni_result == JNI_OK)
@@ -425,14 +430,14 @@ static void JavaModuleHost_Receive(MODULE_HANDLE module, MESSAGE_HANDLE message)
425430

426431
}
427432

428-
JNIEXPORT jint JNICALL Java_com_microsoft_azure_gateway_core_MessageBus_publishMessage(JNIEnv* env, jobject jMessageBus, jlong bus_address, jbyteArray serialized_message)
433+
JNIEXPORT jint JNICALL Java_com_microsoft_azure_gateway_core_MessageBus_publishMessage(JNIEnv* env, jobject jMessageBus, jlong bus_address, jlong module_address, jbyteArray serialized_message)
429434
{
430435
/*Codes_SRS_JAVA_MODULE_HOST_14_048: [This function shall return a non - zero value if any underlying function call fails.]*/
431436
MESSAGE_BUS_RESULT result = MESSAGE_BUS_ERROR;
432437

433438
MESSAGE_BUS_HANDLE bus = (MESSAGE_BUS_HANDLE)bus_address;
439+
MODULE_HANDLE module = (MODULE_HANDLE)module_address;
434440

435-
/*Codes_SRS_JAVA_MODULE_HOST_14_025: [This function shall use convert the jbyteArray message into an unsigned char array.]*/
436441
size_t length = JNIFunc(env, GetArrayLength, serialized_message);
437442
if (length == 0)
438443
{
@@ -447,6 +452,7 @@ JNIEXPORT jint JNICALL Java_com_microsoft_azure_gateway_core_MessageBus_publishM
447452
}
448453
else
449454
{
455+
/*Codes_SRS_JAVA_MODULE_HOST_14_025: [This function shall convert the jbyteArray message into an unsigned char array.]*/
450456
JNIFunc(env, GetByteArrayRegion, serialized_message, 0, length, arr);
451457
jthrowable exception = JNIFunc(env, ExceptionOccurred);
452458
if (exception)
@@ -467,7 +473,7 @@ JNIEXPORT jint JNICALL Java_com_microsoft_azure_gateway_core_MessageBus_publishM
467473
else
468474
{
469475
/*Codes_SRS_JAVA_MODULE_HOST_14_027: [This function shall publish the message to the MESSAGE_BUS_HANDLE addressed by addr and return the value of this function call.]*/
470-
result = MessageBus_Publish(bus, message);
476+
result = MessageBus_Publish(bus, module, message);
471477

472478
//Cleanup
473479
Message_Destroy(message);

0 commit comments

Comments
 (0)