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>