Connecting an existing microservices
In this example, we're considering the scenario where we need to integrate with an existing microservice responsible for data operations.
Architecture existing microservice
Let's outline the inputs our microservice accepts:
Parameters get /myentity3900
:
The interface that will emerge will resemble the following:
Steps for developing on cxbox
Developing a straightforward interaction with the existing microservice architecture.
Step1 Create DTO for integrating with microservice
Create DTO for integrating with microservices through which data will be sent to the microservice
Example
Step 2 Create DAO
Create DAO extends AbstractAnySourceBaseDAO implements AnySourceBaseDAO
Override methods:
- Create : method create
Example
public MyEntityOutServiceDTO create(BusinessComponent bc, MyEntityOutServiceDTO entity) {
entity.setId(null);
return restTemplate.exchange(
fromUriString(integrationConfig.getExistingMicroservicesDataServerUrl()).build().normalize().encode().toUriString(),
POST, new HttpEntity<>(entity), MyEntityOutServiceDTO.class
).getBody();
}
- Deletion: method delete
Example
- Update of existing entries: method update
Example
public MyEntityOutServiceDTO update(BusinessComponent bc, MyEntityOutServiceDTO entity) {
return restTemplate.exchange(
fromUriString(integrationConfig.getExistingMicroservicesDataServerUrl()).build().normalize().encode().toUriString(),
PUT, new HttpEntity<>(entity), MyEntityOutServiceDTO.class
).getBody();
}
-
Getting all data: method getList
Page size:
Limit:
Sorting for field CustomField:
List<String> sortCustomField = getSortFieldName(queryParameters, "customField"); Optional<String> sort = sortCustomField.isEmpty() ? Optional.empty() : Optional.of(sortCustomField.get(0));
Filter for field CustomField:
Example
@Override
public Page<MyEntityOutServiceDTO> getList(final BusinessComponent bc, final QueryParameters queryParameters) {
//Page size
String page = bc.getParameters().getParameter("_page");
//Limit
String limit = bc.getParameters().getParameter("_limit");
//Filter
List<String> filterCustomField = getFilterFieldName(queryParameters, "customField", "contains");
Optional<String> filter = filterCustomField.isEmpty() ? Optional.empty() : Optional.of(filterCustomField.get(0));
//Sorting
List<String> sortCustomField = getSortFieldName(queryParameters, "customField");
Optional<String> sort = sortCustomField.isEmpty() ? Optional.empty() : Optional.of(sortCustomField.get(0));
String urlTemplate = UriComponentsBuilder.fromHttpUrl(integrationConfig.getExistingMicroservicesDataServerUrl())
.queryParam("number", page)
.queryParam("size", limit)
.queryParamIfPresent("filterCustomField", filter)
.queryParamIfPresent("sortCustomField", sort)
.encode()
.toUriString();
ResponseEntity<RestResponsePage<MyEntityOutServiceDTO>> responseEntity = restTemplate.exchange(
urlTemplate,
HttpMethod.GET,
null,
new ParameterizedTypeReference<>() {
},
filter
);
return responseEntity.getBody();
}
private List<String> getSortFieldName(QueryParameters queryParameters, String fieldName) {
return queryParameters.getParameters().entrySet().stream()
.filter(f -> f.getKey().contains("_sort"))
.filter(f -> f.getValue().contains(fieldName))
.map(m -> {
String[] splitOperation = m.getKey().split("\\.");
return splitOperation[splitOperation.length - 1];
}
).toList();
}
private List<String> getFilterFieldName(QueryParameters queryParameters, String fieldName, String searchSpec) {
return queryParameters.getParameters().entrySet().stream()
.filter(f -> f.getKey().contains(fieldName + "." + searchSpec))
.map(Map.Entry::getValue)
.toList();
}
- Getting data by ID: method getByIdIgnoringFirstLevelCache
Example
@Override
public MyEntityOutServiceDTO getByIdIgnoringFirstLevelCache(final BusinessComponent bc) {
return restTemplate.exchange(
fromUriString(integrationConfig.getExistingMicroservicesDataServerUrl() + "/{id}").build()
.expand(bc.getIdAsLong()).normalize().encode()
.toUriString(),
GET, null, MyEntityOutServiceDTO.class
).getBody();
}
Step 3 Create DTO
Create DTO extends DataResponseDTO
Example
Step4 Create MetaBuilder
Create MetaBuilder extends AnySourceFieldMetaBuilder
Example
@SuppressWarnings("EmptyMethod")
@Service
public class MyExampleMeta extends AnySourceFieldMetaBuilder<MyExampleDTO> {
@Override
public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, BcDescription bc,
String id, String parentId) {
fields.setEnabled(MyExampleDTO_.customField);
}
@Override
public void buildIndependentMeta(FieldsMeta<MyExampleDTO> fields, BcDescription bcDescription,
String parentId) {
fields.enableFilter(MyExampleDTO_.customField);
fields.enableSort(MyExampleDTO_.customField);
}
}
Step5 Create Service
Create Service extends AnySourceVersionAwareResponseService
Example
@SuppressWarnings({"java:S", "java:S"})
@RequiredArgsConstructor
@Service
public class MyExampleService extends AnySourceVersionAwareResponseService<MyExampleDTO, MyEntityOutServiceDTO> {
@Getter(onMethod_ = @Override)
private final Class<MyExampleMeta> meta = MyExampleMeta.class;
@Getter(onMethod_ = @Override)
private final Class<MyEntityDao> dao = MyEntityDao.class;
@Override
protected CreateResult<MyExampleDTO> doCreateEntity(MyEntityOutServiceDTO entity, BusinessComponent bc) {
return new CreateResult<>(entityToDto(bc, entity));
}
@Override
protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntityOutServiceDTO entity, MyExampleDTO data, BusinessComponent bc) {
if (data.isFieldChanged(MyExampleDTO_.customField)) {
entity.setCustomField(data.getCustomField());
}
return new ActionResultDTO<>(entityToDto(bc, entity));
}
@Override
public Actions<MyExampleDTO> getActions() {
return Actions.<MyExampleDTO>builder()
.create(crt -> crt.text("Add"))
.addGroup(
"actions",
"Actions",
0,
Actions.<MyExampleDTO>builder()
.action(act -> act
.action("delete", "delete")
)
.action(act -> act
.action("save", "save")
)
.build()).
build();
}
}
Step6 Create Controller
Create Controller implements EnumBcIdentifier
Example
@Getter
public enum PlatformMyExampleController implements EnumBcIdentifier {
myExampleBc(MyExampleService.class);
public static final EnumBcIdentifier.Holder<PlatformMyExampleController> Holder = new Holder<>(
PlatformMyExampleController.class);
private final BcDescription bcDescription;
PlatformMyExampleController(String parentName, Class<?> serviceClass, boolean refresh) {
this.bcDescription = buildDescription(parentName, serviceClass, refresh);
}
PlatformMyExampleController(Class<?> serviceClass) {
this((String) null, serviceClass, false);
}
@Component
public static class BcSupplier extends AbstractEnumBcSupplier<PlatformMyExampleController> {
public BcSupplier() {
super(PlatformMyExampleController.Holder);
}
}
}
Step7 Create widget.json
Example
Step8 Create view.json
Example
{
"name": "myexamplelist",
"title": "My example List",
"url": "/screen/myexample/view/myexamplelist",
"template": "DashboardView",
"widgets": [
{
"widgetName": "SecondLevelMenu",
"position": 0,
"gridWidth": 24
},
{
"widgetName": "MyExampleList",
"position": 20,
"gridWidth": 24
}
],
"rolesAllowed": [
"CXBOX_USER"
]
}
Step9 Create screen.json
Example
{
"name": "myexample",
"icon": "calendar",
"order": 3800,
"title": "Existing microservice",
"navigation": {
"type": "standard",
"menu": [
{
"title": "List",
"child": [
{
"viewName": "myexamplelist"
}
]
},
{
"title": "Info",
"child": [
{
"viewName": "myexampleinfo"
}
]
},
{
"title": "Form",
"child": [
{
"viewName": "myexampleform"
}
]
}
]
}
}