diff --git a/ragconnect.base/src/main/jastadd/Analysis.jrag b/ragconnect.base/src/main/jastadd/Analysis.jrag index 769d283301b8fb29064c8030bfee6f9fb5e433da..1fc2e2f44baccd87c861eaad699d739866a3aae0 100644 --- a/ragconnect.base/src/main/jastadd/Analysis.jrag +++ b/ragconnect.base/src/main/jastadd/Analysis.jrag @@ -24,44 +24,37 @@ aspect Analysis { } // --- isAlreadyDefined --- - syn boolean TokenEndpointDefinition.isAlreadyDefined() { - java.util.List<TokenEndpointDefinition> definitions = lookupTokenEndpointDefinitions(getToken()); - java.util.Set<String> protocols = definitions - .stream() - .map(TokenEndpointDefinition::protocol) - .collect(java.util.stream.Collectors.toSet()); - return definitions.size() > protocols.size(); - } + syn boolean TokenEndpointDefinition.isAlreadyDefined() = lookupTokenEndpointDefinitions(getToken()).size() > 1; syn boolean DependencyDefinition.isAlreadyDefined() = lookupDependencyDefinition(getSource().containingTypeDecl(), getID()) != this; - // --- protocol --- - syn String TokenEndpointDefinition.protocol(); - eq ReceiveFromMqttDefinition.protocol() = "mqtt"; - eq SendToMqttDefinition.protocol() = "mqtt"; - eq ReceiveFromRestDefinition.protocol() = "rest"; - eq SendToRestDefinition.protocol() = "rest"; - - // --- usesPROTOCOL --- - syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty(); - syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty(); +// // --- protocol --- +// syn String TokenEndpointDefinition.protocol(); +// eq ReceiveFromMqttDefinition.protocol() = "mqtt"; +// eq SendToMqttDefinition.protocol() = "mqtt"; +// eq ReceiveFromRestDefinition.protocol() = "rest"; +// eq SendToRestDefinition.protocol() = "rest"; - // --- mqttEndpointDefinitions --- - coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; - ReceiveFromMqttDefinition contributes this - to RagConnect.mqttEndpointDefinitions() - for ragconnect(); - SendToMqttDefinition contributes this - to RagConnect.mqttEndpointDefinitions() - for ragconnect(); +// // --- usesPROTOCOL --- +// syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty(); +// syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty(); - // --- restEndpointDefinitions --- - coll java.util.List<TokenEndpointDefinition> RagConnect.restEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; - ReceiveFromRestDefinition contributes this - to RagConnect.restEndpointDefinitions() - for ragconnect(); - SendToRestDefinition contributes this - to RagConnect.restEndpointDefinitions() - for ragconnect(); +// // --- mqttEndpointDefinitions --- +// coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; +// ReceiveFromMqttDefinition contributes this +// to RagConnect.mqttEndpointDefinitions() +// for ragconnect(); +// SendToMqttDefinition contributes this +// to RagConnect.mqttEndpointDefinitions() +// for ragconnect(); +// +// // --- restEndpointDefinitions --- +// coll java.util.List<TokenEndpointDefinition> RagConnect.restEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; +// ReceiveFromRestDefinition contributes this +// to RagConnect.restEndpointDefinitions() +// for ragconnect(); +// SendToRestDefinition contributes this +// to RagConnect.restEndpointDefinitions() +// for ragconnect(); syn boolean MappingDefinitionType.assignableTo(JavaTypeUse target); eq JavaMappingDefinitionType.assignableTo(JavaTypeUse target) = getType().assignableTo(target); diff --git a/ragconnect.base/src/main/jastadd/MustacheNodes.relast b/ragconnect.base/src/main/jastadd/MustacheNodes.relast index d2d611798005c45e810ebfeddfa6c767b36167e4..ceead524746145c07d1ea980bcd534e25979073b 100644 --- a/ragconnect.base/src/main/jastadd/MustacheNodes.relast +++ b/ragconnect.base/src/main/jastadd/MustacheNodes.relast @@ -1,7 +1,7 @@ //TypeComponentMustache ; //rel TypeComponentMustache.TypeComponent -> TypeComponent ; -MRagConnect ::= ReceiveDefinition:MReceiveDefinition* PushSendDefinition:MSendDefinition* PullSendDefinition:MSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*; +MRagConnect ::= ReceiveDefinition:MReceiveDefinition* SendDefinition:MSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*; abstract MEndpointDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*; MReceiveDefinition : MEndpointDefinition; MSendDefinition : MEndpointDefinition; diff --git a/ragconnect.base/src/main/jastadd/RagConnect.relast b/ragconnect.base/src/main/jastadd/RagConnect.relast index 2729b85c23a87725a954e00d303caf1414cf9267..accc617714ff6bdd24a22831ea84e5d93e6a15b8 100644 --- a/ragconnect.base/src/main/jastadd/RagConnect.relast +++ b/ragconnect.base/src/main/jastadd/RagConnect.relast @@ -7,13 +7,8 @@ rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*; abstract TokenEndpointDefinition : EndpointDefinition; rel TokenEndpointDefinition.Token -> TokenComponent; -abstract ReceiveTokenEndpointDefinition : TokenEndpointDefinition; -abstract SendTokenEndpointDefinition : TokenEndpointDefinition; - -ReceiveFromMqttDefinition : ReceiveTokenEndpointDefinition; -SendToMqttDefinition : SendTokenEndpointDefinition; -ReceiveFromRestDefinition : ReceiveTokenEndpointDefinition; -SendToRestDefinition : SendTokenEndpointDefinition; +ReceiveTokenEndpointDefinition : TokenEndpointDefinition; +SendTokenEndpointDefinition : TokenEndpointDefinition; DependencyDefinition ::= <ID>; rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*; diff --git a/ragconnect.base/src/main/jastadd/backend/Configuration.jadd b/ragconnect.base/src/main/jastadd/backend/Configuration.jadd index d4f5b43f27cb329f1ff82318c6f383f0f69ebbd6..8d3b16c3f99014408c6aefa5655201d222c3d892 100644 --- a/ragconnect.base/src/main/jastadd/backend/Configuration.jadd +++ b/ragconnect.base/src/main/jastadd/backend/Configuration.jadd @@ -2,4 +2,6 @@ aspect Configuration { public static boolean ASTNode.loggingEnabledForReads = false; public static boolean ASTNode.loggingEnabledForWrites = false; public static TypeDecl ASTNode.rootNode; + public static boolean ASTNode.usesMqtt; + public static boolean ASTNode.usesRest; } diff --git a/ragconnect.base/src/main/jastadd/backend/Generation.jadd b/ragconnect.base/src/main/jastadd/backend/Generation.jadd index ff948334b793fc4930585ee5705285187b7c2606..0bb7e85f7a8f3486c2dd1900e1c800d77aead1d1 100644 --- a/ragconnect.base/src/main/jastadd/backend/Generation.jadd +++ b/ragconnect.base/src/main/jastadd/backend/Generation.jadd @@ -34,25 +34,24 @@ aspect AttributesForMustache { eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField(); eq MRagConnect.getRootTypeComponent(int i).isFirst() = i == 0; - syn boolean MRagConnect.usesMqtt() = getRagConnect().usesMqtt(); + syn String MRagConnect.closeMethod() = "ragconnectCloseConnections"; +// syn boolean MRagConnect.usesMqtt() = getRagConnect().usesMqtt(); syn String MRagConnect.mqttHandlerAttribute() = "_mqttHandler"; syn String MRagConnect.mqttHandlerField() = "_mqttHandler"; - syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost"; - syn String MRagConnect.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady"; - syn String MRagConnect.mqttCloseMethod() = "MqttCloseConnections"; +// syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost"; + syn String MRagConnect.mqttSetupWaitUntilReadyMethod() = "ragconnectSetupMqttWaitUntilReady"; - syn boolean MRagConnect.usesRest() = getRagConnect().usesRest(); +// syn boolean MRagConnect.usesRest() = getRagConnect().usesRest(); syn String MRagConnect.restHandlerAttribute() = "_restHandler"; syn String MRagConnect.restHandlerField() = "_restHandler"; - syn String MRagConnect.restSetPortMethod() = "RestSetPort"; - syn String MRagConnect.restCloseMethod() = "RestCloseConnections"; +// syn String MRagConnect.restSetPortMethod() = "RestSetPort"; // --- MEndpointDefinition --- syn String MEndpointDefinition.preemptiveExpectedValue(); syn String MEndpointDefinition.preemptiveReturn(); syn TokenEndpointDefinition MEndpointDefinition.endpointDef(); syn String MEndpointDefinition.firstInputVarName(); - syn String MEndpointDefinition.newConnectionMethod(); +// syn String MEndpointDefinition.newConnectionMethod(); eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1; eq MEndpointDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix(); @@ -61,21 +60,21 @@ aspect AttributesForMustache { inh String MEndpointDefinition.mqttHandlerAttribute(); inh String MEndpointDefinition.restHandlerAttribute(); - syn String MEndpointDefinition.connectParameterName() { - switch (endpointDef().protocol()) { - case "mqtt": return "topic"; - case "rest": return "path"; - default: return null; - } - } - syn String MEndpointDefinition.handlerAttribute() { - switch (endpointDef().protocol()) { - case "mqtt": return mqttHandlerAttribute(); - case "rest": return restHandlerAttribute(); - default: return null; - } - } - syn String MEndpointDefinition.connectMethod() = "connect" + tokenName() + (ragconnect().lookupTokenEndpointDefinitions(token()).size() > 1 ? "Via" + capitalize(endpointDef().protocol()) : ""); + syn String MEndpointDefinition.connectParameterName() = "uriString"; +// switch (endpointDef().protocol()) { +// case "mqtt": return "topic"; +// case "rest": return "path"; +// default: return null; +// } +// } +// syn String MEndpointDefinition.handlerAttribute() { +// switch (endpointDef().protocol()) { +// case "mqtt": return mqttHandlerAttribute(); +// case "rest": return restHandlerAttribute(); +// default: return null; +// } +// } + syn String MEndpointDefinition.connectMethod() = "connect" + tokenName(); syn TokenComponent MEndpointDefinition.token() = endpointDef().getToken(); syn boolean MEndpointDefinition.alwaysApply() = endpointDef().getAlwaysApply(); syn String MEndpointDefinition.resultVarPrefix() = "result"; // we do not need "_" here, because methodName begins with one @@ -112,39 +111,39 @@ aspect AttributesForMustache { eq MReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition(); eq MReceiveDefinition.firstInputVarName() = "message"; - syn String MReceiveDefinition.newConnectionMethod() { - switch (endpointDef().protocol()) { - case "mqtt": return "newConnection"; - case "rest": return "newPUTConnection"; - default: return null; - } - } +// syn String MReceiveDefinition.newConnectionMethod() { +// switch (endpointDef().protocol()) { +// case "mqtt": return "newConnection"; +// case "rest": return "newPUTConnection"; +// default: return null; +// } +// } // --- MSendDefinition --- eq MSendDefinition.preemptiveExpectedValue() = lastValue(); - eq MSendDefinition.preemptiveReturn() { - switch (endpointDef().protocol()) { - case "mqtt": return "return false;"; - case "rest": return "throw e;"; // e is Exception variable - default: return null; - } - } + eq MSendDefinition.preemptiveReturn() = "return false;"; +// switch (endpointDef().protocol()) { +// case "mqtt": return "return false;"; +// case "rest": return "throw e;"; // e is Exception variable +// default: return null; +// } +// } eq MSendDefinition.endpointDef() = getSendTokenEndpointDefinition(); eq MSendDefinition.firstInputVarName() = "get" + tokenName() + "()"; - syn String MSendDefinition.sendTopic() = "_topic_" + tokenName(); + syn String MSendDefinition.sender() = "_sender_" + tokenName(); syn String MSendDefinition.lastValue() = "_lastValue" + tokenName(); syn String MSendDefinition.updateMethod() = "_update_" + tokenName(); syn String MSendDefinition.writeMethod() = "_writeLastValue_" + tokenName(); syn String MSendDefinition.tokenResetMethod() = "get" + tokenName() + "_reset"; - syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush(); - syn String MSendDefinition.newConnectionMethod() { - switch (endpointDef().protocol()) { - case "mqtt": return null; - case "rest": return "newGETConnection"; - default: return null; - } - } +// syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush(); +// syn String MSendDefinition.newConnectionMethod() { +// switch (endpointDef().protocol()) { +// case "mqtt": return null; +// case "rest": return "newGETConnection"; +// default: return null; +// } +// } // --- MMappingDefinition --- syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint(); @@ -182,11 +181,7 @@ aspect AttributesForMustache { for (EndpointDefinition def : getEndpointDefinitionList()) { if (def.isSendTokenEndpointDefinition()) { SendTokenEndpointDefinition sendDef = def.asSendTokenEndpointDefinition(); - if (sendDef.isPush()) { - result.addPushSendDefinition(sendDef.toMustache()); - } else { - result.addPullSendDefinition(sendDef.toMustache()); - } + result.addSendDefinition(sendDef.toMustache()); } else { result.addReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache()); } @@ -257,9 +252,9 @@ aspect AttributesForMustache { aspect AspectGeneration { - syn boolean SendTokenEndpointDefinition.isPush(); - eq SendToMqttDefinition.isPush() = true; - eq SendToRestDefinition.isPush() = false; +// syn boolean SendTokenEndpointDefinition.isPush(); +// eq SendToMqttDefinition.isPush() = true; +// eq SendToRestDefinition.isPush() = false; // --- rootNodeName --- syn String ASTNode.rootNodeName() = rootNode.getName(); diff --git a/ragconnect.base/src/main/jastadd/backend/Mappings.jrag b/ragconnect.base/src/main/jastadd/backend/Mappings.jrag index 0410cc289d9e69fc27b343ac162cdd6b60bcb9d5..fb1239bfdd8e7ca0af60ea2382eff8dcfb22ed60 100644 --- a/ragconnect.base/src/main/jastadd/backend/Mappings.jrag +++ b/ragconnect.base/src/main/jastadd/backend/Mappings.jrag @@ -116,10 +116,8 @@ aspect Mappings { // --- isSuitableEdgeMapping(def) --- syn boolean TokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def); - eq ReceiveFromMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray(); - eq SendToMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray(); - eq ReceiveFromRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isString(); - eq SendToRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isString(); + eq ReceiveTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray(); + eq SendTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray(); // --- isPrimitiveType --- syn boolean TokenComponent.isPrimitiveType() = effectiveJavaTypeUse().isPrimitiveType(); @@ -145,9 +143,9 @@ aspect Mappings { // --- suitableDefaultMapping --- syn DefaultMappingDefinition EndpointDefinition.suitableDefaultMapping(); - eq ReceiveFromMqttDefinition.suitableDefaultMapping() { + eq ReceiveTokenEndpointDefinition.suitableDefaultMapping() { String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : + getToken().effectiveJavaTypeUse().getName() : getMappingList().get(0).getFromType().prettyPrint(); switch(typeName) { case "int": @@ -166,9 +164,9 @@ aspect Mappings { default: return null; } } - eq SendToMqttDefinition.suitableDefaultMapping() { + eq SendTokenEndpointDefinition.suitableDefaultMapping() { String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : + getToken().effectiveJavaTypeUse().getName() : getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); switch(typeName) { case "int": @@ -187,54 +185,54 @@ aspect Mappings { default: return null; } } - eq ReceiveFromRestDefinition.suitableDefaultMapping() { - String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : - getMappingList().get(0).getFromType().prettyPrint(); - switch(typeName) { - case "int": - case "Integer": return ragconnect().defaultStringToIntMapping(); - case "short": - case "Short": return ragconnect().defaultStringToShortMapping(); - case "long": - case "Long": return ragconnect().defaultStringToLongMapping(); - case "float": - case "Float": return ragconnect().defaultStringToFloatMapping(); - case "double": - case "Double": return ragconnect().defaultStringToDoubleMapping(); - case "char": - case "Character": return ragconnect().defaultStringToCharMapping(); - default: return null; - } - } - eq SendToRestDefinition.suitableDefaultMapping() { - String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : - getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); - switch(typeName) { - case "int": - case "Integer": return ragconnect().defaultIntToStringMapping(); - case "short": - case "Short": return ragconnect().defaultShortToStringMapping(); - case "long": - case "Long": return ragconnect().defaultLongToStringMapping(); - case "float": - case "Float": return ragconnect().defaultFloatToStringMapping(); - case "double": - case "Double": return ragconnect().defaultDoubleToStringMapping(); - case "char": - case "Character": return ragconnect().defaultCharToStringMapping(); - default: return null; - } - } +// eq ReceiveFromRestDefinition.suitableDefaultMapping() { +// String typeName = getMappingList().isEmpty() ? +// getToken().getJavaTypeUse().getName() : +// getMappingList().get(0).getFromType().prettyPrint(); +// switch(typeName) { +// case "int": +// case "Integer": return ragconnect().defaultStringToIntMapping(); +// case "short": +// case "Short": return ragconnect().defaultStringToShortMapping(); +// case "long": +// case "Long": return ragconnect().defaultStringToLongMapping(); +// case "float": +// case "Float": return ragconnect().defaultStringToFloatMapping(); +// case "double": +// case "Double": return ragconnect().defaultStringToDoubleMapping(); +// case "char": +// case "Character": return ragconnect().defaultStringToCharMapping(); +// default: return null; +// } +// } +// eq SendToRestDefinition.suitableDefaultMapping() { +// String typeName = getMappingList().isEmpty() ? +// getToken().getJavaTypeUse().getName() : +// getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); +// switch(typeName) { +// case "int": +// case "Integer": return ragconnect().defaultIntToStringMapping(); +// case "short": +// case "Short": return ragconnect().defaultShortToStringMapping(); +// case "long": +// case "Long": return ragconnect().defaultLongToStringMapping(); +// case "float": +// case "Float": return ragconnect().defaultFloatToStringMapping(); +// case "double": +// case "Double": return ragconnect().defaultDoubleToStringMapping(); +// case "char": +// case "Character": return ragconnect().defaultCharToStringMapping(); +// default: return null; +// } +// } // --- isByteArray --- syn boolean MappingDefinitionType.isByteArray() = false; eq JavaArrayMappingDefinitionType.isByteArray() = getType().getName().equals("byte"); - // --- isString --- - syn boolean MappingDefinitionType.isString() = false; - eq JavaMappingDefinitionType.isString() = getType().getName().equals("String"); +// // --- isString --- +// syn boolean MappingDefinitionType.isString() = false; +// eq JavaMappingDefinitionType.isString() = getType().getName().equals("String"); // --- allMappingDefinitions --- syn java.util.List<MappingDefinition> RagConnect.allMappingDefinitions() { @@ -255,19 +253,19 @@ aspect Mappings { result.add(defaultDoubleToBytesMapping()); result.add(defaultCharToBytesMapping()); result.add(defaultStringToBytesMapping()); - // string conversion - result.add(defaultStringToIntMapping()); - result.add(defaultStringToShortMapping()); - result.add(defaultStringToLongMapping()); - result.add(defaultStringToFloatMapping()); - result.add(defaultStringToDoubleMapping()); - result.add(defaultStringToCharMapping()); - result.add(defaultIntToStringMapping()); - result.add(defaultShortToStringMapping()); - result.add(defaultLongToStringMapping()); - result.add(defaultFloatToStringMapping()); - result.add(defaultDoubleToStringMapping()); - result.add(defaultCharToStringMapping()); +// // string conversion +// result.add(defaultStringToIntMapping()); +// result.add(defaultStringToShortMapping()); +// result.add(defaultStringToLongMapping()); +// result.add(defaultStringToFloatMapping()); +// result.add(defaultStringToDoubleMapping()); +// result.add(defaultStringToCharMapping()); +// result.add(defaultIntToStringMapping()); +// result.add(defaultShortToStringMapping()); +// result.add(defaultLongToStringMapping()); +// result.add(defaultFloatToStringMapping()); +// result.add(defaultDoubleToStringMapping()); +// result.add(defaultCharToStringMapping()); return result; } } diff --git a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser index 56a8dc4cc7f3396e778a529e981c1aefb302e18b..0432b0df96c44060f6df1d6918a856f62810230d 100644 --- a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser +++ b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser @@ -31,12 +31,8 @@ EndpointDefinition endpoint_definition ; EndpointDefinition endpoint_definition_type - = RECEIVE token_ref {: return new ReceiveFromMqttDefinition().setToken(token_ref); :} - | RECEIVE token_ref VIA MQTT {: return new ReceiveFromMqttDefinition().setToken(token_ref); :} - | RECEIVE token_ref VIA REST {: return enableAlwaysApply(new ReceiveFromRestDefinition()).setToken(token_ref); :} - | SEND token_ref {: return new SendToMqttDefinition().setToken(token_ref); :} - | SEND token_ref VIA MQTT {: return new SendToMqttDefinition().setToken(token_ref); :} - | SEND token_ref VIA REST {: return enableAlwaysApply(new SendToRestDefinition()).setToken(token_ref); :} + = RECEIVE token_ref {: return new ReceiveTokenEndpointDefinition().setToken(token_ref); :} + | SEND token_ref {: return new SendTokenEndpointDefinition().setToken(token_ref); :} ; TokenComponent token_ref diff --git a/ragconnect.base/src/main/jastadd/scanner/Keywords.flex b/ragconnect.base/src/main/jastadd/scanner/Keywords.flex index fe8a8141140884f7c53295f76877dd277c41ac4c..5773118d8fda8ffdc536b504aa7056b8784ddfb3 100644 --- a/ragconnect.base/src/main/jastadd/scanner/Keywords.flex +++ b/ragconnect.base/src/main/jastadd/scanner/Keywords.flex @@ -5,6 +5,3 @@ "maps" { return sym(Terminals.MAPS); } "to" { return sym(Terminals.TO); } "as" { return sym(Terminals.AS); } -"via" { return sym(Terminals.VIA); } -"mqtt" { return sym(Terminals.MQTT); } -"rest" { return sym(Terminals.REST); } diff --git a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java index 5160ab6611f8a8f177555e55e511153b95a9659b..d44ef9e590abd09d3c7d7026c3da2dfe5f29511b 100644 --- a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java +++ b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java @@ -20,10 +20,14 @@ public class Compiler extends AbstractCompiler { // private ValueOption optionOutputDir; private ValueOption optionRootNode; + private ValueOption optionProtocols; private BooleanOption optionVerbose; private BooleanOption optionLogReads; private BooleanOption optionLogWrites; + private static final String OPTION_PROTOCOL_MQTT = "mqtt"; + private static final String OPTION_PROTOCOL_REST = "rest"; + public Compiler() { super("ragconnect", true); } @@ -61,10 +65,10 @@ public class Compiler extends AbstractCompiler { printMessage("Writing output files"); final List<String> handlers = new ArrayList<>(); - if (ragConnect.usesMqtt()) { + if (ASTNode.usesMqtt) { handlers.add("MqttHandler.jadd"); } - if (ragConnect.usesRest()) { + if (ASTNode.usesRest) { handlers.add("RestHandler.jadd"); } // copy handlers into outputDir @@ -138,6 +142,12 @@ public class Compiler extends AbstractCompiler { new ValueOption("rootNode", "root node in the base grammar.") .acceptAnyValue() .needsValue(true)); + optionProtocols = addOption( + new ValueOption("protocols", "Protocols to enable") + .acceptMultipleValues(true) + .addDefaultValue(OPTION_PROTOCOL_MQTT, "Enable MQTT") + .addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST") + ); optionVerbose = addOption( new BooleanOption("verbose", "Print more messages while compiling.") .defaultValue(false)); @@ -181,6 +191,8 @@ public class Compiler extends AbstractCompiler { ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration); ASTNode.loggingEnabledForReads = optionLogReads.value(); ASTNode.loggingEnabledForWrites = optionLogWrites.value(); + ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT); + ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST); return ragConnect; } diff --git a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java deleted file mode 100644 index 9da13bf479b6fe16be8c935b06cf1e9ad3283308..0000000000000000000000000000000000000000 --- a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.jastadd.ragconnect.compiler; - -import beaver.Parser; -import org.jastadd.ragconnect.ast.*; -import org.jastadd.ragconnect.parser.RagConnectParser; -import org.jastadd.ragconnect.scanner.RagConnectScanner; - -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * Testing Ros2Rag without parser. - * - * @author rschoene - Initial contribution - */ -public class SimpleMain { - - // --- just testing byte[] conversion --- - public static void testing() { - System.out.println("---"); - try { - Class<?> clazz = Class.forName("java.util.List"); - System.out.println("clazz.getName() = " + clazz.getName()); - System.out.println(Integer.class.isAssignableFrom(Integer.class)); - System.out.println(new SimpleJavaTypeUse("int").assignableTo(new SimpleJavaTypeUse("Integer"))); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - System.out.println("---"); - - byte[] bytes; - int i = 1; - double d = 2.3d; - float f = 4.2f; - short sh = 13; - long l = 7L; - String s = "Hello"; - char c = 'a'; - - Integer ii = Integer.valueOf(1); - if (!ii.equals(i)) throw new AssertionError("Ints not equal"); - - // int to byte - ByteBuffer i2b = ByteBuffer.allocate(4); - i2b.putInt(i); - bytes = i2b.array(); - - // byte to int - ByteBuffer b2i = ByteBuffer.wrap(bytes); - int actual_i = b2i.getInt(); - if (i != actual_i) throw new AssertionError("Ints not equal"); - - // double to byte - ByteBuffer d2b = ByteBuffer.allocate(8); - d2b.putDouble(d); - bytes = d2b.array(); - - // byte to double - ByteBuffer b2d = ByteBuffer.wrap(bytes); - double actual_d = b2d.getDouble(); - if (d != actual_d) throw new AssertionError("Doubles not equal"); - - // float to byte - ByteBuffer f2b = ByteBuffer.allocate(4); - f2b.putFloat(f); - bytes = f2b.array(); - - // byte to float - ByteBuffer b2f = ByteBuffer.wrap(bytes); - float actual_f = b2f.getFloat(); - if (f != actual_f) throw new AssertionError("Floats not equal"); - - // short to byte - ByteBuffer sh2b = ByteBuffer.allocate(2); - sh2b.putShort(sh); - bytes = sh2b.array(); - - // byte to short - ByteBuffer b2sh = ByteBuffer.wrap(bytes); - short actual_sh = b2sh.getShort(); - if (sh != actual_sh) throw new AssertionError("Shorts not equal"); - - // long to byte - ByteBuffer l2b = ByteBuffer.allocate(8); - l2b.putLong(l); - bytes = l2b.array(); - - // byte to long - ByteBuffer b2l = ByteBuffer.wrap(bytes); - long actual_l = b2l.getLong(); - if (l != actual_l) throw new AssertionError("Longs not equal"); - - // String to byte - bytes = s.getBytes(); - - // byte to String - String actual_s = new String(bytes); - if (!s.equals(actual_s)) throw new AssertionError("Strings not equal"); - - // char to byte - ByteBuffer c2b = ByteBuffer.allocate(2); - c2b.putChar(c); - bytes = c2b.array(); - - // byte to char - ByteBuffer b2c = ByteBuffer.wrap(bytes); - char actual_c = b2c.getChar(); - if (c != actual_c) throw new AssertionError("Floats not equal"); - } - - public static void main(String[] args) { - testing(); -// createManualAST(); - } - - private static void createManualAST() { - RagConnect model = new RagConnect(); - Program program = parseProgram(Paths.get("ros2rag.starter","src", "main", "jastadd", "RobotModel.relast")); - model.setProgram(program); - - MappingDefinition mappingDefinition = new MappingDefinition(); - mappingDefinition.setID("PoseToPosition"); - mappingDefinition.setFromType(makeMappingDefinitionType("int")); - mappingDefinition.setFromVariableName("x"); - mappingDefinition.setToType(makeMappingDefinitionType("Position")); - mappingDefinition.setContent(" pose.position.x += sqrt(.5 * size.x)\n" + - " MAP round(2)\n" + - " x = x / 100\n" + - " IGNORE_IF_SAME\n" + - " ;"); - model.addMappingDefinition(mappingDefinition); - - ReceiveFromMqttDefinition receiveFromMqttDefinition = new ReceiveFromMqttDefinition(); - receiveFromMqttDefinition.setAlwaysApply(false); - receiveFromMqttDefinition.setToken(TokenComponent.createRef("Link.CurrentPosition")); - receiveFromMqttDefinition.addMapping(mappingDefinition); - model.addEndpointDefinition(receiveFromMqttDefinition); - - model.treeResolveAll(); - for (ErrorMessage error : model.errors()) { - System.err.println(error); - } - - System.out.println(model.generateAspect("Model")); - } - - private static MappingDefinitionType makeMappingDefinitionType(String type) { - JavaMappingDefinitionType result = new JavaMappingDefinitionType(); - result.setType(new SimpleJavaTypeUse(type)); - return result; - } - - private static Program parseProgram(Path path) { - try (BufferedReader reader = Files.newBufferedReader(path)) { - RagConnectScanner scanner = new RagConnectScanner(reader); - RagConnectParser parser = new RagConnectParser(); - GrammarFile grammarFile = (GrammarFile) parser.parse(scanner); - Program program = new Program(); - program.addGrammarFile(grammarFile); - return program; - } catch (IOException | Parser.Exception e) { - e.printStackTrace(); - } - return null; - } -} diff --git a/ragconnect.base/src/main/resources/MqttHandler.jadd b/ragconnect.base/src/main/resources/MqttHandler.jadd index 1161211ffb0b90eaf26c7d27d709d71f7a6369c8..6f40612520cfb97151600dff53c8e0d384ab441e 100644 --- a/ragconnect.base/src/main/resources/MqttHandler.jadd +++ b/ragconnect.base/src/main/resources/MqttHandler.jadd @@ -1,4 +1,73 @@ -aspect MqttHandler { +import java.io.IOException; +import java.util.concurrent.TimeUnit;aspect MqttHandler { +public class MqttServerHandler { + private final java.util.Map<String, MqttHandler> handlers = new java.util.HashMap<>(); + private long time; + private java.util.concurrent.TimeUnit unit; + private String name; + + public MqttServerHandler() { + this("RagConnect"); + } + + public MqttServerHandler(String name) { + this.name = name; + setupWaitUntilReady(1, TimeUnit.SECONDS); + } + + public void setupWaitUntilReady(long time, java.util.concurrent.TimeUnit unit) { + this.time = time; + this.unit = unit; + } + + public MqttHandler resolveHandler(java.net.URI uri) throws IOException { + MqttHandler handler = handlers.get(uri.getHost()); + if (handler == null) { + // first connect to that server + handler = new MqttHandler(); + if (uri.getPort() == -1) { + handler.setHost(uri.getHost()); + } else { + handler.setHost(uri.getHost(), uri.getPort()); + } + handlers.put(uri.getHost(), handler); + } + handler.waitUntilReady(this.time, this.unit); + return handler; + } + + public boolean newConnection(java.net.URI uri, java.util.function.Consumer<byte[]> callback) throws IOException { + return resolveHandler(uri).newConnection(extractTopic(uri), callback); + } + + public void publish(java.net.URI uri, byte[] bytes) throws IOException { + resolveHandler(uri).publish(extractTopic(uri), bytes); + } + + public void publish(java.net.URI uri, byte[] bytes, boolean retain) throws IOException { + resolveHandler(uri).publish(extractTopic(uri), bytes, retain); + } + + public void publish(java.net.URI uri, byte[] bytes, + org.fusesource.mqtt.client.QoS qos, boolean retain) throws IOException { + resolveHandler(uri).publish(extractTopic(uri), bytes, qos, retain); + } + + private String extractTopic(java.net.URI uri) { + String path = uri.getPath(); + if (path.charAt(0) == '/') { + path = path.substring(1); + } + return path; + } + + public void close() { + for (MqttHandler handler : handlers.values()) { + handler.close(); + } + } + +} /** * Helper class to receive updates via MQTT and use callbacks to handle those messages. * @@ -14,10 +83,8 @@ public class MqttHandler { private java.net.URI host; /** The connection to the MQTT broker. */ private org.fusesource.mqtt.client.CallbackConnection connection; - /** Whether we are subscribed to the topics yet */ - private final java.util.concurrent.locks.Condition readyCondition; - private final java.util.concurrent.locks.Lock readyLock; - private boolean ready; + /** Whether we are connected yet */ + private final java.util.concurrent.CountDownLatch readyLatch; private boolean sendWelcomeMessage = true; private org.fusesource.mqtt.client.QoS qos; /** Dispatch knowledge */ @@ -31,9 +98,7 @@ public class MqttHandler { this.name = java.util.Objects.requireNonNull(name, "Name must be set"); this.logger = org.apache.logging.log4j.LogManager.getLogger(MqttHandler.class); this.callbacks = new java.util.HashMap<>(); - this.readyLock = new java.util.concurrent.locks.ReentrantLock(); - this.readyCondition = readyLock.newCondition(); - this.ready = false; + this.readyLatch = new java.util.concurrent.CountDownLatch(1); this.qos = org.fusesource.mqtt.client.QoS.AT_LEAST_ONCE; } @@ -144,13 +209,7 @@ public class MqttHandler { } private void setReady() { - try { - readyLock.lock(); - ready = true; - readyCondition.signalAll(); - } finally { - readyLock.unlock(); - } + readyLatch.countDown(); } private void throwIf(java.util.concurrent.atomic.AtomicReference<Throwable> error) throws java.io.IOException { @@ -163,12 +222,15 @@ public class MqttHandler { this.qos = qos; } - public void newConnection(String topic, java.util.function.Consumer<byte[]> callback) { - if (!ready) { - // should maybe be something more kind than throwing an exception here - throw new IllegalStateException("Updater not ready"); + public boolean newConnection(String topic, java.util.function.Consumer<byte[]> callback) { + if (readyLatch.getCount() > 0) { + System.err.println("Handler not ready"); + return false; +// // should maybe be something more kind than throwing an exception here +// throw new IllegalStateException("Updater not ready"); } // register callback + logger.debug("new connection for {}", topic); if (callbacks.get(topic) == null) { callbacks.put(topic, new java.util.ArrayList<>()); @@ -189,6 +251,7 @@ public class MqttHandler { }); } callbacks.get(topic).add(callback); + return true; } /** @@ -202,15 +265,9 @@ public class MqttHandler { */ public boolean waitUntilReady(long time, java.util.concurrent.TimeUnit unit) { try { - readyLock.lock(); - if (ready) { - return true; - } - return readyCondition.await(time, unit); + return readyLatch.await(time, unit); } catch (InterruptedException e) { e.printStackTrace(); - } finally { - readyLock.unlock(); } return false; } @@ -253,7 +310,7 @@ public class MqttHandler { @Override public void onFailure(Throwable value) { - logger.warn("Could not publish on topic '{}'", topic); + logger.warn("Could not publish on topic '{}'", topic, value); } }); }); diff --git a/ragconnect.base/src/main/resources/RestHandler.jadd b/ragconnect.base/src/main/resources/RestHandler.jadd index 24118f04c563fe0b44105bfe674e269c76e7466f..f7b1a83304fe7aaebe97d105514c3f192d052aec 100644 --- a/ragconnect.base/src/main/resources/RestHandler.jadd +++ b/ragconnect.base/src/main/resources/RestHandler.jadd @@ -1,4 +1,45 @@ -aspect RestHandler { +import java.util.concurrent.TimeUnit;aspect RestHandler { +public class RestServerHandler { + private static final int DEFAULT_PORT = 4567; + private final java.util.Map<Integer, RestHandler> handlers = new java.util.HashMap<>(); + private String name; + + public RestServerHandler() { + this("RagConnect"); + } + + public RestServerHandler(String name) { + this.name = name; + } + + private RestHandler resolveHandler(java.net.URI uri) { + int port = uri.getPort() != -1 ? uri.getPort() : DEFAULT_PORT; + RestHandler handler = handlers.get(port); + if (handler == null) { + // first connect to that server + handler = new RestHandler(); + handler.setPort(port); + handlers.put(port, handler); + } + return handler; + } + + public boolean newPUTConnection(java.net.URI uri, java.util.function.Consumer<String> callback) { + resolveHandler(uri).newPUTConnection(uri.getPath(), callback); + return true; + } + + public boolean newGETConnection(java.net.URI uri, SupplierWithException<String> supplier) { + resolveHandler(uri).newGETConnection(uri.getPath(), supplier); + return true; + } + + public void close() { + for (RestHandler handler : handlers.values()) { + handler.close(); + } + } +} /** * Helper class to receive updates and publishes information via REST. * @author rschoene - Initial contribution @@ -54,7 +95,7 @@ public class RestHandler { if (errors.isEmpty()) { return "OK"; } else { - return makeError(response, 500, errors.stream().collect(java.util.stream.Collectors.joining("\n", "The folloing errors happened: [", "]"))); + return makeError(response, 500, errors.stream().collect(java.util.stream.Collectors.joining("\n", "The following error(s) happened: [", "]"))); } }); } @@ -79,7 +120,7 @@ public class RestHandler { return message; } - public void start() { + private void start() { logger.info("Starting REST server at {}", this.port); spark.Spark.port(this.port); spark.Spark.init(); diff --git a/ragconnect.base/src/main/resources/handleUri.mustache b/ragconnect.base/src/main/resources/handleUri.mustache new file mode 100644 index 0000000000000000000000000000000000000000..a9187f8c610b258b9da28e86da818e13b57d29d5 --- /dev/null +++ b/ragconnect.base/src/main/resources/handleUri.mustache @@ -0,0 +1,11 @@ + String scheme,host, path; + java.net.URI uri; + try { + uri = new java.net.URI({{connectParameterName}}); + scheme = uri.getScheme(); + host = uri.getHost(); + path = uri.getPath(); + } catch (java.net.URISyntaxException e) { + System.err.println(e.getMessage()); // Maybe re-throw error? + return false; + } diff --git a/ragconnect.base/src/main/resources/handler.mustache b/ragconnect.base/src/main/resources/handler.mustache new file mode 100644 index 0000000000000000000000000000000000000000..e89c451007ff309a77297b9b66fe0e20dece73b8 --- /dev/null +++ b/ragconnect.base/src/main/resources/handler.mustache @@ -0,0 +1,7 @@ +aspect RagConnectHandler { +interface RagConnectHandler<T> { + boolean connectReceive(String path, java.util.function.Consumer<T> callback); + boolean sendPush(String path, T value); + boolean connectSendPull(String path, SupplierWithException<T> supplier); +} +} diff --git a/ragconnect.base/src/main/resources/mqtt.mustache b/ragconnect.base/src/main/resources/mqtt.mustache index 95b253a9b4b4e46fda738a66499b8e2a7cc3707d..f10ae88139d958d2f4b0a8f4245b64b41e0f1003 100644 --- a/ragconnect.base/src/main/resources/mqtt.mustache +++ b/ragconnect.base/src/main/resources/mqtt.mustache @@ -1,26 +1,16 @@ aspect MQTT { private String {{rootNodeName}}.MqttName() { return "RagConnectMQTT"; } - private MqttHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttHandler(MqttName()); - public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host) throws java.io.IOException { - {{mqttHandlerField}}.setHost(host); - } - public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host, int port) throws java.io.IOException { - {{mqttHandlerField}}.setHost(host, port); - } - - public boolean {{rootNodeName}}.{{mqttWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) { - return {{mqttHandlerField}}.waitUntilReady(time, unit); - } + private MqttServerHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttServerHandler(MqttName()); - public void {{rootNodeName}}.{{mqttCloseMethod}}() { - {{mqttHandlerField}}.close(); + public void {{rootNodeName}}.{{mqttSetupWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) { + {{mqttHandlerField}}.setupWaitUntilReady(time, unit); } {{#getRootTypeComponents}} - {{#first}}inh MqttHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}} + {{#first}}inh MqttServerHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}} eq {{rootNodeName}}.get{{name}}().{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; {{/getRootTypeComponents}} {{^getRootTypeComponents}} - syn MqttHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; + syn MqttServerHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; {{/getRootTypeComponents}} } diff --git a/ragconnect.base/src/main/resources/ragconnect.mustache b/ragconnect.base/src/main/resources/ragconnect.mustache index 24e25418d07766f0ac881683080a622687ceff8e..5b12e3fae20555a7fe9055b226ca0cb96bcff8f5 100644 --- a/ragconnect.base/src/main/resources/ragconnect.mustache +++ b/ragconnect.base/src/main/resources/ragconnect.mustache @@ -1,21 +1,17 @@ -{{#usesMqtt}} - {{> mqtt}} -{{/usesMqtt}} -{{#usesRest}} - {{> rest}} -{{/usesRest}} +{{#usesMqtt}}{{> mqtt}}{{/usesMqtt}} +{{#usesRest}}{{> rest}}{{/usesRest}} aspect ROS2RAG { + public void {{rootNodeName}}.{{closeMethod}}() { + {{#usesMqtt}}{{mqttHandlerField}}.close();{{/usesMqtt}} + {{#usesRest}}{{restHandlerField}}.close();{{/usesRest}} + } {{#ReceiveDefinitions}} {{> receiveDefinition}} {{/ReceiveDefinitions}} - {{#PushSendDefinitions}} - {{> sendDefinitionPush}} - {{/PushSendDefinitions}} - - {{#PullSendDefinitions}} - {{> sendDefinitionPull}} - {{/PullSendDefinitions}} + {{#SendDefinitions}} + {{> sendDefinition}} + {{/SendDefinitions}} {{#MappingDefinitions}} {{> mappingDefinition}} diff --git a/ragconnect.base/src/main/resources/receiveDefinition.mustache b/ragconnect.base/src/main/resources/receiveDefinition.mustache index 31a08c737349b6c2d16f14a0fab50065d2c01a35..62e2bf6faf441fe7c6d700bb8b4daf6168196c3e 100644 --- a/ragconnect.base/src/main/resources/receiveDefinition.mustache +++ b/ragconnect.base/src/main/resources/receiveDefinition.mustache @@ -1,9 +1,23 @@ - public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) { - {{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, message -> { + public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) throws java.io.IOException { + {{>handleUri}} + java.util.function.Consumer<byte[]> consumer = message -> { {{> mappingApplication}} {{#loggingEnabledForReads}} System.out.println("[Receive] " + {{connectParameterName}} + " -> {{tokenName}} = " + {{lastResult}}); {{/loggingEnabledForReads}} set{{tokenName}}({{lastResult}}); - }); + }; + switch (scheme) { + {{#usesMqtt}} + case "mqtt": return {{mqttHandlerAttribute}}().newConnection(uri, consumer); + {{/usesMqtt}} + {{#usesRest}} + case "rest": return {{restHandlerAttribute}}().newPUTConnection(uri, input -> { + consumer.accept(input.getBytes()); + }); + {{/usesRest}} + default: + System.err.println("Unknown protocol '" + scheme + "'."); + return false; + } } diff --git a/ragconnect.base/src/main/resources/rest.mustache b/ragconnect.base/src/main/resources/rest.mustache index fb77601c38467e0f3f1bd1f01993db410670ce16..6bbde2be4d26e519635c85a6f39f9a18514bfb19 100644 --- a/ragconnect.base/src/main/resources/rest.mustache +++ b/ragconnect.base/src/main/resources/rest.mustache @@ -1,18 +1,12 @@ aspect REST { private String {{rootNodeName}}.RestName() { return "RagConnectREST"; } - private RestHandler {{rootNodeName}}.{{restHandlerField}} = new RestHandler(RestName()); - public void {{rootNodeName}}.{{restSetPortMethod}}(int port) { - {{restHandlerField}}.setPort(port); - } - public void {{rootNodeName}}.{{restCloseMethod}}() { - {{restHandlerField}}.close(); - } + private RestServerHandler {{rootNodeName}}.{{restHandlerField}} = new RestServerHandler(RestName()); {{#getRootTypeComponents}} - {{#first}}inh RestHandler ASTNode.{{restHandlerAttribute}}();{{/first}} + {{#first}}inh RestServerHandler ASTNode.{{restHandlerAttribute}}();{{/first}} eq {{rootNodeName}}.get{{name}}().{{restHandlerAttribute}}() = {{restHandlerField}}; {{/getRootTypeComponents}} {{^getRootTypeComponents}} - syn RestHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}}; + syn RestServerHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}}; {{/getRootTypeComponents}} } diff --git a/ragconnect.base/src/main/resources/sendDefinition.mustache b/ragconnect.base/src/main/resources/sendDefinition.mustache new file mode 100644 index 0000000000000000000000000000000000000000..517baab18824ead12ebca5f1d22901b3a960b0ba --- /dev/null +++ b/ragconnect.base/src/main/resources/sendDefinition.mustache @@ -0,0 +1,51 @@ + private Runnable {{parentTypeName}}.{{sender}} = null; + private byte[] {{parentTypeName}}.{{lastValue}} = null; + + public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) { + {{>handleUri}} + switch (scheme) { + {{#usesMqtt}} + case "mqtt": + // MqttHandler handler = {{mqttHandlerAttribute}}().resolveHandler(uri);{{!optimize later}} + {{sender}} = () -> { + {{#loggingEnabledForWrites}} + System.out.println("[Send] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{connectParameterName}}); + {{/loggingEnabledForWrites}} + try { + {{mqttHandlerAttribute}}().publish(uri, {{lastValue}}); + } catch (java.io.IOException e) { + e.printStackTrace(); + } + }; + {{updateMethod}}(); + if (writeCurrentValue) { + {{writeMethod}}(); + } + break; + {{/usesMqtt}} + {{#usesRest}} + case "rest": + {{restHandlerAttribute}}().newGETConnection(uri, () -> { + {{updateMethod}}(); + return new String({{lastValue}}); + }); + break; + {{/usesRest}} + default: + System.err.println("Unknown protocol '" + scheme + "'."); + return false; + } + return true; + } + + protected boolean {{parentTypeName}}.{{updateMethod}}() { + {{tokenResetMethod}}(); + {{> mappingApplication}} + {{lastValue}} = {{lastResult}}; + // normally we would return true here. unless no connect method was called so far to initialize {{sender}} yet + return {{sender}} != null; + } + + protected void {{parentTypeName}}.{{writeMethod}}() { + {{sender}}.run(); + } diff --git a/ragconnect.base/src/main/resources/sendDefinitionPull.mustache b/ragconnect.base/src/main/resources/sendDefinitionPull.mustache deleted file mode 100644 index 598846d86f9fc67167de7896f42c30cd0cfc3360..0000000000000000000000000000000000000000 --- a/ragconnect.base/src/main/resources/sendDefinitionPull.mustache +++ /dev/null @@ -1,7 +0,0 @@ - public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) { - {{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, () -> { - {{tokenResetMethod}}(); - {{> mappingApplication}} - return {{lastResult}}; - }); - } diff --git a/ragconnect.base/src/main/resources/sendDefinitionPush.mustache b/ragconnect.base/src/main/resources/sendDefinitionPush.mustache deleted file mode 100644 index 3f75b18274d687d306f7778f9846aeca592fa86f..0000000000000000000000000000000000000000 --- a/ragconnect.base/src/main/resources/sendDefinitionPush.mustache +++ /dev/null @@ -1,24 +0,0 @@ - private String {{parentTypeName}}.{{sendTopic}} = null; - private byte[] {{parentTypeName}}.{{lastValue}} = null; - - public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) { - {{sendTopic}} = {{connectParameterName}}; - {{updateMethod}}(); - if (writeCurrentValue) { - {{writeMethod}}(); - } - } - - protected boolean {{parentTypeName}}.{{updateMethod}}() { - {{tokenResetMethod}}(); - {{> mappingApplication}} - {{lastValue}} = {{lastResult}}; - return true; - } - - protected void {{parentTypeName}}.{{writeMethod}}() { - {{#loggingEnabledForWrites}} - System.out.println("[Send] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{sendTopic}}); - {{/loggingEnabledForWrites}} - {{handlerAttribute}}().publish({{sendTopic}}, {{lastValue}}); - } diff --git a/ragconnect.base/src/main/resources/tokenComponent.mustache b/ragconnect.base/src/main/resources/tokenComponent.mustache index 729f442aebfc67ee2bbf5e559a9946405a275260..7de943a37edd9358fec19e53575629a44e976cff 100644 --- a/ragconnect.base/src/main/resources/tokenComponent.mustache +++ b/ragconnect.base/src/main/resources/tokenComponent.mustache @@ -3,11 +3,11 @@ {{#DependencyDefinitions}} for ({{targetParentTypeName}} target : get{{internalRelationPrefix}}TargetList()) { {{#targetEndpointDefinition}} - {{#isPush}} + {{!#isPush}} if (target.{{updateMethod}}()) { target.{{writeMethod}}(); } - {{/isPush}} + {{!/isPush}} {{/targetEndpointDefinition}} } {{/DependencyDefinitions}} diff --git a/ragconnect.tests/build.gradle b/ragconnect.tests/build.gradle index 96b3d74270fae3c825621c5e5d199b6559105510..d638ec5001a8a58505045e37e480ac7c5d08079d 100644 --- a/ragconnect.tests/build.gradle +++ b/ragconnect.tests/build.gradle @@ -67,11 +67,9 @@ relastTest { compilerLocation = '../libs/relast.jar' } -sourceSets { - test { - java.srcDir "src/test/java-gen" - } -} +File genSrc = file("src/test/java-gen"); +sourceSets.test.java.srcDir genSrc +idea.module.generatedSourceDirs += genSrc clean { delete 'src/test/02-after-ragconnect/*/', 'src/test/03-after-relast/*/', 'src/test/java-gen/*/' @@ -249,6 +247,7 @@ task preprocessViaTest(type: JavaExec, group: 'verification') { 'src/test/01-input/via/Test.relast', 'src/test/01-input/via/Test.connect', '--rootNode=A', '--verbose', + '--protocols=mqtt,rest', '--logReads', '--logWrites' } diff --git a/ragconnect.tests/src/test/01-input/via/Test.connect b/ragconnect.tests/src/test/01-input/via/Test.connect index 938490169415b2ce8f3da325ae2a1c768030921f..e4d2862a651dd6e68f67d2a492b6105a15f0a77c 100644 --- a/ragconnect.tests/src/test/01-input/via/Test.connect +++ b/ragconnect.tests/src/test/01-input/via/Test.connect @@ -1,16 +1,15 @@ -receive A.Mqtt2MqttInput via mqtt using MarkMqttInput ; -receive A.Rest2RestInput via rest using MarkRestInput ; -receive A.Mqtt2RestInput via mqtt using MarkMqttInput ; -receive A.Rest2MqttInput via rest using MarkRestInput ; -receive A.Both2BothInput via mqtt using MarkMqttInput ; -receive A.Both2BothInput via rest using MarkRestInput ; +receive A.Mqtt2MqttInput using MarkMqttInput ; +receive A.Rest2RestInput using MarkRestInput ; +receive A.Mqtt2RestInput using MarkMqttInput ; +receive A.Rest2MqttInput using MarkRestInput ; +receive A.Both2BothInput ; -send A.Mqtt2MqttOutput via mqtt using MarkMqttOutput ; -send A.Rest2RestOutput via rest using MarkRestOutput ; -send A.Mqtt2RestOutput via rest using MarkRestOutput ; -send A.Rest2MqttOutput via mqtt using MarkMqttOutput ; -send A.Both2RestOutput via rest using MarkRestOutput ; -send A.Both2MqttOutput via mqtt using MarkMqttOutput ; +send A.Mqtt2MqttOutput using MarkMqttOutput ; +send A.Rest2RestOutput using MarkRestOutput ; +send A.Mqtt2RestOutput using MarkRestOutput ; +send A.Rest2MqttOutput using MarkMqttOutput ; +send A.Both2RestOutput using MarkRestOutput ; +send A.Both2MqttOutput using MarkMqttOutput ; A.Mqtt2MqttOutput canDependOn A.Mqtt2MqttInput as dependencyMqtt2Mqtt ; A.Rest2RestOutput canDependOn A.Rest2RestInput as dependencyRest2Rest ; diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java index 8482c308f29b8381bc698efac91c69e2e94a8d9f..3746ceb3eaf8c83671747000e1fbf70ff37b9e96 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; +import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -49,7 +50,7 @@ public class DefaultOnlyReadTest extends AbstractMqttTest { sender.close(); } if (model != null) { - model.MqttCloseConnections(); + model.ragconnectCloseConnections(); } } @@ -62,23 +63,21 @@ public class DefaultOnlyReadTest extends AbstractMqttTest { @Test public void communicate() throws IOException, InterruptedException { createModel(); - - model.MqttSetHost(TestUtils.getMqttHost()); - assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS)); - - integers.connectIntValue(TOPIC_NATIVE_INT); - integers.connectShortValue(TOPIC_NATIVE_SHORT); - integers.connectLongValue(TOPIC_NATIVE_LONG); - floats.connectFloatValue(TOPIC_NATIVE_FLOAT); - floats.connectDoubleValue(TOPIC_NATIVE_DOUBLE); - chars.connectCharValue(TOPIC_NATIVE_CHAR); - chars.connectStringValue(TOPIC_NATIVE_STRING); - allBoxed.connectIntValue(TOPIC_BOXED_INTEGER); - allBoxed.connectShortValue(TOPIC_BOXED_SHORT); - allBoxed.connectLongValue(TOPIC_BOXED_LONG); - allBoxed.connectFloatValue(TOPIC_BOXED_FLOAT); - allBoxed.connectDoubleValue(TOPIC_BOXED_DOUBLE); - allBoxed.connectCharValue(TOPIC_BOXED_CHARACTER); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); + + integers.connectIntValue(mqttUri(TOPIC_NATIVE_INT)); + integers.connectShortValue(mqttUri(TOPIC_NATIVE_SHORT)); + integers.connectLongValue(mqttUri(TOPIC_NATIVE_LONG)); + floats.connectFloatValue(mqttUri(TOPIC_NATIVE_FLOAT)); + floats.connectDoubleValue(mqttUri(TOPIC_NATIVE_DOUBLE)); + chars.connectCharValue(mqttUri(TOPIC_NATIVE_CHAR)); + chars.connectStringValue(mqttUri(TOPIC_NATIVE_STRING)); + allBoxed.connectIntValue(mqttUri(TOPIC_BOXED_INTEGER)); + allBoxed.connectShortValue(mqttUri(TOPIC_BOXED_SHORT)); + allBoxed.connectLongValue(mqttUri(TOPIC_BOXED_LONG)); + allBoxed.connectFloatValue(mqttUri(TOPIC_BOXED_FLOAT)); + allBoxed.connectDoubleValue(mqttUri(TOPIC_BOXED_DOUBLE)); + allBoxed.connectCharValue(mqttUri(TOPIC_BOXED_CHARACTER)); sender = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost()); assertTrue(sender.waitUntilReady(2, TimeUnit.SECONDS)); diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java index 11fe3d9f240ea595d2c9c5825148c555272ba8cc..80bd95c603da385184927862b42a6f54b1d4f57e 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; import java.util.concurrent.TimeUnit; +import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; import static org.junit.jupiter.api.Assertions.*; /** @@ -50,7 +51,7 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest { receiver.close(); } if (model != null) { - model.MqttCloseConnections(); + model.ragconnectCloseConnections(); } } @@ -129,8 +130,7 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest { } private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException { - model.MqttSetHost(TestUtils.getMqttHost()); - assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS)); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); receiver = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost()); assertTrue(receiver.waitUntilReady(2, TimeUnit.SECONDS)); @@ -205,19 +205,19 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest { data.lastBoxedCharValue = java.nio.ByteBuffer.wrap(bytes).getChar(); }); - nativeIntegers.connectIntValue(TOPIC_NATIVE_INT, writeCurrentValue); - nativeIntegers.connectShortValue(TOPIC_NATIVE_SHORT, writeCurrentValue); - nativeIntegers.connectLongValue(TOPIC_NATIVE_LONG, writeCurrentValue); - nativeFloats.connectFloatValue(TOPIC_NATIVE_FLOAT, writeCurrentValue); - nativeFloats.connectDoubleValue(TOPIC_NATIVE_DOUBLE, writeCurrentValue); - nativeChars.connectCharValue(TOPIC_NATIVE_CHAR, writeCurrentValue); - nativeChars.connectStringValue(TOPIC_NATIVE_STRING, writeCurrentValue); - boxedIntegers.connectIntValue(TOPIC_BOXED_INTEGER, writeCurrentValue); - boxedIntegers.connectShortValue(TOPIC_BOXED_SHORT, writeCurrentValue); - boxedIntegers.connectLongValue(TOPIC_BOXED_LONG, writeCurrentValue); - boxedFloats.connectFloatValue(TOPIC_BOXED_FLOAT, writeCurrentValue); - boxedFloats.connectDoubleValue(TOPIC_BOXED_DOUBLE, writeCurrentValue); - boxedChars.connectCharValue(TOPIC_BOXED_CHARACTER, writeCurrentValue); + nativeIntegers.connectIntValue(mqttUri(TOPIC_NATIVE_INT), writeCurrentValue); + nativeIntegers.connectShortValue(mqttUri(TOPIC_NATIVE_SHORT), writeCurrentValue); + nativeIntegers.connectLongValue(mqttUri(TOPIC_NATIVE_LONG), writeCurrentValue); + nativeFloats.connectFloatValue(mqttUri(TOPIC_NATIVE_FLOAT), writeCurrentValue); + nativeFloats.connectDoubleValue(mqttUri(TOPIC_NATIVE_DOUBLE), writeCurrentValue); + nativeChars.connectCharValue(mqttUri(TOPIC_NATIVE_CHAR), writeCurrentValue); + nativeChars.connectStringValue(mqttUri(TOPIC_NATIVE_STRING), writeCurrentValue); + boxedIntegers.connectIntValue(mqttUri(TOPIC_BOXED_INTEGER), writeCurrentValue); + boxedIntegers.connectShortValue(mqttUri(TOPIC_BOXED_SHORT), writeCurrentValue); + boxedIntegers.connectLongValue(mqttUri(TOPIC_BOXED_LONG), writeCurrentValue); + boxedFloats.connectFloatValue(mqttUri(TOPIC_BOXED_FLOAT), writeCurrentValue); + boxedFloats.connectDoubleValue(mqttUri(TOPIC_BOXED_DOUBLE), writeCurrentValue); + boxedChars.connectCharValue(mqttUri(TOPIC_BOXED_CHARACTER), writeCurrentValue); } private void setData(String integerDriver, String floatDriver, String stringDriver) { diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java index 1a58b683d55b0401485c85caca8105914e6cf67f..3d0706c075d8e4af3b3c5e5fa703f3885b80ddf3 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java @@ -11,6 +11,7 @@ import robot.RobotStateOuterClass.RobotState; import java.io.IOException; import java.util.concurrent.TimeUnit; +import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; import static org.junit.jupiter.api.Assertions.*; /** @@ -42,7 +43,7 @@ public class ExampleTest extends AbstractMqttTest { handler.close(); } if (model != null) { - model.MqttCloseConnections(); + model.ragconnectCloseConnections(); } } @@ -210,8 +211,7 @@ public class ExampleTest extends AbstractMqttTest { } private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException { - model.MqttSetHost(TestUtils.getMqttHost()); - assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS)); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost()); assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS)); @@ -233,9 +233,9 @@ public class ExampleTest extends AbstractMqttTest { } }); - robotArm.connectAppropriateSpeed(TOPIC_CONFIG, writeCurrentValue); - link1.connectCurrentPosition(TOPIC_JOINT1); - link2.connectCurrentPosition(TOPIC_JOINT2); + robotArm.connectAppropriateSpeed(mqttUri(TOPIC_CONFIG), writeCurrentValue); + link1.connectCurrentPosition(mqttUri(TOPIC_JOINT1)); + link2.connectCurrentPosition(mqttUri(TOPIC_JOINT2)); } private void createModel() { diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java index 595976330654d05ae6e7a37dd8514fe901b9164f..5ede1e1896afadc70da7b868cf4272eafa250514 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java @@ -7,6 +7,7 @@ import read1write2.ast.*; import java.io.IOException; import java.util.concurrent.TimeUnit; +import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -44,7 +45,7 @@ public class Read1Write2Test extends AbstractMqttTest { handler.close(); } if (model != null) { - model.MqttCloseConnections(); + model.ragconnectCloseConnections(); } } @@ -137,8 +138,7 @@ public class Read1Write2Test extends AbstractMqttTest { } private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException { - model.MqttSetHost(TestUtils.getMqttHost()); - assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS)); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost()); assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS)); @@ -181,15 +181,15 @@ public class Read1Write2Test extends AbstractMqttTest { dataOther2.lastStringValue = new String(bytes); }); - onSameNonterminal.connectInput(TOPIC_SAME_READ); - onSameNonterminal.connectOutInteger(TOPIC_SAME_WRITE_INT, writeCurrentValue); - onSameNonterminal.connectOutString(TOPIC_SAME_WRITE_STRING, writeCurrentValue); + onSameNonterminal.connectInput(mqttUri(TOPIC_SAME_READ)); + onSameNonterminal.connectOutInteger(mqttUri(TOPIC_SAME_WRITE_INT), writeCurrentValue); + onSameNonterminal.connectOutString(mqttUri(TOPIC_SAME_WRITE_STRING), writeCurrentValue); - onDifferentNonterminal.connectInput(TOPIC_DIFFERENT_READ); - other1.connectOutInteger(TOPIC_DIFFERENT_WRITE1_INT, writeCurrentValue); - other1.connectOutString(TOPIC_DIFFERENT_WRITE1_STRING, writeCurrentValue); - other2.connectOutInteger(TOPIC_DIFFERENT_WRITE2_INT, writeCurrentValue); - other2.connectOutString(TOPIC_DIFFERENT_WRITE2_STRING, writeCurrentValue); + onDifferentNonterminal.connectInput(mqttUri(TOPIC_DIFFERENT_READ)); + other1.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE1_INT), writeCurrentValue); + other1.connectOutString(mqttUri(TOPIC_DIFFERENT_WRITE1_STRING), writeCurrentValue); + other2.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE2_INT), writeCurrentValue); + other2.connectOutString(mqttUri(TOPIC_DIFFERENT_WRITE2_STRING), writeCurrentValue); } private void sendData(String inputSame, String inputDifferent) { diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java index 5f61867b5a254a92090a4b6d502100a356f12ddd..9881eb7110f98a3bc36301f2f7a163c417e9a54e 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java @@ -7,6 +7,7 @@ import read2write1.ast.*; import java.io.IOException; import java.util.concurrent.TimeUnit; +import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -43,7 +44,7 @@ public class Read2Write1Test extends AbstractMqttTest { handler.close(); } if (model != null) { - model.MqttCloseConnections(); + model.ragconnectCloseConnections(); } } @@ -146,8 +147,7 @@ public class Read2Write1Test extends AbstractMqttTest { } private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException { - model.MqttSetHost(TestUtils.getMqttHost()); - assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS)); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost()); assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS)); @@ -178,14 +178,14 @@ public class Read2Write1Test extends AbstractMqttTest { dataOther2.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt(); }); - onSameNonterminal.connectInput1(TOPIC_SAME_READ1); - onSameNonterminal.connectInput2(TOPIC_SAME_READ2); - onSameNonterminal.connectOutInteger(TOPIC_SAME_WRITE_INT, writeCurrentValue); + onSameNonterminal.connectInput1(mqttUri(TOPIC_SAME_READ1)); + onSameNonterminal.connectInput2(mqttUri(TOPIC_SAME_READ2)); + onSameNonterminal.connectOutInteger(mqttUri(TOPIC_SAME_WRITE_INT), writeCurrentValue); - onDifferentNonterminal.connectInput1(TOPIC_DIFFERENT_READ1); - onDifferentNonterminal.connectInput2(TOPIC_DIFFERENT_READ2); - other1.connectOutInteger(TOPIC_DIFFERENT_WRITE1_INT, writeCurrentValue); - other2.connectOutInteger(TOPIC_DIFFERENT_WRITE2_INT, writeCurrentValue); + onDifferentNonterminal.connectInput1(mqttUri(TOPIC_DIFFERENT_READ1)); + onDifferentNonterminal.connectInput2(mqttUri(TOPIC_DIFFERENT_READ2)); + other1.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE1_INT), writeCurrentValue); + other2.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE2_INT), writeCurrentValue); } private void sendData(boolean useSameInput1, String inputSame, diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java index 38616caf60907ff0b17da55d420180f00f1a225c..26c32c5a438bf133d984efa31bde4b05b3b15af1 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java @@ -1,7 +1,11 @@ package org.jastadd.ragconnect.tests; +import org.junit.jupiter.api.Assertions; + import java.io.File; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; @@ -26,6 +30,14 @@ public class TestUtils { } } + public static String mqttUri(String path) { + return "mqtt://" + getMqttHost() + "/" + path; + } + + public static String restUri(String path, int port) { + return "rest://localhost:" + port + "/" + path; + } + public static int getMqttDefaultPort() { return 1883; } diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java index e42393d48cc37b58ad7897ea65bf796c83110e98..896b8711fee14bce4dcf8a12006ddb9e26a5791c 100644 --- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java @@ -14,6 +14,8 @@ import javax.ws.rs.core.MediaType; import java.io.IOException; import java.util.concurrent.TimeUnit; +import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; +import static org.jastadd.ragconnect.tests.TestUtils.restUri; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -62,8 +64,7 @@ public class ViaTest extends AbstractMqttTest { handler.close(); } if (model != null) { - model.MqttCloseConnections(); - model.RestCloseConnections(); + model.ragconnectCloseConnections(); } } @@ -95,8 +96,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-201-R2R-ToRest", "FromMqtt-301-M2R-ToRest", 2, "FromRest-401-R2M-ToMqtt", - 2, "FromMqtt-501-B2M-ToMqtt", - "FromMqtt-501-B2R-ToRest"); + 2, "501-B2M-ToMqtt", + "501-B2R-ToRest"); // send value only for bothInput via REST sendDataForBoth("502", false); @@ -107,8 +108,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-201-R2R-ToRest", "FromMqtt-301-M2R-ToRest", 2, "FromRest-401-R2M-ToMqtt", - 3, "FromRest-502-B2M-ToMqtt", - "FromRest-502-B2R-ToRest"); + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); // send same value only for bothInput via MQTT sendDataForBoth("502", true); @@ -119,8 +120,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-201-R2R-ToRest", "FromMqtt-301-M2R-ToRest", 2, "FromRest-401-R2M-ToMqtt", - 4, "FromMqtt-502-B2M-ToMqtt", - "FromMqtt-502-B2R-ToRest"); + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); // send values for other things sendData("102", "202", "302", "402"); @@ -131,8 +132,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-202-R2R-ToRest", "FromMqtt-302-M2R-ToRest", 3, "FromRest-402-R2M-ToMqtt", - 4, "FromMqtt-502-B2M-ToMqtt", - "FromMqtt-502-B2R-ToRest"); + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); // send same values again for other things sendData("102", "202", "302", "402"); @@ -143,8 +144,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-202-R2R-ToRest", "FromMqtt-302-M2R-ToRest", 3, "FromRest-402-R2M-ToMqtt", - 4, "FromMqtt-502-B2M-ToMqtt", - "FromMqtt-502-B2R-ToRest"); + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); } @Test @@ -170,8 +171,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-211-R2R-ToRest", "FromMqtt-311-M2R-ToRest", 1, "FromRest-411-R2M-ToMqtt", - 1, "FromMqtt-511-B2M-ToMqtt", - "FromMqtt-511-B2R-ToRest"); + 1, "511-B2M-ToMqtt", + "511-B2R-ToRest"); // send value only for bothInput via REST sendDataForBoth("512", false); @@ -182,8 +183,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-211-R2R-ToRest", "FromMqtt-311-M2R-ToRest", 1, "FromRest-411-R2M-ToMqtt", - 2, "FromRest-512-B2M-ToMqtt", - "FromRest-512-B2R-ToRest"); + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); // send same value only for bothInput via MQTT sendDataForBoth("512", true); @@ -194,8 +195,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-211-R2R-ToRest", "FromMqtt-311-M2R-ToRest", 1, "FromRest-411-R2M-ToMqtt", - 3, "FromMqtt-512-B2M-ToMqtt", - "FromMqtt-512-B2R-ToRest"); + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); // send values for other things sendData("112", "212", "312", "412"); @@ -206,8 +207,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-212-R2R-ToRest", "FromMqtt-312-M2R-ToRest", 2, "FromRest-412-R2M-ToMqtt", - 3, "FromMqtt-512-B2M-ToMqtt", - "FromMqtt-512-B2R-ToRest"); + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); // send same values again for other things sendData("112", "212", "312", "412"); @@ -218,8 +219,8 @@ public class ViaTest extends AbstractMqttTest { "FromRest-212-R2R-ToRest", "FromMqtt-312-M2R-ToRest", 2, "FromRest-412-R2M-ToMqtt", - 3, "FromMqtt-512-B2M-ToMqtt", - "FromMqtt-512-B2R-ToRest"); + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); } private void sendData(String inputMqtt2Mqtt, String inputRest2Rest, String inputMqtt2Rest, String inputRest2Mqtt) { @@ -269,9 +270,7 @@ public class ViaTest extends AbstractMqttTest { } private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException { - model.MqttSetHost(TestUtils.getMqttHost()); - model.RestSetPort(REST_PORT); - assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS)); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost()); assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS)); @@ -308,18 +307,18 @@ public class ViaTest extends AbstractMqttTest { senderRest2Mqtt = client.target(REST_SERVER_BASE_URL + PATH_REST_2_MQTT_RECEIVE); senderBoth2Rest = client.target(REST_SERVER_BASE_URL + PATH_BOTH_REST_RECEIVE); - model.connectMqtt2MqttInput(TOPIC_MQTT_2_MQTT_RECEIVE); - model.connectMqtt2MqttOutput(TOPIC_MQTT_2_MQTT_SEND, writeCurrentValue); - model.connectMqtt2RestInput(TOPIC_MQTT_2_REST_RECEIVE); - model.connectMqtt2RestOutput(PATH_MQTT_2_REST_SEND, writeCurrentValue); - model.connectRest2MqttInput(PATH_REST_2_MQTT_RECEIVE); - model.connectRest2MqttOutput(TOPIC_REST_2_MQTT_SEND, writeCurrentValue); - model.connectRest2RestInput(PATH_REST_2_REST_RECEIVE); - model.connectRest2RestOutput(PATH_REST_2_REST_SEND, writeCurrentValue); - model.connectBoth2BothInputViaMqtt(TOPIC_BOTH_MQTT_RECEIVE); - model.connectBoth2BothInputViaRest(PATH_BOTH_REST_RECEIVE); - model.connectBoth2MqttOutput(TOPIC_BOTH_2_MQTT_SEND, writeCurrentValue); - model.connectBoth2RestOutput(PATH_BOTH_2_REST_SEND, writeCurrentValue); + model.connectMqtt2MqttInput(mqttUri(TOPIC_MQTT_2_MQTT_RECEIVE)); + model.connectMqtt2MqttOutput(mqttUri(TOPIC_MQTT_2_MQTT_SEND), writeCurrentValue); + model.connectMqtt2RestInput(mqttUri(TOPIC_MQTT_2_REST_RECEIVE)); + model.connectMqtt2RestOutput(restUri(PATH_MQTT_2_REST_SEND, REST_PORT), writeCurrentValue); + model.connectRest2MqttInput(restUri(PATH_REST_2_MQTT_RECEIVE, REST_PORT)); + model.connectRest2MqttOutput(mqttUri(TOPIC_REST_2_MQTT_SEND), writeCurrentValue); + model.connectRest2RestInput(restUri(PATH_REST_2_REST_RECEIVE, REST_PORT)); + model.connectRest2RestOutput(restUri(PATH_REST_2_REST_SEND, REST_PORT), writeCurrentValue); + model.connectBoth2BothInput(mqttUri(TOPIC_BOTH_MQTT_RECEIVE)); + model.connectBoth2BothInput(restUri(PATH_BOTH_REST_RECEIVE, REST_PORT)); + model.connectBoth2MqttOutput(mqttUri(TOPIC_BOTH_2_MQTT_SEND), writeCurrentValue); + model.connectBoth2RestOutput(restUri(PATH_BOTH_2_REST_SEND, REST_PORT), writeCurrentValue); } private static class ReceiverData { diff --git a/ragconnect.tests/src/test/resources/log4j2.xml b/ragconnect.tests/src/test/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..4c0d4548c61b23abad6aabc6811e68cd8a928871 --- /dev/null +++ b/ragconnect.tests/src/test/resources/log4j2.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="INFO"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + </Appenders> + <Loggers> + <Root level="debug"> + <AppenderRef ref="Console"/> + </Root> + <Logger name="org.eclipse.jetty" level="info" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + </Loggers> +</Configuration> diff --git a/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java b/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java index 7c6d930aefa358a24b53be7349e1d667fc681380..a7a910395550868efa893efbf8ade2057e7b7b61 100644 --- a/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java +++ b/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java @@ -32,7 +32,11 @@ public class Util { handler.setHost(hostAndPort.host, hostAndPort.port); } - public static void iterateLinks(HandleLink callback, ActualConfiguration config) { + public static String mqttUri(String topic, ActualConfiguration config) { + return "mqtt://" + config.server + "/" + topic; + } + + public static void iterateLinks(HandleLink callback, ActualConfiguration config) throws IOException { for (Map.Entry<String, SortedMap<String, String>> dataRobot : config.parts.entrySet()) { String topicPrefix = dataRobot.getKey() + "/"; for (Map.Entry<String, String> dataLink : dataRobot.getValue().entrySet()) { @@ -69,6 +73,6 @@ public class Util { @FunctionalInterface public interface HandleLink { - void handle(boolean isEndEffector, String topic, String name); + void handle(boolean isEndEffector, String topic, String name) throws IOException; } } diff --git a/ros2rag.goal/build.gradle b/ros2rag.goal/build.gradle index 0c537c2ba4f8d5a5f92fc572249ddcb0afa94896..3bfe45ab6c9aef96b069ff56faf8c47597f11acf 100644 --- a/ros2rag.goal/build.gradle +++ b/ros2rag.goal/build.gradle @@ -18,7 +18,9 @@ configurations { baseRuntimeClasspath } -sourceSets.main.java.srcDir "src/gen/java" +File genSrc = file("src/gen/java"); +sourceSets.main.java.srcDir genSrc +idea.module.generatedSourceDirs += genSrc dependencies { implementation project (':ragconnect.base') diff --git a/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java b/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java index fc04dc9aeda6cc79222f1042a2d583abeeb86c6d..5dad7c9a5ef62f291fd67967cb067b2597d6239a 100644 --- a/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java +++ b/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java @@ -33,7 +33,6 @@ public class GoalMain { ActualConfiguration config = Util.parseConfig(configFile); model = new GoalModel(); - Util.setMqttHost(model::MqttSetHost, config); for (DataWorkPose dataWorkPose : config.goal_poses) { WorkPose workPose = new WorkPose(); @@ -60,7 +59,7 @@ public class GoalMain { robotState.setLastUpdate(0); model.setRobotState(robotState); - model.MqttWaitUntilReady(2, TimeUnit.SECONDS); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); logger.debug("Setting dependencies"); /* @@ -82,15 +81,15 @@ public class GoalMain { */ Util.iterateLinks((isEndEffector, topic, name) -> { if (isEndEffector) { - robotState.connectCurrentPosition(topic); - robotState.connectLastUpdate(topic); + robotState.connectCurrentPosition(Util.mqttUri(topic, config)); + robotState.connectLastUpdate(Util.mqttUri(topic, config)); } }, config); // next position is not initialized, so don't send it - model.getWorkflow().connectNextTrajectory(config.topics.trajectory, false); - model.getWorkflow().connectCurrentStep(config.topics.nextStep); + model.getWorkflow().connectNextTrajectory(Util.mqttUri(config.topics.trajectory, config), false); + model.getWorkflow().connectCurrentStep(Util.mqttUri(config.topics.nextStep, config)); // initial next step is sent, as soon as this is received, the workflow starts - model.getWorkflow().connectReadyForThisStep(config.topics.nextStep, true); + model.getWorkflow().connectReadyForThisStep(Util.mqttUri(config.topics.nextStep, config), true); logStatus("Start"); CountDownLatch exitCondition = new CountDownLatch(1); @@ -140,7 +139,7 @@ public class GoalMain { private void close() { logger.info("Exiting ..."); mainHandler.close(); - model.MqttCloseConnections(); + model.ragconnectCloseConnections(); } public static void main(String[] args) throws IOException, InterruptedException { diff --git a/ros2rag.safety/build.gradle b/ros2rag.safety/build.gradle index 30d6296bdc98ad7a87f3dedbb0739fe6074120d2..4bfec22f282ed5700cd4bf05edfd4791b0f4515a 100644 --- a/ros2rag.safety/build.gradle +++ b/ros2rag.safety/build.gradle @@ -18,7 +18,10 @@ configurations { baseRuntimeClasspath } -sourceSets.main.java.srcDir "src/gen/java" + +File genSrc = file("src/gen/java"); +sourceSets.main.java.srcDir genSrc +idea.module.generatedSourceDirs += genSrc dependencies { implementation project (':ragconnect.base') diff --git a/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java b/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java index 7627ac005d67c1332323f95866b5f55703cfb532..bf34044f5f194c7a20e600ecd33b02da5116449c 100644 --- a/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java +++ b/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java @@ -29,7 +29,6 @@ public class StarterMain { ActualConfiguration config = Util.parseConfig(configFile); model = new Model(); - Util.setMqttHost(model::MqttSetHost, config); ZoneModel zoneModel = new ZoneModel(); @@ -45,7 +44,7 @@ public class StarterMain { } zoneModel.addSafetyZone(safetyZone); model.setZoneModel(zoneModel); - model.MqttWaitUntilReady(2, TimeUnit.SECONDS); + model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS); RobotArm robotArm = new RobotArm(); model.setRobotArm(robotArm); @@ -63,10 +62,10 @@ public class StarterMain { link.setName(name); link.setCurrentPosition(IntPosition.of(0, 0, 0)); link.containingRobotArm().addDependency1(link); - link.connectCurrentPosition(topic); + link.connectCurrentPosition(Util.mqttUri(topic, config)); }, config); - robotArm.connectAppropriateSpeed(config.topics.robotConfig, true); + robotArm.connectAppropriateSpeed(Util.mqttUri(config.topics.robotConfig, config), true); logStatus("Start", robotArm); CountDownLatch exitCondition = new CountDownLatch(1); @@ -102,7 +101,7 @@ public class StarterMain { private void close() { logger.info("Exiting ..."); mainHandler.close(); - model.MqttCloseConnections(); + model.ragconnectCloseConnections(); } public static void main(String[] args) throws IOException, InterruptedException {