Extending RagConnect

To add a new communication protocol, the following locations have to be changed (replace ABC and abc with the name of the protocol):

Within ragconnect.base/src/main/resources:

  • Add a new handler ABCHandler, if appropriate, similar to the existing handlers
    • If further methods are needed for handler initialization, add a new template abc.mustache containing those procedures. Add {{#usesABC}}{{> abc}}{{/usesABC}} at the top of ragconnect.mustache to use this template
  • In receiveDefinition.mustache and sendDefinition.mustache: add a new case in the switch statement defining the logic to happen for both definitions. If the new protocol is close to a PUSH semantic, follow mqtt. If it is closer to PULL semantic, follow rest.

Within ragconnect.base/src/main/jastadd:

  • In backend/Configuration:
    • Add a new static boolean flag usesABC to indicate whether the protocol is used
  • In backend/Generation:
    • Add new attributes for type MRagConnect for handler attribute and handler field, if needed
    • Add attributes for newly introduced references in changed mustache templates, if any
    • Add a newly constructed handler within the definition of RagConnect.toMustache with the needed fields (class name, construction snippet, handler attribute, handler field, the boolean flag you just added to Configuration)
  • In backend/MustacheNodesToYAML:
    • Add key-value-pair for usesABC (and handler, if any)
    • Add key-value-pairs for newly introduced referemces in changed mustache templates, if any

In ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java:

  • Add a new choice for --protocols similar to the existing ones
  • Set the flag usesABC if the choice is given.
  • Add code to add the handler to the list handlers if the choice is given, i.e., if ASTNode.usesABC

Furthermore, new test cases are appreciated, see below.

Writing Tests

To add new tests, have a look at the module ragconnect.tests. It has three parts: 1) In src/test/01-input/* are the specifications that are going to be compiled (in principle using the steps described in the guide to add RagConnect). 2) In src/test/java, the jUnit 5 test classes are implemented. They mostly correspond 1-to-1 to a directory of the first part. 3) In build.gradle the instructions how to compile the specifications using the gradle plugin PreprocessorPlugin (org.jastadd.preprocessor:testing).

Specifications

Every specification must have at least a README.md to describe the purpose of the test, a grammar Test.relast, and a RagConnect specification Test.connect. Usually an aspect file Test.jadd is included.

Test Classes

Based on jUnit 5, the test classes testing some behaviour. If sending and/or receiving functionality is used, consider extending AbstractMqttTest in order to avoid duplicate code. In case of extending this class, please order the methods according to their lifecycle, i.e.: - createModel - setupReceiverAndConnect - communicateSendInitialValue - communicateOnlyUpdatedValue - closeConnections

Within AbstractMqttTest, an MqttHandler named publisher is available to publish content. Some convenience methods are provided in TestUtils, e.g., the DefaultMappings, and mqttUri to prepend "mqtt://" and the correct host for the mqtt broker (localhost or a CI-specific host). All tests are required to run both locally, and within the CI.

build.gradle

Use the PreprocessorPlugin, the build process can be written concisely in three parts per task:

task compileTreeAllowedTokens(type: RagConnectTest) {
    ragconnect {
        outputDir = file('src/test/02-after-ragconnect/treeAllowedTokens')
        inputFiles = [file('src/test/01-input/treeAllowedTokens/Test.relast'),
                      file('src/test/01-input/treeAllowedTokens/Test.connect'),
                      file('src/test/01-input/treeAllowedTokens/TestDependencies.connect')]
        rootNode = 'Root'
    }
    relast {
        useJastAddNames = true
        grammarName = 'src/test/03-after-relast/treeAllowedTokens/treeAllowedTokens'
        serializer = 'jackson'
    }
    jastadd {
        jastAddList = 'JastAddList'
        packageName = 'treeAllowedTokens.ast'
        inputFiles = [file('src/test/01-input/treeAllowedTokens/Test.jadd')]
    }
}