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
- Apache Maven
- JDK 21
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 ofcom.smeup.kokos.model.SmeupDataNode
(usecom.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 1 | Column 2 |
---|---|
Row 1 column 1 | Row 1 column 2 |
Row 2 column 1 | Row 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 messageSmeupMessage.SmeupMessageGravity.ERROR
: error messageSmeupMessage.SmeupMessageGravity.WARN
: warning message
Mode list:
SmeupMessage.SmeupMessageMode.TN
: temporary notificationSmeupMessage.SmeupMessageMode.PN
: permanent notificationSmeupMessage.SmeupMessageMode.PM
: permament modal notificationSmeupMessage.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