Skip to content

Authoring Transport Configuration

Pascal Honegger edited this page Jun 15, 2023 · 2 revisions

Overview

This page describes the process required to create a custom transport configuration. The required steps can be summarized to:

  1. Decide on plugin programming language (e.g. Kotlin or Java)
  2. Create SAMT plugin with a new transport configuration
  3. Release SAMT plugin

Prerequisites

All you need to get started with writing your own SAMT transport configuration is a working Java or Kotlin development environment. SAMT is built and tested against Java 17, we recommend targeting a modern JVM version. This guide will use Kotlin for the example code, but the same principles apply to Java or any other JVM language as well. An example of a custom transport configuration written in Java can be found at samtkit/example-java-plugin.

You will need to add the following dependencies to your project:

Maven
<dependencies>
  <dependency>
      <groupId>tools.samt</groupId>
      <artifactId>public-api</artifactId>
      <version>${samt.version}</version>
  </dependency>
  <dependency>
      <groupId>tools.samt</groupId>
      <artifactId>common</artifactId>
      <version>${samt.version}</version>
      <scope>test</scope>
  </dependency>
  <dependency>
      <groupId>tools.samt</groupId>
      <artifactId>compiler</artifactId>
      <version>${samt.version}</version>
      <scope>test</scope>
  </dependency>
  <dependency>
      <groupId>tools.samt</groupId>
      <artifactId>codegen</artifactId>
      <version>${samt.version}</version>
      <scope>test</scope>
  </dependency>
  <dependency>
      <groupId>tools.samt</groupId>
      <artifactId>samt-config</artifactId>
      <version>${samt.version}</version>
      <scope>test</scope>
  </dependency>
</dependencies>
Gradle (Kotlin)
dependencies {
  implementation("tools.samt:public-api:$samtVersion")
  testImplementation("tools.samt:common:$samtVersion")
  testImplementation("tools.samt:compiler:$samtVersion")
  testImplementation("tools.samt:codegen:$samtVersion")
  testImplementation("tools.samt:samt-config:$samtVersion")
}
Gradle (Groovy)
dependencies {
  implementation 'tools.samt:public-api:$samtVersion'
  testImplementation 'tools.samt:common:$samtVersion'
  testImplementation 'tools.samt:compiler:$samtVersion'
  testImplementation 'tools.samt:codegen:$samtVersion'
  testImplementation 'tools.samt:samt-config:$samtVersion'
}

Writing the Transport Configuration & Parser

New transport configurations can be created by implementing the TransportConfiguration interface. However, this configuration is only a data store which is then queried by the generators. In order to create this configuration, a matching TransportConfigurationParser needs to be implemented. This parser is responsible for transforming the SAMT configuration block into a strictly typed configuration object.

In order to make a custom transport configuration useful, you will likely also need to create a custom generator, see Authoring Generators for details.

For the purposes of this example, we will create a generator that creates a markdown file containing a list of all the declared enums in the SAMT project. This can be achieved by iterating over all the provided SAMT packages and accessing the list of declared enums. Once the output has been generated, it must be returned as a list of CodegenFile objects.

class MyTransportConfiguration(/* Add your configuration here */) : TransportConfiguration {
    override val name: String get() = MyTransportConfiguration.name

    companion object {
        const val name = "MyTransport" // <-- Must be unique and not contain any dashes or whitespaces!
    }
}

class MyTransportConfigurationParser : TransportConfigurationParser {
    override val transportName: String get() = MyTransportConfiguration.name

    override fun parse(params: TransportConfigurationParserParams): TransportConfiguration {
        // params.config is null if the user did not provide a configuration block
        // you can return a reasonable default value, or report an error
        val config = params.config ?: return MyTransportConfiguration()

        // Read field "foo" as a number
        val fooValue = config.getField("foo").asValue.asLong

        // Validate the configuration
        if (fooValue < 0) {
            params.reportError("foo must be a positive number", config.getField("foo"))
        }

        // Read advanced configurations
        val serviceNames: Map<ServiceType, String> = config.getField("customServiceNames").asObject.fields.entries.associate { (key, value) ->
            // Will throw if the key is not a service name
            key.asServiceName to value.asValue.asString
        }
        return MyTransportConfiguration()
    }
}

Publishing Your Plugin

DISCLAIMER: As currently implemented, there is no way to load your own transport configuration into the SAMT CLI. This feature hasn't been implemented yet, but will possible in the future.