Skip to main content

Simple Binary Encoding and Data Transfer Objects

How to use SBEs and DTOs within your projects

Add and adapt the following into your project. This will:

  • Generate the SBE encoders/decoders and the DTOs
  • Move the generated schema to an expected location for the KeySquare API to detect and publish on application launch

You can follow the Eclipse and IntelliJ tutorials for steps on enabling automatic code generation upon saving your SBE schemas.

info

Note that in the example below, the SBE schema file used is "sbe-model-client.xml". This schema file can be named more appropriately for your model, in which case you should search-and-replace "sbe-model-client" with your choice of naming. Note that other text within the block below should remain unchanged.

  <build>
<plugins>

<!-- step 1: unpack the key square core definitions for usage in a custom model -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.8.1</version>
<executions>
<?m2e execute onConfiguration,onIncremental?>
<execution>
<id>unpack-file</id>
<phase>generate-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>trading.keysquare</groupId>
<artifactId>keysquare-api-all-jdk17</artifactId>
<type>jar</type>
<outputDirectory>${project.build.directory}/keysquare</outputDirectory>
<includes>sbe-model-core-definintions.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

<!-- step 2: generate SBE encoders, decoders and DTOs for the file "sbe-model-client.xml" -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>generate-sbes-and-pojos</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED</argument>
<argument>-Dsbe.output.dir=${project.build.directory}/generated/src/main/java</argument>
<argument>-Dsbeir.output.dir=${project.build.directory}/generated/src/main/resources</argument>
<argument>-cp</argument>
<classpath/>
<argument>trading.keysquare.codegen.Main</argument>
<argument>${project.build.resources[0].directory}/sbe-model-client.xml</argument>
</arguments>
</configuration>
</execution>
</executions>
<configuration>
<includeProjectDependencies>true</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<workingDirectory>${project.build.directory}/generated/src/main/java</workingDirectory>
</configuration>
</plugin>

<!-- step 3: add the generated sources to the claspath -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<?m2e execute onConfiguration,onIncremental?>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>
${project.build.directory}/generated/src/main/java/</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-resource</id>
<phase>generate-sources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.build.directory}/generated/src/main/resources/</directory>
</resource>
<resource>
<directory>${project.build.directory}/keysquare/</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>

Example SBE schema

The XML schema needs to be placed in the appropriate directory. As per Maven plugin configuration above, this would be

${project.build.resources[0].directory}/sbe-model-client.xml

The SBE schema example here is pretty standard. Notable items:

  • The semanticVersion is used in our Data Viewer to name the schema
  • You should include the sbe-model-core-definitions.xml as described which includes some base things such as our KeyHeader
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe" xmlns:xi="http://www.w3.org/2001/XInclude"
package="trading.keysquare.model.sbe"
id="1"
version="1"
semanticVersion="Client Model"
description="Client SBE Models"
byteOrder="littleEndian">

<!-- this file is extracted from keysquare-api jar and as part of the build process -->
<xi:include href="../../../target/keysquare/sbe-model-core-definitions.xml" />

<types>

<type name="char6" primitiveType="char" length="6" />
<type name="char8" primitiveType="char" length="8" />
<type name="char10" primitiveType="char" length="10" />
<type name="char12" primitiveType="char" length="12" />
<type name="char16" primitiveType="char" length="16" />
<type name="char20" primitiveType="char" length="20" />
<type name="char30" primitiveType="char" length="30" />
<type name="char40" primitiveType="char" length="40" />
<type name="char50" primitiveType="char" length="50" />
<type name="char100" primitiveType="char" length="100" />
<type name="char200" primitiveType="char" length="200" />

<type name="InstrumentId" primitiveType="char" length="20" />

<enum name="ReferenceDataSource" encodingType="int8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="INTERNAL">1</validValue>
<validValue name="ION">2</validValue>
<validValue name="BLOOMBERG">3</validValue>
<validValue name="ANVIL">4</validValue>
<validValue name="BROADWAY">5</validValue>
</enum>

<enum name="PriceSource" encodingType="int8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="HOUSE">1</validValue>
<validValue name="PXE">2</validValue>
<validValue name="PRICING_SERVER">3</validValue>
<validValue name="TOMS">4</validValue>
</enum>

<enum name="PriceClassification" encodingType="int8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="LIVE">1</validValue>
<validValue name="SOD">2</validValue>
<validValue name="EOD">3</validValue>
</enum>

<enum name="PriceStatus" encodingType="int8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="OK">1</validValue>
<validValue name="WARN">2</validValue>
<validValue name="ERROR">3</validValue>
</enum>

</types>

<sbe:message name="SampleMessage" id="5000" description="Test">
<field name="keyHeader" id="1" type="keyHeader" />
<field name="id" id="2" type="char10" semanticType="id" />
<field name="message" id="3" type="char100" />
<field name="price" id="4" type="double" />
<field name="qty" id="5" type="int64" />
<field name="time" id="6" type="nanoTime" />
<field name="date" id="7" type="date" />
<field name="booleanField" id="8" type="BooleanType" />
</sbe:message>

</xml>