Skip to main content

Getting Started

To simplify the creation of a micro-executor based on Java, an SDK is available that contains everything necessary.

It encapsulates all standard features such as:

  • Types
  • Interfaces
  • HTTP Server

Prerequisites

Getting started

Kokos SDK Java is provided via a Maven dependency.

Create a new Java 11 (UTF-8) maven project with your favorite IDE (Eclipse, NetBeans, IntelliJ) and add the following dependency:

<dependency>
<groupId>com.smeup.kokos</groupId>
<artifactId>kokos-sdk-java</artifactId>
<version>[VERSION]</version>
</dependency>

To be able to download the SDK you need to add this to the maven_settings.xml file (~/.m2/settings.xml):

<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>https://repo.smeup.cloud/nexus/content/groups/public</url>
</mirror>
</mirrors>

Create a Main class as follow and execute it.

Micro executor API docs and tester is available at: http://localhost:8001/swagger/index.html.

public class Main {

private static final String ME_ID = "[ME_ID]";

public static void main(String[] args) throws Exception {
// start server
RestApi.startServer(ME_ID, MicroExecutorConfiguration.class);
}
}

Configuration

The SDK automatically creates a [USER_HOME]/etc/kokos/[ME_ID]/[ME_ID].yaml file based on MicroExecutorConfiguration.

You can extend it and execute a callback function before the server starts.

RestApi.startServer([MICRO EXECUTOR ID], [CLASS extends MicroExecutorConfiguration], [CALLBACK]);

Develop a Service

A Service in Kokos is a specified java class that extends com.smeup.kokos.sdk.caller.KokosService abstract class. Each service must be placed in com.smeup.kokos.service package.

@DocsService(name = "[SERVICE_NAME]", description = "Service description")
public class [SERVICE_NAME] extends KokosService {
}

es.
@DocsService(name = "JA_TST_00", description = "Test Service description")
public class JA_TST_00 extends KokosService {
}

A Service can contain n methods whose name corresponds to the method function of the Fun. To define a Service Method you can use @ServiceMethod annotation.

@DocsService(name = "[SERVICE_NAME]", description = "Service description")
public class [SERVICE_NAME] extends KokosService {

@DocsServiceMethod(component = "TRE", function = "[METHOD_NAME]", obj1 = @DocsServiceParam(param = "[T1];[P1];[K1]", optional = false), p = {}, input = {}, description = "Service method description")
@ServiceMethod([METHOD_NAME])
public void methodName(Fun fun, ExecutionContext context) throws Exception {
}
}

es.
@DocsService(name = "[SERVICE_NAME]", description = "Test Service description")
public class JA_TST_00 extends KokosService {

@DocsServiceMethod(component = "TRE", function = "GET.TRE", obj1 = @DocsServiceParam(param = "[T1];[P1];[K1]", optional = false), p = {}, input = {}, description = "Service method description")
@ServiceMethod("GET.TRE")
public void getTRE(Fun fun, ExecutionContext context) throws Exception {
}

}

Each method must stream an instance of SmeupDataStructure (com.smeup.kokos.sdk.model.data) to outputstream.

As follow and example of SmeupTree.

  @DocsServiceMethod(component = "TRE", function = "GET.TRE", obj1 = @DocsServiceParam(param = "[T1];[P1];[K1]", optional = false), p = {}, input = {}, description = "Service method description")
@ServiceMethod("GET.TRE")
public void getTRE(Fun fun, ExecutionContext context) throws Exception {
this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "COL", "BONMAI"))
.value("Bonardi Mattia")
.build(), false);
}

KokosService inherits a set of methods for returning a chunked SmeupDataStructure.

Write a SmeupDataTree

this.writeDataNode(SmeupDataNode node, boolean hasChildren);

writeDataNode method accepts two parameter:

  • SmeupDataNode node: the instance of com.smeup.kokos.model.SmeupDataNode (use com.smeup.kokos.sdk.util.SmeupDataNodeBuilder to create it)
  • boolean hasChildren: false to write only node. true to write node and prepare writer to write subsequent nodes as children.

Use this.writeDataNodeClosure() to stop the writer from writing child nodes.

Es: write 1 level SmeupTree

this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "SED", "ERB"))
.value("Erbusco")
.build(), false);
this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "SED", "BRE"))
.value("Brescia")
.build(), false);
this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "SED", "NOV"))
.value("Nova Milanese")
.build(), false);

Result:

  • CN;SED;ERB - Erbusco
  • CN;SED;BRE - Brescia
  • CN;SED;NOV - Nova Milanese

Es: write annidated SmeupTree

this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "SED", "ERB"))
.value("Erbusco")
.build(), true);
this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "SED", "BRE"))
.value("Brescia")
.build(), false);
this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "SED", "NOV"))
.value("Nova Milanese")
.build(), false);
this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "SED", "PAD"))
.value("Padova")
.build(), false);

Result:

  • CN;SED;ERB - Erbusco
    • CN;SED;BRE - Brescia
    • CN;SED;NOV - Nova Milanese
    • CN;SED;PAD - Padova

Write a SmeupDataTable

SmeupDataTable is composed by columns (SmeupDataColumn) and rows (SmeupDataRow).

// write column/columns
this.writeDataColumn(SmeupDataColumn column)
this.writeDataColumns(List<SmeupDataColumn> columns)

// write row
public void writeDataRow(final SmeupDataRow row)

To properly create SmeupDataColumn and SmeupDataRow you can use the relative builders: SmeupDataColumnBuilder and SmeupDataRowBuilder.

Es. Write 2x2 table

this.writeDataColumn(SmeupDataColumnBuilder.builder().name("COL1").title("Column 1").build());
this.writeDataColumn(SmeupDataColumnBuilder.builder().name("COL2").title("Column 2").build());
this.writeDataRow(SmeupDataRowBuilder.builder()
.cell("COL1", SmeupDataCellBuilder.builder()
.value("Row 1 column 1")
.build())
.cell("COL2", SmeupDataCellBuilder.builder()
.value("Row 1 column 2")
.build())
.build());
this.writeDataRow(SmeupDataRowBuilder.builder()
.cell("COL1", SmeupDataCellBuilder.builder()
.value("Row 2 column 1")
.build())
.cell("COL2", SmeupDataCellBuilder.builder()
.value("Row 2 column 2")
.build())
.build());

Result:

Column 1Column 2
Row 1 column 1Row 1 column 2
Row 2 column 1Row 2 column 2

Write a SmeupFeedback or SmeupMessage

SmeupFeedback is composed only by a list SmeupMessage. Also SmeupTable and SmeupTree can contains message. So we can see the SmeupTable and the SmeupTree as extensions of the SmeupFeedback. To properly return a message you can call the following method:

this.writeMessage(SmeupMessageBuilder.builder().message(me.toString())
.gravity([GRAVITY]).mode([MODE])
.build());

Gravity list:

  • SmeupMessage.SmeupMessageGravity.INFO: informational message
  • SmeupMessage.SmeupMessageGravity.ERROR: error message
  • SmeupMessage.SmeupMessageGravity.WARN: warning message

Mode list:

  • SmeupMessage.SmeupMessageMode.TN: temporary notification
  • SmeupMessage.SmeupMessageMode.PN: permanent notification
  • SmeupMessage.SmeupMessageMode.PM: permament modal notification
  • SmeupMessage.SmeupMessageMode.HH: hide notification

Service documentation

In order to better document services, we are using annotations, which are:

  • @DocsService -> used to document the entire service
  • @DocsServiceMethod -> used to document a method inside a service
  • @DocsServiceParam -> used to document a parameter that can be passed to a method in a service.

A detailed description on how to document a service is available here