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

Merge branch 'dev' into feature/improvement-tests

# Conflicts:
#	ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
parents 5add29c7 c453ddee
No related branches found
No related tags found
1 merge request!31Resolve "Improvement of tests"
Showing
with 365 additions and 34 deletions
...@@ -42,6 +42,8 @@ test: ...@@ -42,6 +42,8 @@ test:
- ./gradlew --console=plain --no-daemon allTests - ./gradlew --console=plain --no-daemon allTests
artifacts: artifacts:
when: always when: always
paths:
- "ragconnect.tests/test.log"
reports: reports:
junit: "ragconnect.tests/build/test-results/**/TEST-*.xml" junit: "ragconnect.tests/build/test-results/**/TEST-*.xml"
expire_in: 1 week expire_in: 1 week
......
# Changelog # Changelog
## 1.0.0 (dev)
### Changes
- Allow connection endpoints for relations ([#37](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/37)) and attributes ([#38](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/38))
- Allow send connection endpoints non-NTA nonterminals ([#36](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/36))
- Allow context-free context endpoints ([#34](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/34))
- Experimental support for Java handler ([#52](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/52))
- Make specification language more concise ([#33](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/33))
### Development Changes
- Make grammar(s) more concise ([#40](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/40))
- Enhance documentation, adding a DSL description
## 0.3.2 ## 0.3.2
- Allow connection endpoints for list nonterminals ([#21](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/21)) - Allow connection endpoints for list nonterminals ([#21](https://git-st.inf.tu-dresden.de/jastadd/ragconnect/-/issues/21))
......
...@@ -6,16 +6,16 @@ Additional options are as follows. ...@@ -6,16 +6,16 @@ Additional options are as follows.
| Name | Required (Default) | Description | | Name | Required (Default) | Description |
|---|---|---| |---|---|---|
| `--rootNode` | Yes | Root node in the base grammar. | | `--rootNode` | Yes | Root node in the base grammar. |
| `--protocols` | No (`mqtt`) | Protocols to enable, currently available: `mqtt, rest`. | | `--protocols` | No (`mqtt`) | Protocols to enable, currently available: `java` (experimental), `mqtt`, `rest`. |
| `--printYaml` | No (false) | Print out YAML instead of generating files. | | `--printYaml` | No (false) | Print out YAML instead of generating files. |
| `--verbose` | No (false) | Print more messages while compiling. | | `--verbose` | No (false) | Print more messages while compiling. |
| `--logReads` | No (false) | Enable logging for every received message. | | `--logReads` | No (false) | Enable logging for every received message. |
| `--logWrites` | No (false) | Enable logging for every sent message. | | `--logWrites` | No (false) | Enable logging for every sent message. |
| `--logIncremental` | No (false) | Enable logging for observer in incremental dependency tracking. | | `--logIncremental` | No (false) | Enable logging for observer in incremental dependency tracking. |
| `--logTarget` | No (`console`) | Logging target to use, currently available: `console, slf4j`. | | `--logTarget` | No (`console`) | Logging target to use, currently available: `console, slf4j`. |
| `--experimental-jastadd-329` | No (false) | Use trace events `INC_FLUSH_START` and `INC_FLUSH_END` ([JastAdd issue #329][jastadd-issue-329]), see [section about automatic dependency tracking](/using#dependency-tracking-automatically-derived). | | `--experimental-jastadd-329` | No (false) | Use tracing events `INC_FLUSH_START` and `INC_FLUSH_END` ([JastAdd issue #329][jastadd-issue-329]), see [section about automatic dependency tracking](/using#dependency-tracking-automatically-derived). |
| `--incremental` | No (false) | Enables incremental dependency tracking (if `trace` is also set appropriately). | | `--incremental` | No (false) | Enables incremental dependency tracking (if `tracing` is also set appropriately). |
| `--trace[=flush]` | No (false) | Enables incremental dependency tracking (if `incremental` is also set appropriately). | | `--tracing[=flush]` | No (false) | Enables incremental dependency tracking (if `incremental` is also set appropriately). |
| `--version` | No (false) | Print version info and exit (reused JastAdd option) | | `--version` | No (false) | Print version info and exit (reused JastAdd option) |
| `--o` | No (`.`) | Output directory (reused JastAdd option) | | `--o` | No (`.`) | Output directory (reused JastAdd option) |
...@@ -29,6 +29,16 @@ However, depending on the selected protocols and/or used features, additional de ...@@ -29,6 +29,16 @@ However, depending on the selected protocols and/or used features, additional de
## Communication protocol characteristics ## Communication protocol characteristics
### Java
- Protocol identifier: `java`
- URI scheme: `java://<ignored-host>[:ignored-port]/<topic>`
- the value for host and port are always ignored, but are necessary to form a legal URI
- No required runtime dependencies
- Additional remarks:
- First leading slash not included in topic.
- Currently, the default mappings are applied, which requires a consumer to expect `byte[]` (instead of a more intuitive token or node value). This might change in future versions.
### MQTT ### MQTT
- Protocol identifier: `mqtt` - Protocol identifier: `mqtt`
...@@ -59,15 +69,15 @@ However, depending on the selected protocols and/or used features, additional de ...@@ -59,15 +69,15 @@ However, depending on the selected protocols and/or used features, additional de
### Automatic dependency tracking ### Automatic dependency tracking
- Condition: When passing `--incremental` and `--trace=flush` to RagConnect - Condition: When passing `--incremental` and `--tracing=flush` to RagConnect
- Required runtime dependencies: _none_ - Required runtime dependencies: _none_
- Required options for RelAST compiler: _none_ - Required options for RelAST compiler: _none_
- Required options for JastAdd: - Required options for JastAdd:
- `--incremental` - `--incremental`
- `--trace=flush` - `--tracing=flush`
- Remarks: - Remarks:
- Other (additional) values passed to those two options must be equal (e.g., `--incremental=param` passed to RagConnect must be also passed to JastAdd) - Other (additional) values passed to those two options must be equal (e.g., `--incremental=param` passed to RagConnect must be also passed to JastAdd)
- Other values besides `flush` can be added to `--trace` - Other values besides `flush` can be added to `--tracing`
- [Feature description](/using#dependency-tracking-automatically-derived) - [Feature description](/using#dependency-tracking-automatically-derived)
### (Safer) Automatic dependency tracking ### (Safer) Automatic dependency tracking
......
...@@ -49,7 +49,7 @@ Specifying such an endpoint has several consequences: ...@@ -49,7 +49,7 @@ Specifying such an endpoint has several consequences:
**Example**: **Example**:
```java ```
// grammar // grammar
Root ::= A SingleA:A [OptA:A] ListA:A* ; Root ::= A SingleA:A [OptA:A] ListA:A* ;
A ::= <Value> ; A ::= <Value> ;
...@@ -60,13 +60,15 @@ receive Root.SingleA using MyMapping; // specialized endpoint ...@@ -60,13 +60,15 @@ receive Root.SingleA using MyMapping; // specialized endpoint
``` ```
Implied, additional connect specifications: Implied, additional connect specifications:
```java
```
receive Root.A; receive Root.A;
receive Root.OptA; receive Root.OptA;
receive indexed Root.ListA; receive indexed Root.ListA;
``` ```
Application code: Application code:
```java ```java
A a = root.getOptA(); A a = root.getOptA();
// new method on A: // new method on A:
......
...@@ -47,7 +47,7 @@ Otherwise, the deprecated manual dependencies must be used. ...@@ -47,7 +47,7 @@ Otherwise, the deprecated manual dependencies must be used.
### Dependency tracking: Automatically derived ### Dependency tracking: Automatically derived
To automatically track dependencies, the two additional parameters `--incremental` and `--trace=flush` have to be provided to both RagConnect and (in the later stage) JastAdd. To automatically track dependencies, the two additional parameters `--incremental` and `--tracing=flush` have to be provided to both RagConnect and (in the later stage) JastAdd.
This will generate a different implementation of RagConnect relying on enabled incremental evaluation of JastAdd. This will generate a different implementation of RagConnect relying on enabled incremental evaluation of JastAdd.
The value for `incremental` has only been tested for `incremental=param`. The value for `incremental` has only been tested for `incremental=param`.
The value for `trace` can include other values besides `flush`. The value for `trace` can include other values besides `flush`.
......
aspect RagConnectHandlers { aspect RagConnectHandlers {
syn Handler RagConnect.javaHandler() = resolveHandlerByName("java");
syn Handler RagConnect.mqttHandler() = resolveHandlerByName("mqtt"); syn Handler RagConnect.mqttHandler() = resolveHandlerByName("mqtt");
syn Handler RagConnect.restHandler() = resolveHandlerByName("rest"); syn Handler RagConnect.restHandler() = resolveHandlerByName("rest");
......
...@@ -15,6 +15,10 @@ aspect SharedMustache { ...@@ -15,6 +15,10 @@ aspect SharedMustache {
syn boolean RagConnect.configExperimentalJastAdd329() = getConfiguration().getExperimentalJastAdd329(); syn boolean RagConnect.configExperimentalJastAdd329() = getConfiguration().getExperimentalJastAdd329();
syn boolean RagConnect.configEvaluationCounter() = getConfiguration().getEvaluationCounter();
syn String RagConnect.evaluationCounterVariable() = internalRagConnectPrefix() + "evaluationCounter";
syn String RagConnect.internalRagConnectPrefix() = "_ragconnect_"; syn String RagConnect.internalRagConnectPrefix() = "_ragconnect_";
syn String RagConnect.logDebug() = logStatement("debug"); syn String RagConnect.logDebug() = logStatement("debug");
...@@ -99,6 +103,10 @@ aspect MustacheHandler { ...@@ -99,6 +103,10 @@ aspect MustacheHandler {
// === RagConnect === // === RagConnect ===
syn String RagConnect.closeMethodName() = "ragconnectCloseConnections"; syn String RagConnect.closeMethodName() = "ragconnectCloseConnections";
syn String RagConnect.evaluationCounterInnerClass() = internalRagConnectPrefix() + "Counter";
syn String RagConnect.evaluationCounterSummaryMethodName() = "ragconnectEvaluationCounterSummary";
syn boolean RagConnect.hasRootTypeComponents() = !rootTypeComponents().isEmpty(); syn boolean RagConnect.hasRootTypeComponents() = !rootTypeComponents().isEmpty();
syn List<TypeComponent> RagConnect.rootTypeComponents() { syn List<TypeComponent> RagConnect.rootTypeComponents() {
...@@ -118,6 +126,10 @@ aspect MustacheHandler { ...@@ -118,6 +126,10 @@ aspect MustacheHandler {
syn String Handler.fieldName() = ragconnect().internalRagConnectPrefix() + getUniqueName() + "Handler"; syn String Handler.fieldName() = ragconnect().internalRagConnectPrefix() + getUniqueName() + "Handler";
syn String Handler.pushMethodName() = "ragconnect" + capitalize(getUniqueName()) + "Push";
syn String Handler.registerConsumerMethodName() = "ragconnect" + capitalize(getUniqueName()) + "RegisterConsumer";
syn String Handler.setupWaitUntilReadyMethodName() = "ragconnectSetup" + capitalize(getUniqueName()) + "WaitUntilReady"; syn String Handler.setupWaitUntilReadyMethodName() = "ragconnectSetup" + capitalize(getUniqueName()) + "WaitUntilReady";
} }
......
...@@ -243,7 +243,7 @@ aspect Mappings { ...@@ -243,7 +243,7 @@ aspect Mappings {
return getEndpointTarget().isTypeEndpointTarget() && typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultBytesToListMapping(typeDecl.getName()) : ragconnect().defaultBytesToTreeMapping(typeDecl.getName()); return getEndpointTarget().isTypeEndpointTarget() && typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultBytesToListMapping(typeDecl.getName()) : ragconnect().defaultBytesToTreeMapping(typeDecl.getName());
} catch (Exception ignore) { } catch (Exception ignore) {
} }
System.err.println("Could not find suitable default mapping for " + targetTypeName() + " on " + this); System.err.println("Could not find suitable default receive mapping for " + targetTypeName() + " on " + this);
return null; return null;
} }
} }
...@@ -287,7 +287,7 @@ aspect Mappings { ...@@ -287,7 +287,7 @@ aspect Mappings {
} catch (Exception ignore) { } catch (Exception ignore) {
// exception should be logged to debug/fine // exception should be logged to debug/fine
} }
System.err.println("Could not find suitable default mapping for " + targetTypeName() + " on " + this); System.err.println("Could not find suitable default send mapping for " + targetTypeName() + " on " + this);
return null; return null;
} }
} }
......
...@@ -40,5 +40,6 @@ Configuration ::= ...@@ -40,5 +40,6 @@ Configuration ::=
<JastAddOpt:String> <JastAddOpt:String>
<IncrementalOptionActive:boolean> <IncrementalOptionActive:boolean>
<CacheAllOptionActive:boolean> <CacheAllOptionActive:boolean>
<EvaluationCounter:boolean>
<ExperimentalJastAdd329:boolean>; <ExperimentalJastAdd329:boolean>;
rel Configuration.RootNode -> TypeDecl ; rel Configuration.RootNode -> TypeDecl ;
...@@ -31,10 +31,12 @@ public class Compiler extends AbstractCompiler { ...@@ -31,10 +31,12 @@ public class Compiler extends AbstractCompiler {
private BooleanOption optionLogIncremental; private BooleanOption optionLogIncremental;
private ValueOption optionLogTarget; private ValueOption optionLogTarget;
private BooleanOption optionExperimentalJastAdd329; private BooleanOption optionExperimentalJastAdd329;
private BooleanOption optionEvaluationCounter;
private static final String OPTION_LOGGING_TARGET_CONSOLE = "console"; private static final String OPTION_LOGGING_TARGET_CONSOLE = "console";
private static final String OPTION_LOGGING_TARGET_SLF4J = "slf4j"; 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_MQTT = "mqtt";
private static final String OPTION_PROTOCOL_REST = "rest"; private static final String OPTION_PROTOCOL_REST = "rest";
...@@ -179,6 +181,7 @@ public class Compiler extends AbstractCompiler { ...@@ -179,6 +181,7 @@ public class Compiler extends AbstractCompiler {
new ValueOption("protocols", "Protocols to enable") new ValueOption("protocols", "Protocols to enable")
.acceptMultipleValues(true) .acceptMultipleValues(true)
.addDefaultValue(OPTION_PROTOCOL_MQTT, "Enable MQTT") .addDefaultValue(OPTION_PROTOCOL_MQTT, "Enable MQTT")
.addAcceptedValue(OPTION_PROTOCOL_JAVA, "Enable Java (experimental)")
.addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST") .addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST")
); );
optionPrintYaml = addOption( optionPrintYaml = addOption(
...@@ -204,6 +207,9 @@ public class Compiler extends AbstractCompiler { ...@@ -204,6 +207,9 @@ public class Compiler extends AbstractCompiler {
optionExperimentalJastAdd329 = addOption( optionExperimentalJastAdd329 = addOption(
new BooleanOption("experimental-jastadd-329", "Use trace events INC_FLUSH_START and INC_FLUSH_END (JastAdd issue #329).") new BooleanOption("experimental-jastadd-329", "Use trace events INC_FLUSH_START and INC_FLUSH_END (JastAdd issue #329).")
.defaultValue(false)); .defaultValue(false));
optionEvaluationCounter = addOption(
new BooleanOption("evaluationCounter", "Enable counters for evaluation.")
.defaultValue(false));
} }
private RagConnect parseProgram(Collection<String> files) throws CompilerException { private RagConnect parseProgram(Collection<String> files) throws CompilerException {
...@@ -299,15 +305,16 @@ public class Compiler extends AbstractCompiler { ...@@ -299,15 +305,16 @@ public class Compiler extends AbstractCompiler {
* Set all configuration values. * Set all configuration values.
* @param ragConnect the RagConnect instance to set configuration values * @param ragConnect the RagConnect instance to set configuration values
*/ */
private void setConfiguration(RagConnect ragConnect) { private void setConfiguration(RagConnect ragConnect) throws CompilerException {
ragConnect.setConfiguration(new Configuration()); ragConnect.setConfiguration(new Configuration());
ragConnect.getConfiguration().setLoggingEnabledForReads(optionLogReads.value()); ragConnect.getConfiguration().setLoggingEnabledForReads(optionLogReads.value());
ragConnect.getConfiguration().setLoggingEnabledForWrites(optionLogWrites.value()); ragConnect.getConfiguration().setLoggingEnabledForWrites(optionLogWrites.value());
ragConnect.getConfiguration().setLoggingEnabledForIncremental(optionLogIncremental.value()); ragConnect.getConfiguration().setLoggingEnabledForIncremental(optionLogIncremental.value());
ragConnect.getConfiguration().setLoggingTarget(optionLogTarget.value()); ragConnect.getConfiguration().setLoggingTarget(optionLogTarget.value());
ragConnect.getConfiguration().setExperimentalJastAdd329(optionExperimentalJastAdd329.value()); ragConnect.getConfiguration().setExperimentalJastAdd329(optionExperimentalJastAdd329.value());
ragConnect.getConfiguration().setEvaluationCounter(optionEvaluationCounter.value());
// reuse "--incremental" and "--trace=flush" options of JastAdd // reuse "--incremental" and "--tracing=flush" options of JastAdd
boolean incrementalOptionActive = this.getConfiguration().incremental() && this.getConfiguration().traceFlush(); boolean incrementalOptionActive = this.getConfiguration().incremental() && this.getConfiguration().traceFlush();
ragConnect.getConfiguration().setIncrementalOptionActive(incrementalOptionActive); ragConnect.getConfiguration().setIncrementalOptionActive(incrementalOptionActive);
if (isVerbose()) { if (isVerbose()) {
...@@ -326,11 +333,12 @@ public class Compiler extends AbstractCompiler { ...@@ -326,11 +333,12 @@ public class Compiler extends AbstractCompiler {
rootNode = ragConnect.getProgram().resolveTypeDecl(optionRootNode.value()); rootNode = ragConnect.getProgram().resolveTypeDecl(optionRootNode.value());
} catch (RuntimeException re) { } catch (RuntimeException re) {
// root node was not found // root node was not found
throw new RuntimeException("Could not resolve root node '" + optionRootNode.value() + "'!", re); throw new CompilerException("Could not resolve root node '" + optionRootNode.value() + "'!", re);
} }
ragConnect.getConfiguration().setRootNode(rootNode); ragConnect.getConfiguration().setRootNode(rootNode);
// Handler ::= <ClassName> <UniqueName> <InUse:boolean>; // 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("MqttServerHandler", "mqtt", optionProtocols.hasValue(OPTION_PROTOCOL_MQTT)));
ragConnect.addHandler(new Handler("RestServerHandler", "rest", optionProtocols.hasValue(OPTION_PROTOCOL_REST))); 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<java.util.function.BiConsumer<String, byte[]>>> callbackList = new java.util.concurrent.ConcurrentHashMap<>();
private final java.util.Map<RagConnectToken, java.util.function.BiConsumer<String, byte[]>> tokensForRemoval = new java.util.HashMap<>();
private String name;
private JavaHandler() {
this("RagConnect");
}
public JavaHandler(String name) {
this.name = name;
}
private static String extractPath(java.net.URI uri) {
String path = uri.getPath();
if (path.charAt(0) == '/') {
path = path.substring(1);
}
return path;
}
RagConnectToken registerConsumer(String path, java.util.function.Consumer<byte[]> consumer) {
RagConnectToken token = new RagConnectToken(java.net.URI.create("internal://host/" + path), null);
registerCallback(token, (s, bytes) -> consumer.accept(bytes));
return token;
}
boolean registerCallback(RagConnectToken connectToken, java.util.function.BiConsumer<String, byte[]> callback) {
String path = extractPath(connectToken.uri);
{{logInfo}}("[JAVA_HANDLER] Registering new callback for {{log_}}.", path);
java.util.List<java.util.function.BiConsumer<String, byte[]>> registeredCallbacks = callbackList.get(path);
if (registeredCallbacks == null) {
registeredCallbacks = java.util.Collections.synchronizedList(new java.util.ArrayList<>());
callbackList.put(path, registeredCallbacks);
}
registeredCallbacks.add(callback);
tokensForRemoval.put(connectToken, callback);
return true;
}
boolean unregisterCallback(RagConnectToken connectToken) {
String path = extractPath(connectToken.uri);
java.util.function.BiConsumer<String, byte[]> callback = tokensForRemoval.get(connectToken);
{{logInfo}}("[JAVA_HANDLER] Unregistering callback with uuid: on path: {{log_}}", path);
return callbackList.get(path).remove(callback);
}
void close() {
}
boolean push(String uriString, byte[] data) {
String path = extractPath(java.net.URI.create(uriString));
{{logDebug}}("[JAVA_HANDLER] Pushing a message for {{log_}}.", path);
if (data == null) {
{{logDebug}}("[JAVA_HANDLER] data was null, aborting");
return false;
}
String dataString = new String(data);
{{logDebug}}("[JAVA_HANDLER] Data: {{log_}}", dataString);
java.util.List<java.util.function.BiConsumer<String, byte[]>> callbacks = callbackList.get(path);
if (callbacks == null) {
{{logError}}("[JAVA_HANDLER] Could not publish message. No callback registered for path {{log_}}", path);
return false;
}
for (java.util.function.BiConsumer<String, byte[]> callback : callbacks) {
callback.accept(path, data);
}
return true;
}
}
...@@ -10,14 +10,14 @@ try { ...@@ -10,14 +10,14 @@ try {
return false; return false;
} }
if (scheme == null || scheme.isBlank()) { if (scheme == null || scheme.isBlank()) {
{{logError}}("Missing or empty scheme in " + uri); {{logError}}("Missing or empty scheme in {{log_}}", uri);
return false; return false;
} }
if (host == null || host.isBlank()) { if (host == null || host.isBlank()) {
{{logError}}("Missing or empty host in " + uri); {{logError}}("Missing or empty host in {{log_}}", uri);
return false; return false;
} }
if (path == null || path.isBlank()) { if (path == null || path.isBlank()) {
{{logError}}("Missing or empty path in " + uri); {{logError}}("Missing or empty path in {{log_}}", uri);
return false; return false;
} }
...@@ -19,13 +19,25 @@ aspect RagConnectHandler { ...@@ -19,13 +19,25 @@ aspect RagConnectHandler {
{{/configIncrementalOptionActive}} {{/configIncrementalOptionActive}}
} }
{{#javaHandler}}
{{#InUse}}
public RagConnectToken {{rootNodeName}}.{{registerConsumerMethodName}}(String path, java.util.function.Consumer<byte[]> consumer) {
return {{fieldName}}.registerConsumer(path, consumer);
}
public boolean {{rootNodeName}}.{{pushMethodName}}(String uriString, byte[] data) {
return {{fieldName}}.push(uriString, data);
}
{{> JavaHandler}}
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}} {{#mqttHandler}}
{{#InUse}} {{#InUse}}
public void {{rootNodeName}}.{{setupWaitUntilReadyMethodName}}(long time, java.util.concurrent.TimeUnit unit) { public void {{rootNodeName}}.{{setupWaitUntilReadyMethodName}}(long time, java.util.concurrent.TimeUnit unit) {
{{fieldName}}.setupWaitUntilReady(time, unit); {{fieldName}}.setupWaitUntilReady(time, unit);
} }
{{/InUse}}
{{> MqttHandler}} {{> MqttHandler}}
{{/InUse}}
{{/mqttHandler}} {{/mqttHandler}}
{{#restHandler}} {{#restHandler}}
......
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementCall("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{#Send}} {{#Send}}
{{^PrimitiveType}} {{^PrimitiveType}}
if ({{firstInputVarName}} == null) { if ({{firstInputVarName}} == null) {
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementFirstNull("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{preemptiveReturn}} {{preemptiveReturn}}
} }
{{/PrimitiveType}} {{/PrimitiveType}}
...@@ -12,13 +18,22 @@ try { ...@@ -12,13 +18,22 @@ try {
{{/innerMappingDefinitions}} {{/innerMappingDefinitions}}
} catch (RagConnectRejectMappingException e) { } catch (RagConnectRejectMappingException e) {
// do not print message in case of rejection // do not print message in case of rejection
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementReject("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{preemptiveReturn}} {{preemptiveReturn}}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementException("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{preemptiveReturn}} {{preemptiveReturn}}
} }
{{^AlwaysApply}} {{^AlwaysApply}}
if ({{{condition}}}) { if ({{{condition}}}) {
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementSkip("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{preemptiveReturn}} {{preemptiveReturn}}
} }
{{/AlwaysApply}} {{/AlwaysApply}}
protected static {{{toType}}} ASTNode.{{methodName}}({{{fromType}}} {{FromVariableName}}) throws Exception { protected {{{toType}}} ASTNode.{{methodName}}({{{fromType}}} {{FromVariableName}}) throws Exception {
{{{Content}}} {{{Content}}}
} }
...@@ -285,3 +285,98 @@ aspect RagConnectObserver { ...@@ -285,3 +285,98 @@ aspect RagConnectObserver {
} }
} }
{{/configIncrementalOptionActive}} {{/configIncrementalOptionActive}}
aspect EvaluationCounter {
public String ASTNode.{{evaluationCounterSummaryMethodName}}() {
{{#configEvaluationCounter}}
return {{evaluationCounterVariable}}.summary();
{{/configEvaluationCounter}}
{{^configEvaluationCounter}}
String message = "Option --evaluationCounter was not set. No Summary available";
{{logWarn}}(message);
return message;
{{/configEvaluationCounter}}
}
{{#configEvaluationCounter}}
static EvaluationCounter ASTNode.{{evaluationCounterVariable}} = new EvaluationCounter();
public class EvaluationCounter {
private java.util.Map<String, java.util.Map<String, {{evaluationCounterInnerClass}}>> counters = new java.util.HashMap<>();
private final java.util.function.Function<? super String, ? extends java.util.Map<String, {{evaluationCounterInnerClass}}>> parentAbsent = key -> {
return new java.util.HashMap<>();
};
private final java.util.function.Function<? super String, ? extends {{evaluationCounterInnerClass}}> entityAbsent = key -> {
return new {{evaluationCounterInnerClass}}();
};
public void incrementReceive(String parentTypeName, String entityName) {
getCounter(parentTypeName, entityName).receive += 1;
}
public void incrementSend(String parentTypeName, String entityName) {
getCounter(parentTypeName, entityName).send += 1;
}
public void incrementCall(String parentTypeName, String entityName) {
getCounter(parentTypeName, entityName).call += 1;
}
public void incrementFirstNull(String parentTypeName, String entityName) {
getCounter(parentTypeName, entityName).firstNull += 1;
}
public void incrementSkip(String parentTypeName, String entityName) {
getCounter(parentTypeName, entityName).skip += 1;
}
public void incrementException(String parentTypeName, String entityName) {
getCounter(parentTypeName, entityName).exception += 1;
}
public void incrementReject(String parentTypeName, String entityName) {
getCounter(parentTypeName, entityName).reject += 1;
}
public String summary() {
StringBuilder sb = new StringBuilder();
// header
sb.append("parentTypeName,entityName,receive,send,call,firstNull,skip,exception,reject").append("\n");
// values
java.util.Set<String> sortedParentTypes = new java.util.TreeSet<>(counters.keySet());
for (String parentType : sortedParentTypes) {
java.util.Set<String> sortedEntityNames = new java.util.TreeSet<>(counters.get(parentType).keySet());
for (String entityName : sortedEntityNames) {
{{evaluationCounterInnerClass}} count = getCounter(parentType, entityName);
java.util.StringJoiner sj = new java.util.StringJoiner(",", "", "\n");
sj.add(parentType)
.add(entityName)
.add(Integer.toString(count.receive))
.add(Integer.toString(count.send))
.add(Integer.toString(count.call))
.add(Integer.toString(count.firstNull))
.add(Integer.toString(count.skip))
.add(Integer.toString(count.exception))
.add(Integer.toString(count.reject))
;
sb.append(sj);
}
}
return sb.toString();
}
private {{evaluationCounterInnerClass}} getCounter(String parentTypeName, String entityName) {
return counters.computeIfAbsent(parentTypeName, parentAbsent).computeIfAbsent(entityName, entityAbsent);
}
}
class {{evaluationCounterInnerClass}} {
int receive = 0;
int send = 0;
int call = 0;
int firstNull = 0;
int skip = 0;
int exception = 0;
int reject = 0;
}
{{/configEvaluationCounter}}
}
...@@ -25,6 +25,9 @@ private int {{parentTypeName}}.{{resolveInListMethodName}}(String topic) { ...@@ -25,6 +25,9 @@ private int {{parentTypeName}}.{{resolveInListMethodName}}(String topic) {
*/ */
public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParameterName}}{{#typeIsList}}{{#IndexBasedListAccess}}{{^WithAdd}}, int index{{/WithAdd}}{{/IndexBasedListAccess}}{{/typeIsList}}) throws java.io.IOException { public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParameterName}}{{#typeIsList}}{{#IndexBasedListAccess}}{{^WithAdd}}, int index{{/WithAdd}}{{/IndexBasedListAccess}}{{/typeIsList}}) throws java.io.IOException {
java.util.function.BiConsumer<String, byte[]> consumer = (topic, message) -> { java.util.function.BiConsumer<String, byte[]> consumer = (topic, message) -> {
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementReceive("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{> mappingApplication}} {{> mappingApplication}}
{{#configLoggingEnabledForReads}} {{#configLoggingEnabledForReads}}
{{logDebug}}("[Receive] {{log_}} -> {{entityName}} = {{log_}}", {{connectParameterName}}, {{lastResult}}); {{logDebug}}("[Receive] {{log_}} -> {{entityName}} = {{log_}}", {{connectParameterName}}, {{lastResult}});
...@@ -70,6 +73,9 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete ...@@ -70,6 +73,9 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
*/ */
public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParameterName}}) throws java.io.IOException { public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParameterName}}) throws java.io.IOException {
java.util.function.BiConsumer<String, byte[]> consumer = (topic, message) -> { java.util.function.BiConsumer<String, byte[]> consumer = (topic, message) -> {
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementReceive("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
int index = {{resolveInListMethodName}}(topic); int index = {{resolveInListMethodName}}(topic);
{{> mappingApplication}} {{> mappingApplication}}
{{#configLoggingEnabledForReads}} {{#configLoggingEnabledForReads}}
...@@ -93,6 +99,13 @@ private boolean {{parentTypeName}}.{{internalConnectMethodName}}(String {{connec ...@@ -93,6 +99,13 @@ private boolean {{parentTypeName}}.{{internalConnectMethodName}}(String {{connec
RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}"); RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}");
boolean success; boolean success;
switch (scheme) { switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java":
success = {{attributeName}}().registerCallback(connectToken, consumer);
break;
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}} {{#mqttHandler}}
{{#InUse}} {{#InUse}}
case "mqtt": case "mqtt":
...@@ -130,6 +143,12 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam ...@@ -130,6 +143,12 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
} }
RagConnectDisconnectHandlerMethod disconnectingMethod; RagConnectDisconnectHandlerMethod disconnectingMethod;
switch (scheme) { switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java": disconnectingMethod = {{attributeName}}()::unregisterCallback;
break;
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}} {{#mqttHandler}}
{{#InUse}} {{#InUse}}
case "mqtt": disconnectingMethod = {{attributeName}}()::disconnect; case "mqtt": disconnectingMethod = {{attributeName}}()::disconnect;
......
...@@ -5,6 +5,22 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete ...@@ -5,6 +5,22 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}"); RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}");
boolean success; boolean success;
switch (scheme) { switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java":
final JavaHandler handler = {{attributeName}}();
{{senderName}}.add(() -> {
handler.push(path, {{lastValueGetterCall}});
}{{#IndexBasedListAccess}}, index{{/IndexBasedListAccess}}, connectToken);
{{updateMethodName}}();
if (writeCurrentValue) {
{{writeMethodName}}({{#IndexBasedListAccess}}index, {{/IndexBasedListAccess}}connectToken);
}
success = true;
break;
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}} {{#mqttHandler}}
{{#InUse}} {{#InUse}}
case "mqtt": case "mqtt":
...@@ -78,6 +94,13 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam ...@@ -78,6 +94,13 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
{{/configIncrementalOptionActive}} {{/configIncrementalOptionActive}}
RagConnectDisconnectHandlerMethod disconnectingMethod; RagConnectDisconnectHandlerMethod disconnectingMethod;
switch (scheme) { switch (scheme) {
{{#javaHandler}}
{{#InUse}}
case "java":
disconnectingMethod = {{senderName}}::remove;
break;
{{/InUse}}
{{/javaHandler}}
{{#mqttHandler}} {{#mqttHandler}}
{{#InUse}} {{#InUse}}
case "mqtt": case "mqtt":
...@@ -111,14 +134,25 @@ protected boolean {{parentTypeName}}.{{updateMethodName}}({{#IndexBasedListAcces ...@@ -111,14 +134,25 @@ protected boolean {{parentTypeName}}.{{updateMethodName}}({{#IndexBasedListAcces
{{> mappingApplication}} {{> mappingApplication}}
{{lastValueSetter}}({{#IndexBasedListAccess}}index, {{/IndexBasedListAccess}}{{lastResult}}); {{lastValueSetter}}({{#IndexBasedListAccess}}index, {{/IndexBasedListAccess}}{{lastResult}});
// normally we would return true here. unless no connect method was called so far to initialize {{senderName}} yet // normally we would return true here. unless no connect method was called so far to initialize {{senderName}} yet
{{#configEvaluationCounter}}
if ({{senderName}} == null) {
{{evaluationCounterVariable}}.incrementSkip("{{parentTypeName}}", "{{entityName}}");
}
{{/configEvaluationCounter}}
return {{senderName}} != null; return {{senderName}} != null;
} }
protected void {{parentTypeName}}.{{writeMethodName}}({{#IndexBasedListAccess}}int index{{/IndexBasedListAccess}}) { protected void {{parentTypeName}}.{{writeMethodName}}({{#IndexBasedListAccess}}int index{{/IndexBasedListAccess}}) {
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementSend("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{senderName}}.run({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}}); {{senderName}}.run({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}});
} }
protected void {{parentTypeName}}.{{writeMethodName}}({{#IndexBasedListAccess}}int index, {{/IndexBasedListAccess}}RagConnectToken token) { protected void {{parentTypeName}}.{{writeMethodName}}({{#IndexBasedListAccess}}int index, {{/IndexBasedListAccess}}RagConnectToken token) {
{{#configEvaluationCounter}}
{{evaluationCounterVariable}}.incrementSend("{{parentTypeName}}", "{{entityName}}");
{{/configEvaluationCounter}}
{{senderName}}.run({{#IndexBasedListAccess}}index, {{/IndexBasedListAccess}}token); {{senderName}}.run({{#IndexBasedListAccess}}index, {{/IndexBasedListAccess}}token);
} }
......
...@@ -3,3 +3,4 @@ src/gen-res/ ...@@ -3,3 +3,4 @@ src/gen-res/
src/gen/ src/gen/
out/ out/
*.class *.class
test.log
...@@ -71,6 +71,8 @@ dependencies { ...@@ -71,6 +71,8 @@ dependencies {
testImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' testImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
api group: 'com.google.protobuf', name: 'protobuf-java', version: '3.0.0' api group: 'com.google.protobuf', name: 'protobuf-java', version: '3.0.0'
implementation group: 'de.tudresden.inf.st', name: 'dumpAst', version: "1.0.2-68"
} }
// --- Preprocessors --- // --- Preprocessors ---
...@@ -672,9 +674,7 @@ task compileRelationIncremental(type: RagConnectTest) { ...@@ -672,9 +674,7 @@ task compileRelationIncremental(type: RagConnectTest) {
inputFiles = [file('src/test/01-input/relation/Test.relast'), inputFiles = [file('src/test/01-input/relation/Test.relast'),
file('src/test/01-input/relation/Test.connect')] file('src/test/01-input/relation/Test.connect')]
rootNode = 'Root' rootNode = 'Root'
logWrites = true extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329', '--evaluationCounter'])
logIncremental = true
extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
} }
relast { relast {
useJastAddNames = true useJastAddNames = true
...@@ -689,9 +689,31 @@ task compileRelationIncremental(type: RagConnectTest) { ...@@ -689,9 +689,31 @@ 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'
protocols = ['java']
extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329', '--evaluationCounter'])
}
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 --- // --- Task order ---
classes.dependsOn(':ragconnect.base:jar') classes.dependsOn(':ragconnect.base:jar')
//compileAttributeIncremental.outputs.upToDateWhen { false }
// --- Misc --- // --- Misc ---
static ArrayList<String> defaultRagConnectOptionsAnd(ArrayList<String> options = []) { static ArrayList<String> defaultRagConnectOptionsAnd(ArrayList<String> options = []) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment