The Message

Last updated 6 months ago

Let's define our schema (message) for sending our Hello World from one stage to another.

What should our message look like?

Remember our diagram from before. We'd like to go from one stage, that's producing a name, to another stage, which would display your name. Our message should look pretty simple, containing one field for the name.

Under src/test/resources, create a new file named HelloWorldSchema.xml with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<templates xmlns="http://www.fixprotocol.org/ns/fast/td/1.1">
<template name="HelloWorldMessage" id="1">
<string name="GreetingName" id="100" charset="unicode"/>
</template>
</templates>

This is based on the FAST protocol, and defines exactly what our messages on pipes should look like.

  • First, we define a new template that will contain the name called HelloWorldName with a unique ID.

  • Inside it, we define a UTF-8 string named GreetingName, which will store the name of the person we want to say hello to.

However, the XML file alone does not do much good. We need to actually write code that can read and write using this schema.

...or do we?

Pronghorn has a very unique approach to generating Java files. First, we create a test to verify that our schema matches our implementation. If it doesn't, the console will tell us what code we need to insert to make sure it runs correctly. Sounds simply enough, right?

Create a new file under src/main/java/com.ociweb and name it HelloWorldSchema.java with the following placeholder code:

package com.ociweb;
import com.ociweb.pronghorn.pipe.*;
public class HelloWorldSchema extends MessageSchema<HelloWorldSchema> {
public HelloWorldSchema() {
super(null);
}
}

Next, create a new test under src/test/java/com.ociweb and name it HelloWorldSchemaTest.java. Insert the following code:

package com.ociweb;
import com.ociweb.pronghorn.pipe.util.build.FROMValidation;
import org.junit.jupiter.api.Test;
public class HelloWorldSchemaTest {
@Test
public void messageClientNetResponseSchemaFROMTest() {
assertTrue(FROMValidation.checkSchema("/HelloWorldSchema.xml", HelloWorldSchema.class));
}
}

Run the test. It will fail - but that's not necessarily a bad thing. Take a look at the console and you will notice that it suggests corrected code.

Copy paste this generated code into the previously created HelloWorldSchema.java , replacing the placeholder code:

package com.ociweb;
import com.ociweb.pronghorn.pipe.*;
public class HelloWorldSchema extends MessageSchema<HelloWorldSchema> {
public final static FieldReferenceOffsetManager FROM = new FieldReferenceOffsetManager(
new int[]{0xc0400002,0xa8000000,0xc0200002},
(short)0,
new String[]{"HelloWorldMessage","GreetingName",null},
new long[]{1, 100, 0},
new String[]{"global",null,null},
"HelloWorldSchema.xml",
new long[]{2, 2, 0},
new int[]{2, 2, 0});
public HelloWorldSchema() {
super(FROM);
}
protected HelloWorldSchema(FieldReferenceOffsetManager from) {
super(from);
}
public static final HelloWorldSchema instance = new HelloWorldSchema();
public static final int MSG_HELLOWORLDMESSAGE_1 = 0x00000000; //Group/OpenTempl/2
public static final int MSG_HELLOWORLDMESSAGE_1_FIELD_GREETINGNAME_100 = 0x01400001; //UTF8/None/0
public static void consume(Pipe<HelloWorldSchema> input) {
while (PipeReader.tryReadFragment(input)) {
int msgIdx = PipeReader.getMsgIdx(input);
switch(msgIdx) {
case MSG_HELLOWORLDMESSAGE_1:
consumeHelloWorldMessage(input);
break;
case -1:
//requestShutdown();
break;
}
PipeReader.releaseReadLock(input);
}
}
public static void consumeHelloWorldMessage(Pipe<HelloWorldSchema> input) {
StringBuilder fieldGreetingName = PipeReader.readUTF8(input,MSG_HELLOWORLDMESSAGE_1_FIELD_GREETINGNAME_100,new StringBuilder(PipeReader.readBytesLength(input,MSG_HELLOWORLDMESSAGE_1_FIELD_GREETINGNAME_100)));
}
public static void publishHelloWorldMessage(Pipe<HelloWorldSchema> output, CharSequence fieldGreetingName) {
PipeWriter.presumeWriteFragment(output, MSG_HELLOWORLDMESSAGE_1);
PipeWriter.writeUTF8(output,MSG_HELLOWORLDMESSAGE_1_FIELD_GREETINGNAME_100, fieldGreetingName);
PipeWriter.publishWrites(output);
}
}

Congratulations, you first message protocol has been created! On the next page, we will create a simple producing stage that creates a simple message and passes it on.