Available Services
Service as Smeup Entity DAO
Smeup Entity engine allows to define a custom DAO located into micro executor java-rpgle. The custom DAO corresponds a particular Service with pre-set methods. To create a custom DAO you can extends com.smeup.kokos.sdk.caller.KokosEntityDAOService
class and implements the relative methods.
Below is an example of a custom DAO:
package com.smeup.kokos.service;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import com.smeup.kokos.caller.KokosEntityDAOService;
import com.smeup.kokos.entity.SmeupEntityOavSlice;
import com.smeup.kokos.entity.SmeupEntitySlice;
import com.smeup.kokos.model.ExecutionContext;
/**
* Dummy DAO for test
*/
public class JA_TST_01 extends KokosEntityDAOService {
private static final SmeupEntitySlice entity1;
private static final SmeupEntitySlice entity2;
static {
SmeupEntityOavSlice entity1oavI01 = new SmeupEntityOavSlice();
entity1oavI01.setId("I/01");
entity1oavI01.setValue("BONMAI");
SmeupEntityOavSlice entity1oavI02 = new SmeupEntityOavSlice();
entity1oavI02.setId("I/02");
entity1oavI02.setValue("BG");
SmeupEntityOavSlice entity2oavI01 = new SmeupEntityOavSlice();
entity2oavI01.setId("I/01");
entity2oavI01.setValue("LANMAM");
SmeupEntityOavSlice entity2oavI02 = new SmeupEntityOavSlice();
entity2oavI02.setId("I/02");
entity2oavI02.setValue("PR");
entity1 = new SmeupEntitySlice();
entity1.setCode("BONMAI");
entity1.getOavs().put("I/01", entity1oavI01);
entity1.getOavs().put("I/02", entity1oavI02);
entity2 = new SmeupEntitySlice();
entity2.setCode("LANMAM");
entity2.getOavs().put("I/01", entity2oavI01);
entity2.getOavs().put("I/02", entity2oavI02);
}
@Override
public SmeupEntitySlice findById(ExecutionContext context, String id) throws Exception {
return entity1;
}
@Override
public Iterator<SmeupEntitySlice> findAll(ExecutionContext context) throws Exception {
final List<SmeupEntitySlice> sliceList = Arrays.asList(entity1, entity2);
return sliceList.iterator();
}
@Override
public Iterator<SmeupEntitySlice> findMany(ExecutionContext context, List<String> codes) throws Exception {
final List<SmeupEntitySlice> sliceList = Arrays.asList(entity1);
return sliceList.iterator();
}
@Override
public void deleteById(ExecutionContext context, String id) throws Exception {
}
@Override
public void updateById(ExecutionContext context, SmeupEntitySlice entity) throws Exception {
}
@Override
public SmeupEntitySlice insertNew(ExecutionContext context, SmeupEntitySlice entity) throws Exception {
return entity;
}
}
Fallback Service
In your MicroExecutor you can create a FallbackService which is called when the service specified in the Fun is not implemented. In this way you can manage a sort of default service, or use it to "forward" the Fun to a different backend (e.g. IBMi).
To create a fallback service you need to create a class called KokosFallbackServiceImpl
, extend com.smeup.kokos.sdk.caller.KokosFallbackService
and implements the relative methods.
Here's an example of Fallback Service:
public class KokosFallbackServiceImpl extends KokosFallbackService {
@Override
public void execute(Fun fun, ExecutionContext context) throws Exception {
this.writeDataNode(SmeupDataNodeBuilder.builder()
.obj(new SmeupDataObj("CN", "COL", "MOSPAO")
.value("Mossini Paolo")
.build(), false);
}
}
Callable Program
In your Microexecutor you can develop a Program that can be called by RPGLE code. To do this you need to create a class that extends com.smeup.kokos.sdk.caller.KokosCallableProgram
and implements the execute
method.
Here's an example of Callable Program:
public class MU_250_10D extends KokosCallableProgram {
@Override
public Map<String, String> execute(Map<String, String> entry, ExecutionContext context) throws Exception {
entry.put("MEID", Main.ME_ID);
entry.put("PGM", this.getClass().getName());
entry.put("USER", context.getUser().getUsername());
LocalDate today = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
String formattedDate = today.format(formatter);
entry.put("DATE", formattedDate);
LocalTime currentTime = LocalTime.now();
entry.put("TIME", currentTime.toString());
return entry;
}
}
The working example can be found in Kokos Showcase at this link
Update Service (Input Panel)
Overview
Kokos SDK provide a straightforward API in order to implement all the logics of a Input Panel. All the implementations are wrapped into KokosInputPanelService. Read more here
This abstract class implements every methods defined by specifications:
- init
- update
These methods are given by the SDK. You don't have to implement them. They have the responsability to handle respectively initialization logic and update logic.
Here an example of Input Panel:
public class MyInputPanelService extends KokosInputPanelService {
public MyInputPanelService() {
super(new MyInputPanelServiceStrategy());
}
}
As you can see, this class extends KokosInputPanelService and it inherits all its methods.
You could customize the behaviour of an Input Panel through the implementation of a custom class (MyInputPanelServiceStrategy in the given example). This class have to contain:
- a configuration of an Input Panel
- how to save data
Business Logic Implementation
Every Input Panel need to extends a KokosInputPanelService. As a result, you have to call its contructor and you must pass a parameter. It's a KokosInputPanelStrategy and it's an abstract class which impose you to implements two methods:
- load
- save
load method
This method aims to implement all the initialization logic. It has no input parameter and its response contains a configuration for an Input Panel and, eventually, its data.
save method
This method aims to implement all the update logic and how an Input Panel must render after this action.
It has an input parameter, which contain all the INPUT data taken from the fun.
Its response must contains:
- a configuration for the an Input Panel
- data
- messages (converted in SmeupMessages)
- rerendering flag (default: true)
Developers Helpers
Inorder to achive ad ease and intuitive developer experience, Kokos SDK provides some builders. This helpers could be used either in save method and load method and builders are designed for an easy response generation of both this methods.
Configuration builder
Configuration builder aims to ease the constrution of a Input Panel. The class InputPanelConfigurationBuilder has everything in order to create an Input Panel programmatically. You can create fields of any kind of shapes, with a custom title. As for the InputPanelConfiguration, its fields are built with a builder (InputPanelFieldBuilder). Even the layout is built with InputPanelLayoutBuilder.
Here's an example
InputPanelConfigurationBuilder.builder()
.withField("City", InputPanelFieldBuilder.builder(cellName1)
.withTitle("City")
.withShape(SmeupCellShapes.TEXT_FIELD)
.build())
.withField("Postcode", InputPanelFieldBuilder.builder(cellName2)
.withTitle("Postcode")
.withObj(cell2_obj)
.withShape(SmeupCellShapes.TEXT_FIELD)
.build())
.withField("Region", InputPanelFieldBuilder.builder(cellName3)
.withTitle("Region")
.withShape(SmeupCellShapes.TEXT_FIELD)
.build())
.withLayout(
InputPanelLayoutBuilder.builder()
.withSection(
InputPanelLayoutSectionBuilder.builder()
.withId("Section1")
.withDim("5")
.withGridCols(1)
.withGridRows(3)
.withGap(1)
.withContent(
InputPanelLayoutFieldBuilder.builder("LayoutField1")
.withRowSpan(1)
.withRowStart(1)
.withRowEnd(2)
.build())
.withContent(
InputPanelLayoutFieldBuilder.builder("LayoutField2")
.withRowSpan(2)
.withRowStart(1)
.withRowEnd(3)
.build())
.build())
.build())
.build();
Data builder
Data builder aims to ease the constrution of an Input Panel's data. The class InputPanelDataBuilder has everything in order to create programmtically a dataset for an Input Panel. Every field of an Input Panel is built with an InputPanelFieldDataBuilder. Here's a basic example
InputPanelDataBuilder.builder()
.withField("City", InputPanelFieldDataBuilder.builder()
.withValue("Bari")
.build())
.withField("Postcode", InputPanelFieldDataBuilder.builder()
.withValue("70123")
.build())
.withField("Region", InputPanelFieldDataBuilder.builder()
.withValue("Puglia")
.build())
.build();