Команды
Команда — декларативное описание действия, которое нужно сделать на удаленном сервисе или локально.
Команды в Citeck ECOS в качестве транспорта используют очереди RabbitMQ. Использование команд возможно как в синхронном, так и в асинхронном режиме.
Целью команд могут быть:
Тип сервиса (ecos-process, ecos-uiserv, alfresco и др.). Команду исполняет один из инстансов данного сервиса.
Инстанс сервиса (у каждого типа сервиса может быть много инстансов).
Все типы сервисов (широковещательные команды). Сервис-источник команды отправляет широковещательную команду в RabbitMQ и её обрабатывают все сервисы, которые в данный момент активны.
Выполнение команды осуществляется с помощью сервиса CommandService. В частности его методом execute и executeSync:
Команды могут быть как локальными (т.е. исполняются в рамках одного сервиса), так и удаленными (команда отправляется в другой микросервис, в этом случае необходимо указать id микросервиса, куда отправится команда)
Для реализации удаленной команды:
Создать DTO в сервисе, ИЗ которого будет отправлена команда и там где она будет исполняться, например, если необходимо отправить команду из alfresco в микросервис интеграций, то необходимо создать 2 идентичных класса, один в alfresco, а второй в микросервис интеграций:
@Data
@CommandType("execute-spark-method")
public class SparkServiceMethodCommand {
private String dataSourceId;
private String methodName;
private Map<String, String> methodAttributes;
}
Обязательно указать аннотацию CommandType с уникальным именем команды (по ней определяется какому Executorу будет отдана данная команда (см. пункт 3)).
Также необходим DTO с ожидаемым ответом, его также необходимо реализовать в обоих сервисах.
По сути отправляем DTO c данными, который конвертируется в json, затем отправляется в нужный микросервис, там конвертируется обратно в DTO и с ним уже работает executor, после обработки executorом снова необходимо отдать DTO c ответом, который также конвертируется в json и отсылается обратно в то место, откуда была вызвана команда, там он опять трансформируется из json в ResponseDTO. Например, ответ, который ожидаем от исполнения команды высланным выше DTO:
@AllArgsConstructor
@NoArgsConstructor
@Data
public class SparkServiceMethodCommandResponse {
private String status;
private String xmlContent;
}
В сервисе, КУДА отсылается команда, необходимо реализовать Executor, который будет обрабатывать DTO.
В executor необходимо имплиментировать интерфейс CommandExecutor<E> , где E - входящий DTO (п.1)
Также необходимо реализовать метод execute(E), в котором собственно и заключается обработка самой команды. Т.е. принимаем на вход DTO c запросом (п.1), берем из него данные, обрабатываем, затем формируем DTO с ответом в этом методе и возвращаем его.
Пример:
public class CallSparkServiceCommandExecutor implements CommandExecutor<SparkServiceMethodCommand> {
@Override
public SparkServiceMethodCommandResponse execute(SparkServiceMethodCommand executeServiceMethodCommand) {
String statusString = "Error";
String methodName = executeServiceMethodCommand.getMethodName();
if (methodName.equals("Complete")) {
statusString = "Done";
}
SparkServiceMethodCommandResponse response = new SparkServiceMethodCommandResponse();
response.setStatus(statusString);
response.setXmlContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><TestTag>Test</TestTag>");
return response;
}
}
Пример логики, где просто проверяем имя метода и формируем ответную DTO.
В сервисе, ИЗ которого отправляем командный запрос, используем CommandService для отправки команды, пример:
public String sendSparkRequest(String dataSourceId, String methodName, Map<String, String> attributes) {
SparkServiceMethodCommand command = new SparkServiceMethodCommand();
command.setDataSourceId(dataSourceId);
command.setMethodName(methodName);
command.setMethodAttributes(attributes);
SparkServiceMethodCommandResponse result = commandsService.executeSync(command, "integrations")
.getResultAs(SparkServiceMethodCommandResponse.class);
return result.getXmlContent();
}
В данном примере формируем DTO (также можно использовать builder) и отправляем команду в микросервис интеграций, явно указывая это во втором параметре.
В ответе ожидаем SparkServiceMethodCommandResponse DTO и используем метод .getResultAs для автоматической конвертации ответа в удобный DTO.