Skip to content
Snippets Groups Projects
Commit 87a1dcd9 authored by René Schöne's avatar René Schöne
Browse files

Updated initial version of Java handler.

- also missing fix for CI (ragdoc-view should always run)
parent c3d6b2d6
No related branches found
No related tags found
1 merge request!30Feature: JavaHandler
Pipeline #13530 failed
This commit is part of merge request !30. Comments created here will be created in the context of that merge request.
Showing
with 270 additions and 8 deletions
......@@ -94,9 +94,6 @@ ragdoc_view:
- OUTPUT_DIR=$(pwd -P)/pages/docs/ragdoc
- cd /ragdoc-view/src/ && rm -rf data && ln -s $DATA_DIR
- /ragdoc-view/build-view.sh --output-path=$OUTPUT_DIR
only:
- dev
- master
artifacts:
paths:
- "pages/docs/ragdoc"
......
aspect RagConnectHandlers {
syn Handler RagConnect.javaHandler() = resolveHandlerByName("java");
syn Handler RagConnect.mqttHandler() = resolveHandlerByName("mqtt");
syn Handler RagConnect.restHandler() = resolveHandlerByName("rest");
......
......@@ -35,6 +35,7 @@ public class Compiler extends AbstractCompiler {
private static final String OPTION_LOGGING_TARGET_CONSOLE = "console";
private static final String OPTION_LOGGING_TARGET_SLF4J = "slf4j";
private static final String OPTION_PROTOCOL_JAVA = "java";
private static final String OPTION_PROTOCOL_MQTT = "mqtt";
private static final String OPTION_PROTOCOL_REST = "rest";
......@@ -179,6 +180,7 @@ public class Compiler extends AbstractCompiler {
new ValueOption("protocols", "Protocols to enable")
.acceptMultipleValues(true)
.addDefaultValue(OPTION_PROTOCOL_MQTT, "Enable MQTT")
.addAcceptedValue(OPTION_PROTOCOL_JAVA, "Enable Java")
.addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST")
);
optionPrintYaml = addOption(
......@@ -331,6 +333,7 @@ public class Compiler extends AbstractCompiler {
ragConnect.getConfiguration().setRootNode(rootNode);
// Handler ::= <ClassName> <UniqueName> <InUse:boolean>;
ragConnect.addHandler(new Handler("JavaHandler", "java", optionProtocols.hasValue(OPTION_PROTOCOL_JAVA)));
ragConnect.addHandler(new Handler("MqttServerHandler", "mqtt", optionProtocols.hasValue(OPTION_PROTOCOL_MQTT)));
ragConnect.addHandler(new Handler("RestServerHandler", "rest", optionProtocols.hasValue(OPTION_PROTOCOL_REST)));
}
......
/**
* Singleton class providing routing functionality for byte[] based message calls.
*/
public class JavaHandler {
public static JavaHandler JAVA_HANDLER_INSTANCE = null;
private java.util.Map<String, java.util.List<Pair<String, java.util.function.BiConsumer<String, byte[]>>>> callbackList = new java.util.concurrent.ConcurrentHashMap<>();
private String name;
private JavaHandler() {
this("RagConnect");
}
public JavaHandler(String name) {
this.name = name;
}
public synchronized static JavaHandler getInstance() {
if (JAVA_HANDLER_INSTANCE == null) {
JAVA_HANDLER_INSTANCE = new JavaHandler();
}
return JAVA_HANDLER_INSTANCE;
}
public String registerCallback(String topic, java.util.function.BiConsumer<String, byte[]> callback) {
{{logInfo}}("[JAVA_HANDLER] Registering new callback for {{log_}}.", topic);
String callbackUUID = java.util.UUID.randomUUID().toString();
java.util.List<Pair<String, java.util.function.BiConsumer<String, byte[]>>> registeredCallbacks = getAllCallbacks().get(topic);
if (registeredCallbacks == null) {
java.util.List<Pair<String, java.util.function.BiConsumer<String, byte[]>>> newCallbackList = java.util.Collections.synchronizedList(new java.util.ArrayList<>());
newCallbackList.add(new Pair<>(callbackUUID, callback));
callbackList.put(topic, newCallbackList);
} else {
registeredCallbacks.add(new Pair<>(callbackUUID, callback));
}
return callbackUUID;
}
public boolean unregisterCallback(String path, String uuid) {
{{logInfo}}("[JAVA_HANDLER] Unregistering callback with uuid: {{log_}}", uuid + " on path: {{log_}}", path);
java.util.List<Pair<String, java.util.function.BiConsumer<String, byte[]>>> callbacks = getAllCallbacks().get(path);
int count = 0;
if (callbacks != null) {
for (Pair<String, java.util.function.BiConsumer<String, byte[]>> callbackPair : callbacks) {
if (callbackPair._1.equals(uuid)) {
callbacks.remove(count);
return true;
} else {
count++;
}
}
}
return false;
}
public void close() {
}
public boolean push(String topic, byte[] data) {
{{logDebug}}("[JAVA_HANDLER] Pushing a message.");
String dataString = new String(data);
{{logDebug}}("[JAVA_HANDLER] Data: {{log_}}", dataString);
java.util.List<Pair<String, java.util.function.BiConsumer<String, byte[]>>> callbacks = getAllCallbacks().get(topic);
if (callbacks == null) {
{{logError}}("[JAVA_HANDLER] Could not publish message. No callback registered for topic {{log_}}", topic);
return false;
}
for (Pair<String, java.util.function.BiConsumer<String, byte[]>> callbackPair : callbacks) {
{{logDebug}}("[JAVA_HANDLER] Calling callback: {{log_}}", callbackPair._1);
callbackPair._2.accept(topic, data);
}
return true;
}
public java.util.Map<String, java.util.List<Pair<String, java.util.function.BiConsumer<String, byte[]>>>> getAllCallbacks() {
return callbackList;
}
}
......@@ -19,13 +19,19 @@ aspect RagConnectHandler {
{{/configIncrementalOptionActive}}
}
{{#javaHandler}}
{{#InUse}}
{{> JavaHandler}}
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}}
{{#InUse}}
public void {{rootNodeName}}.{{setupWaitUntilReadyMethodName}}(long time, java.util.concurrent.TimeUnit unit) {
{{fieldName}}.setupWaitUntilReady(time, unit);
}
{{/InUse}}
{{> MqttHandler}}
{{/InUse}}
{{/mqttHandler}}
{{#restHandler}}
......
......@@ -93,6 +93,13 @@ private boolean {{parentTypeName}}.{{internalConnectMethodName}}(String {{connec
RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}");
boolean success;
switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java":
success = {{attributeName}}().registerCallback(path, consumer, connectToken);
break;
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}}
{{#InUse}}
case "mqtt":
......@@ -130,6 +137,11 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
}
RagConnectDisconnectHandlerMethod disconnectingMethod;
switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java": return {{attributeName}}().unregisterCallback(uri.getPath(), connectTokens.get(this).get(uri).globalId);
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}}
{{#InUse}}
case "mqtt": disconnectingMethod = {{attributeName}}()::disconnect;
......
......@@ -5,6 +5,21 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}");
boolean success;
switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java":
final JavaHandler handler = {{attributeName}}().getInstance();
{{senderName}}.add(() -> {
handler.push(path, {{lastValueGetterCall}});
}{{#IndexBasedListAccess}}, index{{/IndexBasedListAccess}}, connectToken);
{{updateMethodName}}();
if (writeCurrentValue) {
{{writeMethodName}}({{#IndexBasedListAccess}}index, {{/IndexBasedListAccess}}connectToken);
}
break;
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}}
{{#InUse}}
case "mqtt":
......@@ -78,6 +93,13 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
{{/configIncrementalOptionActive}}
RagConnectDisconnectHandlerMethod disconnectingMethod;
switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java":
disconnectingMethod = {{senderName}}::remove;
break;
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}}
{{#InUse}}
case "mqtt":
......
......@@ -649,8 +649,6 @@ task compileRelationIncremental(type: RagConnectTest) {
inputFiles = [file('src/test/01-input/relation/Test.relast'),
file('src/test/01-input/relation/Test.connect')]
rootNode = 'Root'
logWrites = true
logIncremental = true
extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
}
relast {
......@@ -666,9 +664,34 @@ task compileRelationIncremental(type: RagConnectTest) {
}
}
// --- Test: java-incremental ---
task compileJavaIncremental(type: RagConnectTest) {
ragconnect {
outputDir = file('src/test/02-after-ragconnect/javaInc')
inputFiles = [file('src/test/01-input/java/Test.relast'),
file('src/test/01-input/java/Test.connect')]
rootNode = 'Root'
logWrites = true
logIncremental = true
protocols = ['java']
extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
}
relast {
useJastAddNames = true
grammarName = 'src/test/03-after-relast/javaInc/javaInc'
serializer = 'jackson'
}
jastadd {
jastAddList = 'JastAddList'
packageName = 'javaInc.ast'
inputFiles = [file('src/test/01-input/java/Test.jadd')]
extraOptions = JASTADD_INCREMENTAL_OPTIONS_TRACING_FULL
}
}
// --- Task order ---
classes.dependsOn(':ragconnect.base:jar')
//compileAttributeIncremental.outputs.upToDateWhen { false }
compileJavaIncremental.outputs.upToDateWhen { false }
// --- Misc ---
static ArrayList<String> defaultRagConnectOptionsAnd(ArrayList<String> options = []) {
......
# Java
Idea: Use receive and send definitions using the Java handler.
send SenderRoot.SendToken ;
send SenderRoot.SendNode ;
send SenderRoot.SendManyNode ;
send SenderRoot.SendNTA ;
AddSuffix maps A a to A {:
A result = new A();
String changedValue = a.getValue() + "post";
result.setValue(changedValue);
result.setInner(new Inner("inner" + a.getInner().getInnerValue()));
return result;
:}
AddStringSuffix maps String s to String {:
return s + "post";
:}
AddPlusOne maps int i to int {:
return i + 1;
:}
receive ReceiverRoot.SomeToken;
receive ReceiverRoot.SomeNode;
receive ReceiverRoot.SomeNodeWithMapping using AddSuffix;
receive ReceiverRoot.ManyNode;
aspect Computation {
syn String SenderRoot.basic() = getInput();
syn String SenderRoot.simple() = getInput() + "Post";
syn A SenderRoot.getSendNTA() {
A result = new A();
result.setValue(getInput());
Inner inner = new Inner();
inner.setInnerValue("1");
result.setInner(inner);
return result;
}
}
aspect MakeCodeCompile {
}
aspect MakeCodeWork {
}
aspect NameResolution {
// overriding customID guarantees to produce the same JSON representation for equal lists
// otherwise, the value for id is different each time
@Override
protected String A.customID() {
return getClass().getSimpleName() + getValue();
}
@Override
protected String Inner.customID() {
return getClass().getSimpleName() + getInnerValue();
}
}
Root ::= SenderRoot* ReceiverRoot;
SenderRoot ::= <Input> <SendToken> SendNode:A SendManyNode:A* /SendNTA:A/ ;
ReceiverRoot ::=
<SomeToken>
SomeNode:A
SomeNodeWithMapping:A
ManyNode:A*;
A ::= <Value> Inner ;
Inner ::= <InnerValue> ;
package org.jastadd.ragconnect.tests;
import javaInc.ast.Root;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Testing the Java handler.
*
* @author rschoene - Initial contribution
*/
@Tag("New")
public class JavaTest {
protected Logger logger = LoggerFactory.getLogger(getClass());
private Root model;
void createModel() {
model = new Root();
}
@Test
public void testCommunicateSendInitialValue() {
createModel();
}
@Test
public void testCommunicateOnlyUpdatedValue() {
createModel();
}
@AfterEach
public void alwaysCloseConnections() {
logger.debug("Closing connections");
if (model != null) {
model.ragconnectCloseConnections();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment