- command type 이 deploy 타입일 경우 파일 유효성 검사 로직 추가
This commit is contained in:
parent
c625560cc6
commit
15be9161f3
|
@ -1,7 +1,11 @@
|
||||||
package inc.sdt.blokworks.devicedeployer;
|
package inc.sdt.blokworks.devicedeployer;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.presentation.rest.RestTemplateResponseErrorHandler;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class DeviceDeployerApplication {
|
public class DeviceDeployerApplication {
|
||||||
|
@ -10,4 +14,11 @@ public class DeviceDeployerApplication {
|
||||||
SpringApplication.run(DeviceDeployerApplication.class, args);
|
SpringApplication.run(DeviceDeployerApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate(RestTemplateBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.errorHandler(new RestTemplateResponseErrorHandler())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ import java.util.LinkedHashMap;
|
||||||
@Component
|
@Component
|
||||||
public class BashCommand implements CommandInfo{
|
public class BashCommand implements CommandInfo{
|
||||||
@Override
|
@Override
|
||||||
public LinkedHashMap<String, Object> put(OutboundMessage message, LinkedHashMap<String, Object> map) {
|
public LinkedHashMap<String, Object> put(OutboundMessage message) {
|
||||||
|
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("cmd", message.getCommand());
|
map.put("cmd", message.getCommand());
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,5 @@ import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
public interface CommandInfo {
|
public interface CommandInfo {
|
||||||
LinkedHashMap<String, Object> put(OutboundMessage message, LinkedHashMap<String, Object> map);
|
LinkedHashMap<String, Object> put(OutboundMessage message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.application;
|
package inc.sdt.blokworks.devicedeployer.application;
|
||||||
|
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.presentation.GiteaApiRequestHandler;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -13,7 +14,11 @@ public class CommandInvoker {
|
||||||
private final JsonCommand jsonCommand;
|
private final JsonCommand jsonCommand;
|
||||||
private final DeployCommandInvoker deployCommandInvoker;
|
private final DeployCommandInvoker deployCommandInvoker;
|
||||||
|
|
||||||
public CommandInvoker(BashCommand bashCommand, SystemdCommand systemdCommand, DockerCommand dockerCommand, JsonCommand jsonCommand, DeployCommandInvoker deployCommandInvoker) {
|
public CommandInvoker(BashCommand bashCommand,
|
||||||
|
SystemdCommand systemdCommand,
|
||||||
|
DockerCommand dockerCommand,
|
||||||
|
JsonCommand jsonCommand,
|
||||||
|
DeployCommandInvoker deployCommandInvoker) {
|
||||||
this.bashCommand = bashCommand;
|
this.bashCommand = bashCommand;
|
||||||
this.systemdCommand = systemdCommand;
|
this.systemdCommand = systemdCommand;
|
||||||
this.dockerCommand = dockerCommand;
|
this.dockerCommand = dockerCommand;
|
||||||
|
@ -21,22 +26,25 @@ public class CommandInvoker {
|
||||||
this.deployCommandInvoker = deployCommandInvoker;
|
this.deployCommandInvoker = deployCommandInvoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedHashMap<String, Object> invoke(OutboundMessage message, LinkedHashMap<String, Object> map) {
|
public LinkedHashMap<String, Object> invoke(OutboundMessage message) {
|
||||||
|
if(message.getCommandType() == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
switch (message.getCommandType()) {
|
switch (message.getCommandType()) {
|
||||||
case bash -> {
|
case bash -> {
|
||||||
return bashCommand.put(message, map);
|
return bashCommand.put(message);
|
||||||
}
|
}
|
||||||
case systemd -> {
|
case systemd -> {
|
||||||
return systemdCommand.put(message, map);
|
return systemdCommand.put(message);
|
||||||
}
|
}
|
||||||
case docker -> {
|
case docker -> {
|
||||||
return dockerCommand.put(message, map);
|
return dockerCommand.put(message);
|
||||||
}
|
}
|
||||||
case deploy -> {
|
case deploy -> {
|
||||||
return deployCommandInvoker.invoke(message, map);
|
return deployCommandInvoker.invoke(message);
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
return jsonCommand.put(message, map);
|
return jsonCommand.put(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.*;
|
import inc.sdt.blokworks.devicedeployer.domain.*;
|
||||||
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessagePayload;
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessagePayload;
|
||||||
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.OutboundMessagePayload;
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.OutboundMessagePayload;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.presentation.GiteaApiRequestHandler;
|
||||||
import org.eclipse.paho.client.mqttv3.IMqttClient;
|
import org.eclipse.paho.client.mqttv3.IMqttClient;
|
||||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
@ -25,36 +25,27 @@ public class DefaultDeployerService implements DeployerService{
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
private final DeployerRepositoryDelegate deployerRepositoryDelegate;
|
private final DeployerRepositoryDelegate deployerRepositoryDelegate;
|
||||||
private final DeployRequestRepositoryDelegate requestRepositoryDelegate;
|
private final DeployRequestRepositoryDelegate requestRepositoryDelegate;
|
||||||
private final CommandInvoker commandInvoker;
|
|
||||||
|
|
||||||
public DefaultDeployerService(IMqttClient mqttClient,
|
public DefaultDeployerService(IMqttClient mqttClient,
|
||||||
ObjectMapper objectMapper,
|
ObjectMapper objectMapper,
|
||||||
DeployerRepositoryDelegate deployerRepositoryDelegate,
|
DeployerRepositoryDelegate deployerRepositoryDelegate,
|
||||||
DeployRequestRepositoryDelegate requestRepositoryDelegate,
|
DeployRequestRepositoryDelegate requestRepositoryDelegate) {
|
||||||
CommandInvoker commandInvoker) {
|
|
||||||
this.log = LoggerFactory.getLogger(this.getClass());
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
this.mqttClient = mqttClient;
|
this.mqttClient = mqttClient;
|
||||||
this.objectMapper = objectMapper;
|
this.objectMapper = objectMapper;
|
||||||
this.deployerRepositoryDelegate = deployerRepositoryDelegate;
|
this.deployerRepositoryDelegate = deployerRepositoryDelegate;
|
||||||
this.requestRepositoryDelegate = requestRepositoryDelegate;
|
this.requestRepositoryDelegate = requestRepositoryDelegate;
|
||||||
this.commandInvoker = commandInvoker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void publish(OutboundMessage outboundMessage, String assetCode) {
|
public void publish(OutboundMessage outboundMessage) {
|
||||||
log.info("[publish] deployMessage = {}, assetCode = {}", outboundMessage, assetCode);
|
log.info("[publish] outboundMessage = {}", outboundMessage);
|
||||||
final DeviceType deviceType = outboundMessage.getDeviceType();
|
|
||||||
LinkedHashMap<String, Object> commandInfo = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
commandInfo = commandInvoker.invoke(outboundMessage, commandInfo);
|
|
||||||
|
|
||||||
OutboundMessagePayload payload = new OutboundMessagePayload(
|
OutboundMessagePayload payload = new OutboundMessagePayload(
|
||||||
commandInfo,
|
outboundMessage.getCommandInfo(),
|
||||||
outboundMessage.getCommandType(),
|
outboundMessage.getCommandType(),
|
||||||
outboundMessage.getSubCommandType(),
|
outboundMessage.getSubCommandType(),
|
||||||
deviceType,
|
outboundMessage.getAssetCode(),
|
||||||
assetCode,
|
|
||||||
outboundMessage.getRequestId()
|
outboundMessage.getRequestId()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -62,8 +53,8 @@ public class DefaultDeployerService implements DeployerService{
|
||||||
MqttMessage message = new MqttMessage();
|
MqttMessage message = new MqttMessage();
|
||||||
message.setPayload(bytes);
|
message.setPayload(bytes);
|
||||||
|
|
||||||
mqttClient.publish("/devicecontrol/"+deviceType+"/"+assetCode, message);
|
mqttClient.publish("/device-control/"+outboundMessage.getAssetCode(), message);
|
||||||
log.info("[publish] message = {}", message);
|
log.info("[publish] payload = {}", payload);
|
||||||
}catch (JsonProcessingException | MqttException e) {
|
}catch (JsonProcessingException | MqttException e) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,14 @@ import java.util.LinkedHashMap;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class DeployCommand implements CommandInfo {
|
public class DeployCommand implements CommandInfo {
|
||||||
private final String filePath;
|
|
||||||
|
|
||||||
public DeployCommand(@Value("${stackbase.api.host}") String filePath) {
|
|
||||||
this.filePath = filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LinkedHashMap<String, Object> put(OutboundMessage message, LinkedHashMap<String, Object> map) {
|
public LinkedHashMap<String, Object> put(OutboundMessage message) {
|
||||||
final String url = filePath + message.getFileId();
|
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("cmd", message.getCommand());
|
map.put("cmd", message.getCommand());
|
||||||
map.put("appName", message.getAppName());
|
map.put("appName", message.getAppName());
|
||||||
map.put("name", message.getName());
|
map.put("name", message.getName());
|
||||||
map.put("fileUrl", url);
|
map.put("fileUrl", message.getUrl());
|
||||||
map.put("fileType", message.getFileType());
|
map.put("fileType", message.getFileType());
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,42 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.application;
|
package inc.sdt.blokworks.devicedeployer.application;
|
||||||
|
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.SubCommandType;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.presentation.GiteaApiRequestHandler;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class DeployCommandInvoker {
|
public class DeployCommandInvoker {
|
||||||
private final DockerCommand dockerCommand;
|
private final DockerCommand dockerCommand;
|
||||||
private final DeployCommand deployCommand;
|
private final DeployCommand deployCommand;
|
||||||
|
private final JsonCommand jsonCommand;
|
||||||
|
|
||||||
public DeployCommandInvoker(DockerCommand dockerCommand, DeployCommand deployCommand) {
|
public DeployCommandInvoker(DockerCommand dockerCommand, DeployCommand deployCommand, JsonCommand jsonCommand) {
|
||||||
this.dockerCommand = dockerCommand;
|
this.dockerCommand = dockerCommand;
|
||||||
this.deployCommand = deployCommand;
|
this.deployCommand = deployCommand;
|
||||||
|
this.jsonCommand = jsonCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedHashMap<String, Object> invoke(OutboundMessage message, LinkedHashMap<String, Object> map) {
|
public LinkedHashMap<String, Object> invoke(OutboundMessage message) {
|
||||||
|
if(message.getSubCommandType() == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
switch (message.getSubCommandType()) {
|
switch (message.getSubCommandType()) {
|
||||||
case systemd -> {
|
case systemd -> {
|
||||||
return deployCommand.put(message, map);
|
return deployCommand.put(message);
|
||||||
|
}
|
||||||
|
case docker -> {
|
||||||
|
return dockerCommand.put(message);
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
return dockerCommand.put(message, map);
|
return jsonCommand.put(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,12 @@ import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessage
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface DeployerService extends Function<InboundDeployMessagePayload, Mono<Void>> {
|
public interface DeployerService extends Function<InboundDeployMessagePayload, Mono<Void>> {
|
||||||
void publish(OutboundMessage assetApp, String assetCode);
|
void publish(OutboundMessage message);
|
||||||
DeployRequest save(DeployRequest deployRequest);
|
DeployRequest save(DeployRequest deployRequest);
|
||||||
Page<AssetApp> getAll(String assetCode, int page, int size);
|
Page<AssetApp> getAll(String assetCode, int page, int size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,10 @@ import java.util.LinkedHashMap;
|
||||||
public class DockerCommand implements CommandInfo {
|
public class DockerCommand implements CommandInfo {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LinkedHashMap<String, Object> put(OutboundMessage message, LinkedHashMap<String, Object> map) {
|
public LinkedHashMap<String, Object> put(OutboundMessage message) {
|
||||||
|
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("cmd", message.getCommand());
|
map.put("cmd", message.getCommand());
|
||||||
|
map.put("appName", message.getAppName());
|
||||||
map.put("name", message.getName()); // container 이름
|
map.put("name", message.getName()); // container 이름
|
||||||
map.put("image", message.getImage());
|
map.put("image", message.getImage());
|
||||||
map.put("options", message.getOptions());
|
map.put("options", message.getOptions());
|
||||||
|
|
|
@ -8,7 +8,8 @@ import java.util.LinkedHashMap;
|
||||||
@Component
|
@Component
|
||||||
public class JsonCommand implements CommandInfo {
|
public class JsonCommand implements CommandInfo {
|
||||||
@Override
|
@Override
|
||||||
public LinkedHashMap<String, Object> put(OutboundMessage message, LinkedHashMap<String, Object> map) {
|
public LinkedHashMap<String, Object> put(OutboundMessage message) {
|
||||||
|
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("cmd", String.valueOf(message.getCommandType()));
|
map.put("cmd", String.valueOf(message.getCommandType()));
|
||||||
map.put("appName", message.getAppName());
|
map.put("appName", message.getAppName());
|
||||||
map.put("parameter", message.getParameters());
|
map.put("parameter", message.getParameters());
|
||||||
|
|
|
@ -8,7 +8,8 @@ import java.util.LinkedHashMap;
|
||||||
@Component
|
@Component
|
||||||
public class SystemdCommand implements CommandInfo {
|
public class SystemdCommand implements CommandInfo {
|
||||||
@Override
|
@Override
|
||||||
public LinkedHashMap<String, Object> put(OutboundMessage message, LinkedHashMap<String, Object> map) {
|
public LinkedHashMap<String, Object> put(OutboundMessage message) {
|
||||||
|
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("cmd", message.getCommand());
|
map.put("cmd", message.getCommand());
|
||||||
map.put("service", message.getAppName());
|
map.put("service", message.getAppName());
|
||||||
return map;
|
return map;
|
||||||
|
|
|
@ -5,18 +5,16 @@ public class DeployRequest {
|
||||||
private String assetCode;
|
private String assetCode;
|
||||||
private String appName;
|
private String appName;
|
||||||
private OperationType operationType;
|
private OperationType operationType;
|
||||||
private DeviceType deviceType;
|
|
||||||
private CommandType commandType;
|
private CommandType commandType;
|
||||||
private SubCommandType subCommandType;
|
private SubCommandType subCommandType;
|
||||||
|
|
||||||
protected DeployRequest() {}
|
protected DeployRequest() {}
|
||||||
|
|
||||||
public DeployRequest(String requestId, String assetCode, String appName, OperationType operationType, DeviceType deviceType, CommandType commandType, SubCommandType subCommandType) {
|
public DeployRequest(String requestId, String assetCode, String appName, OperationType operationType, CommandType commandType, SubCommandType subCommandType) {
|
||||||
this.requestId = requestId;
|
this.requestId = requestId;
|
||||||
this.assetCode = assetCode;
|
this.assetCode = assetCode;
|
||||||
this.appName = appName;
|
this.appName = appName;
|
||||||
this.operationType = operationType;
|
this.operationType = operationType;
|
||||||
this.deviceType = deviceType;
|
|
||||||
this.commandType = commandType;
|
this.commandType = commandType;
|
||||||
this.subCommandType = subCommandType;
|
this.subCommandType = subCommandType;
|
||||||
}
|
}
|
||||||
|
@ -37,10 +35,6 @@ public class DeployRequest {
|
||||||
return operationType;
|
return operationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceType getDeviceType() {
|
|
||||||
return deviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandType getCommandType() {
|
public CommandType getCommandType() {
|
||||||
return commandType;
|
return commandType;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +50,6 @@ public class DeployRequest {
|
||||||
", assetCode='" + assetCode + '\'' +
|
", assetCode='" + assetCode + '\'' +
|
||||||
", appName='" + appName + '\'' +
|
", appName='" + appName + '\'' +
|
||||||
", operationType=" + operationType +
|
", operationType=" + operationType +
|
||||||
", deviceType=" + deviceType +
|
|
||||||
", commandType=" + commandType +
|
", commandType=" + commandType +
|
||||||
", subCommandType=" + subCommandType +
|
", subCommandType=" + subCommandType +
|
||||||
'}';
|
'}';
|
||||||
|
@ -71,7 +64,6 @@ public class DeployRequest {
|
||||||
private String assetCode;
|
private String assetCode;
|
||||||
private String appName;
|
private String appName;
|
||||||
private OperationType operationType;
|
private OperationType operationType;
|
||||||
private DeviceType deviceType;
|
|
||||||
private CommandType commandType;
|
private CommandType commandType;
|
||||||
private SubCommandType subCommandType;
|
private SubCommandType subCommandType;
|
||||||
|
|
||||||
|
@ -95,11 +87,6 @@ public class DeployRequest {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder deviceType(DeviceType deviceType) {
|
|
||||||
this.deviceType = deviceType;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder commandType(CommandType commandType) {
|
public Builder commandType(CommandType commandType) {
|
||||||
this.commandType = commandType;
|
this.commandType = commandType;
|
||||||
return this;
|
return this;
|
||||||
|
@ -116,7 +103,6 @@ public class DeployRequest {
|
||||||
deployRequest.assetCode = this.assetCode;
|
deployRequest.assetCode = this.assetCode;
|
||||||
deployRequest.appName = this.appName;
|
deployRequest.appName = this.appName;
|
||||||
deployRequest.operationType = this.operationType;
|
deployRequest.operationType = this.operationType;
|
||||||
deployRequest.deviceType = this.deviceType;
|
|
||||||
deployRequest.commandType = this.commandType;
|
deployRequest.commandType = this.commandType;
|
||||||
deployRequest.subCommandType = this.subCommandType;
|
deployRequest.subCommandType = this.subCommandType;
|
||||||
return deployRequest;
|
return deployRequest;
|
||||||
|
|
|
@ -3,29 +3,38 @@ package inc.sdt.blokworks.devicedeployer.domain;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
public class OutboundMessage {
|
public class OutboundMessage {
|
||||||
private String fileId;
|
private String url;
|
||||||
private String fileType;
|
private String fileType;
|
||||||
|
private String assetCode;
|
||||||
private String appName; // 사용자가 정한 파일 이름
|
private String appName; // 사용자가 정한 파일 이름
|
||||||
private String name; // stackbase 에 저장된 파일 이름
|
private String name; // stackbase 에 저장된 파일 이름
|
||||||
private String image;
|
private String image;
|
||||||
private LinkedHashMap<String, Object> options;
|
private LinkedHashMap<String, Object> options;
|
||||||
private String command;
|
private String command;
|
||||||
private String requestId;
|
private String requestId;
|
||||||
private DeviceType deviceType;
|
|
||||||
private CommandType commandType;
|
private CommandType commandType;
|
||||||
private SubCommandType subCommandType;
|
private SubCommandType subCommandType;
|
||||||
private LinkedHashMap<String, String> parameters;
|
private LinkedHashMap<String, String> parameters;
|
||||||
|
private LinkedHashMap<String, Object> commandInfo;
|
||||||
|
|
||||||
protected OutboundMessage() {}
|
protected OutboundMessage() {}
|
||||||
|
|
||||||
public String getFileId() {
|
public String getUrl() {
|
||||||
return fileId;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileType() {
|
public String getFileType() {
|
||||||
return fileType;
|
return fileType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAssetCode() {
|
||||||
|
return assetCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAssetCode(String assetCode) {
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAppName() {
|
public String getAppName() {
|
||||||
return appName;
|
return appName;
|
||||||
}
|
}
|
||||||
|
@ -54,10 +63,6 @@ public class OutboundMessage {
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceType getDeviceType() {
|
|
||||||
return deviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandType getCommandType() {
|
public CommandType getCommandType() {
|
||||||
return commandType;
|
return commandType;
|
||||||
}
|
}
|
||||||
|
@ -70,21 +75,30 @@ public class OutboundMessage {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LinkedHashMap<String, Object> getCommandInfo() {
|
||||||
|
return commandInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommandInfo(LinkedHashMap<String, Object> commandInfo) {
|
||||||
|
this.commandInfo = commandInfo;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "OutboundMessage{" +
|
return "OutboundMessage{" +
|
||||||
"fileId='" + fileId + '\'' +
|
"url='" + url + '\'' +
|
||||||
", fileType='" + fileType + '\'' +
|
", fileType='" + fileType + '\'' +
|
||||||
|
", assetCode='" + assetCode + '\'' +
|
||||||
", appName='" + appName + '\'' +
|
", appName='" + appName + '\'' +
|
||||||
", name='" + name + '\'' +
|
", name='" + name + '\'' +
|
||||||
", image='" + image + '\'' +
|
", image='" + image + '\'' +
|
||||||
", options=" + options +
|
", options=" + options +
|
||||||
", command='" + command + '\'' +
|
", command='" + command + '\'' +
|
||||||
", requestId='" + requestId + '\'' +
|
", requestId='" + requestId + '\'' +
|
||||||
", deviceType=" + deviceType +
|
|
||||||
", commandType=" + commandType +
|
", commandType=" + commandType +
|
||||||
", subCommandType=" + subCommandType +
|
", subCommandType=" + subCommandType +
|
||||||
", parameters=" + parameters +
|
", parameters=" + parameters +
|
||||||
|
", commandInfo=" + commandInfo +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,21 +107,22 @@ public class OutboundMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
private String fileId;
|
private String url;
|
||||||
private String fileType;
|
private String fileType;
|
||||||
|
private String assetCode;
|
||||||
private String appName;
|
private String appName;
|
||||||
private String name;
|
private String name;
|
||||||
private String image;
|
private String image;
|
||||||
private LinkedHashMap<String, Object> options;
|
private LinkedHashMap<String, Object> options;
|
||||||
private String command;
|
private String command;
|
||||||
private String requestId;
|
private String requestId;
|
||||||
private DeviceType deviceType;
|
|
||||||
private CommandType commandType;
|
private CommandType commandType;
|
||||||
private SubCommandType subCommandType;
|
private SubCommandType subCommandType;
|
||||||
private LinkedHashMap<String, String> parameters;
|
private LinkedHashMap<String, String> parameters;
|
||||||
|
private LinkedHashMap<String, Object> commandInfo;
|
||||||
|
|
||||||
public Builder fileId(String fileId) {
|
public Builder url(String url) {
|
||||||
this.fileId = fileId;
|
this.url = url;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +131,11 @@ public class OutboundMessage {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder assetCode(String assetCode) {
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder appName(String appName) {
|
public Builder appName(String appName) {
|
||||||
this.appName = appName;
|
this.appName = appName;
|
||||||
return this;
|
return this;
|
||||||
|
@ -146,11 +166,6 @@ public class OutboundMessage {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder deviceType(DeviceType deviceType) {
|
|
||||||
this.deviceType = deviceType;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder commandType(CommandType commandType) {
|
public Builder commandType(CommandType commandType) {
|
||||||
this.commandType = commandType;
|
this.commandType = commandType;
|
||||||
return this;
|
return this;
|
||||||
|
@ -166,20 +181,26 @@ public class OutboundMessage {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder commandInfo(LinkedHashMap<String, Object> commandInfo) {
|
||||||
|
this.commandInfo = commandInfo;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public OutboundMessage build() {
|
public OutboundMessage build() {
|
||||||
OutboundMessage deployMessage = new OutboundMessage();
|
OutboundMessage deployMessage = new OutboundMessage();
|
||||||
deployMessage.fileId = this.fileId;
|
deployMessage.url = this.url;
|
||||||
deployMessage.fileType = this.fileType;
|
deployMessage.fileType = this.fileType;
|
||||||
|
deployMessage.assetCode = this.assetCode;
|
||||||
deployMessage.appName = this.appName;
|
deployMessage.appName = this.appName;
|
||||||
deployMessage.name = this.name;
|
deployMessage.name = this.name;
|
||||||
deployMessage.image = this.image;
|
deployMessage.image = this.image;
|
||||||
deployMessage.options = this.options;
|
deployMessage.options = this.options;
|
||||||
deployMessage.command = this.command;
|
deployMessage.command = this.command;
|
||||||
deployMessage.requestId = this.requestId;
|
deployMessage.requestId = this.requestId;
|
||||||
deployMessage.deviceType = this.deviceType;
|
|
||||||
deployMessage.commandType = this.commandType;
|
deployMessage.commandType = this.commandType;
|
||||||
deployMessage.subCommandType = this.subCommandType;
|
deployMessage.subCommandType = this.subCommandType;
|
||||||
deployMessage.parameters = this.parameters;
|
deployMessage.parameters = this.parameters;
|
||||||
|
deployMessage.commandInfo = this.commandInfo;
|
||||||
return deployMessage;
|
return deployMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.domain;
|
||||||
|
|
||||||
|
public record Result(
|
||||||
|
String name,
|
||||||
|
int pid,
|
||||||
|
int size,
|
||||||
|
String message,
|
||||||
|
long releasedAt,
|
||||||
|
long updatedAt
|
||||||
|
){}
|
|
@ -1,6 +1,7 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.domain;
|
package inc.sdt.blokworks.devicedeployer.domain;
|
||||||
|
|
||||||
public enum Status {
|
public record Status(
|
||||||
success,
|
int succeed,
|
||||||
fail
|
int statusCode,
|
||||||
}
|
String errMsg
|
||||||
|
){}
|
|
@ -2,5 +2,6 @@ package inc.sdt.blokworks.devicedeployer.domain;
|
||||||
|
|
||||||
public enum SubCommandType {
|
public enum SubCommandType {
|
||||||
systemd,
|
systemd,
|
||||||
docker
|
docker,
|
||||||
|
single
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.infrastructure.mqtt;
|
package inc.sdt.blokworks.devicedeployer.infrastructure.mqtt;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Result;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.Status;
|
import inc.sdt.blokworks.devicedeployer.domain.Status;
|
||||||
|
|
||||||
public record InboundDeployMessagePayload(
|
public record InboundDeployMessagePayload(
|
||||||
|
@ -9,12 +10,4 @@ public record InboundDeployMessagePayload(
|
||||||
Result result,
|
Result result,
|
||||||
String requestId
|
String requestId
|
||||||
) {
|
) {
|
||||||
public record Result(
|
|
||||||
String name,
|
|
||||||
int pid,
|
|
||||||
int size,
|
|
||||||
String message,
|
|
||||||
long releasedAt,
|
|
||||||
long updatedAt
|
|
||||||
){}
|
|
||||||
}
|
}
|
|
@ -10,7 +10,6 @@ public record OutboundMessagePayload(
|
||||||
HashMap<String, Object> cmdInfo,
|
HashMap<String, Object> cmdInfo,
|
||||||
CommandType cmdType,
|
CommandType cmdType,
|
||||||
SubCommandType subCmdType,
|
SubCommandType subCmdType,
|
||||||
DeviceType deviceType,
|
|
||||||
String assetCode,
|
String assetCode,
|
||||||
String requestId
|
String requestId
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.infrastructure.relational;
|
package inc.sdt.blokworks.devicedeployer.infrastructure.relational;
|
||||||
|
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.Status;
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
@Entity(name = "asset_app")
|
@Entity(name = "asset_app")
|
||||||
|
@ -21,20 +20,25 @@ class AssetAppEntity {
|
||||||
private Long updatedAt;
|
private Long updatedAt;
|
||||||
@Column(name = "pid")
|
@Column(name = "pid")
|
||||||
private int pid;
|
private int pid;
|
||||||
@Column(name = "status")
|
@Column(name = "succeed")
|
||||||
@Enumerated(EnumType.STRING)
|
private int succeed;
|
||||||
private Status status;
|
@Column(name = "statusCode")
|
||||||
|
private int statusCode;
|
||||||
|
@Column(name = "error_message")
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
protected AssetAppEntity() {}
|
protected AssetAppEntity() {}
|
||||||
|
|
||||||
public AssetAppEntity(String assetCode, String name, int size, Long releasedAt, Long updatedAt, int pid, Status status) {
|
public AssetAppEntity(String assetCode, String name, int size, Long releasedAt, Long updatedAt, int pid, int succeed, int statusCode, String errorMessage) {
|
||||||
this.assetCode = assetCode;
|
this.assetCode = assetCode;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.releasedAt = releasedAt;
|
this.releasedAt = releasedAt;
|
||||||
this.updatedAt = updatedAt;
|
this.updatedAt = updatedAt;
|
||||||
this.pid = pid;
|
this.pid = pid;
|
||||||
this.status = status;
|
this.succeed = succeed;
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -65,7 +69,15 @@ class AssetAppEntity {
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Status getStatus() {
|
public int getSucceed() {
|
||||||
return status;
|
return succeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return errorMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package inc.sdt.blokworks.devicedeployer.infrastructure.relational;
|
||||||
|
|
||||||
import inc.sdt.blokworks.devicedeployer.application.DeployerRepositoryDelegate;
|
import inc.sdt.blokworks.devicedeployer.application.DeployerRepositoryDelegate;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.AssetApp;
|
import inc.sdt.blokworks.devicedeployer.domain.AssetApp;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Status;
|
||||||
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessagePayload;
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessagePayload;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -52,7 +53,9 @@ public class AssetAppRelationalRepository implements DeployerRepositoryDelegate
|
||||||
assetApp.getReleaseAt(),
|
assetApp.getReleaseAt(),
|
||||||
assetApp.getUpdatedAt(),
|
assetApp.getUpdatedAt(),
|
||||||
assetApp.getPid(),
|
assetApp.getPid(),
|
||||||
assetApp.getStatus()
|
assetApp.getStatus().succeed(),
|
||||||
|
assetApp.getStatus().statusCode(),
|
||||||
|
assetApp.getStatus().errMsg()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +67,7 @@ public class AssetAppRelationalRepository implements DeployerRepositoryDelegate
|
||||||
.pid(entity.getPid())
|
.pid(entity.getPid())
|
||||||
.releasedAt(entity.getReleasedAt())
|
.releasedAt(entity.getReleasedAt())
|
||||||
.updatedAt(entity.getUpdatedAt())
|
.updatedAt(entity.getUpdatedAt())
|
||||||
.status(entity.getStatus())
|
.status(new Status(entity.getSucceed(), entity.getStatusCode(), entity.getErrorMessage()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,6 @@ public class DeployRequestEntity {
|
||||||
@Column(name = "operation_type", length = 255)
|
@Column(name = "operation_type", length = 255)
|
||||||
private OperationType operationType;
|
private OperationType operationType;
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@Column(name = "device_type", length = 255)
|
|
||||||
private DeviceType deviceType;
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Column(name = "command_type", length = 255)
|
@Column(name = "command_type", length = 255)
|
||||||
private CommandType commandType;
|
private CommandType commandType;
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
|
@ -33,12 +30,11 @@ public class DeployRequestEntity {
|
||||||
|
|
||||||
protected DeployRequestEntity() {}
|
protected DeployRequestEntity() {}
|
||||||
|
|
||||||
public DeployRequestEntity(String requestId, String assetCode, String appName, OperationType operationType, DeviceType deviceType, CommandType commandType, SubCommandType subCommandType) {
|
public DeployRequestEntity(String requestId, String assetCode, String appName, OperationType operationType, CommandType commandType, SubCommandType subCommandType) {
|
||||||
this.requestId = requestId;
|
this.requestId = requestId;
|
||||||
this.assetCode = assetCode;
|
this.assetCode = assetCode;
|
||||||
this.appName = appName;
|
this.appName = appName;
|
||||||
this.operationType = operationType;
|
this.operationType = operationType;
|
||||||
this.deviceType = deviceType;
|
|
||||||
this.commandType = commandType;
|
this.commandType = commandType;
|
||||||
this.subCommandType = subCommandType;
|
this.subCommandType = subCommandType;
|
||||||
}
|
}
|
||||||
|
@ -63,10 +59,6 @@ public class DeployRequestEntity {
|
||||||
return operationType;
|
return operationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceType getDeviceType() {
|
|
||||||
return deviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandType getCommandType() {
|
public CommandType getCommandType() {
|
||||||
return commandType;
|
return commandType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ public class DeployRequestRelationalRepository implements DeployRequestRepositor
|
||||||
deployRequest.getAssetCode(),
|
deployRequest.getAssetCode(),
|
||||||
deployRequest.getAppName(),
|
deployRequest.getAppName(),
|
||||||
deployRequest.getOperationType(),
|
deployRequest.getOperationType(),
|
||||||
deployRequest.getDeviceType(),
|
|
||||||
deployRequest.getCommandType(),
|
deployRequest.getCommandType(),
|
||||||
deployRequest.getSubCommandType()
|
deployRequest.getSubCommandType()
|
||||||
);
|
);
|
||||||
|
@ -52,7 +51,6 @@ public class DeployRequestRelationalRepository implements DeployRequestRepositor
|
||||||
.assetCode(entity.getAssetCode())
|
.assetCode(entity.getAssetCode())
|
||||||
.appName(entity.getAppName())
|
.appName(entity.getAppName())
|
||||||
.operationType(entity.getOperationType())
|
.operationType(entity.getOperationType())
|
||||||
.deviceType(entity.getDeviceType())
|
|
||||||
.commandType(entity.getCommandType())
|
.commandType(entity.getCommandType())
|
||||||
.subCommandType(entity.getSubCommandType())
|
.subCommandType(entity.getSubCommandType())
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.presentation;
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.application.CommandInvoker;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.application.DeployCommandInvoker;
|
||||||
import inc.sdt.blokworks.devicedeployer.application.DeployerService;
|
import inc.sdt.blokworks.devicedeployer.application.DeployerService;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.*;
|
import inc.sdt.blokworks.devicedeployer.domain.*;
|
||||||
import inc.sdt.blokworks.devicedeployer.infrastructure.amqp.ResourceMapping;
|
import inc.sdt.blokworks.devicedeployer.infrastructure.amqp.ResourceMapping;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.presentation.exception.NotFoundException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -11,8 +15,11 @@ import org.springframework.data.domain.Page;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class DeployerController {
|
public class DeployerController {
|
||||||
|
@ -20,14 +27,20 @@ public class DeployerController {
|
||||||
private final DeployerService deployerService;
|
private final DeployerService deployerService;
|
||||||
private final OutboundMessageResourceConverter outboundMessageResourceConverter;
|
private final OutboundMessageResourceConverter outboundMessageResourceConverter;
|
||||||
private final AssetAppResourceConverter assetAppResourceConverter;
|
private final AssetAppResourceConverter assetAppResourceConverter;
|
||||||
|
private final CommandInvoker commandInvoker;
|
||||||
|
private final GiteaApiRequestHandler giteaApiRequestHandler;
|
||||||
|
|
||||||
public DeployerController(DeployerService deployerService,
|
public DeployerController(DeployerService deployerService,
|
||||||
OutboundMessageResourceConverter outboundMessageResourceConverter,
|
OutboundMessageResourceConverter outboundMessageResourceConverter,
|
||||||
AssetAppResourceConverter assetAppResourceConverter) {
|
AssetAppResourceConverter assetAppResourceConverter,
|
||||||
|
CommandInvoker commandInvoker,
|
||||||
|
GiteaApiRequestHandler giteaApiRequestHandler) {
|
||||||
this.log = LoggerFactory.getLogger(this.getClass());
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
this.deployerService = deployerService;
|
this.deployerService = deployerService;
|
||||||
this.outboundMessageResourceConverter = outboundMessageResourceConverter;
|
this.outboundMessageResourceConverter = outboundMessageResourceConverter;
|
||||||
this.assetAppResourceConverter = assetAppResourceConverter;
|
this.assetAppResourceConverter = assetAppResourceConverter;
|
||||||
|
this.commandInvoker = commandInvoker;
|
||||||
|
this.giteaApiRequestHandler = giteaApiRequestHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,24 +52,36 @@ public class DeployerController {
|
||||||
@ResponseStatus(HttpStatus.CREATED)
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
@PostMapping("/assets/{assetCode}/apps")
|
@PostMapping("/assets/{assetCode}/apps")
|
||||||
public void deploy(@PathVariable String assetCode,
|
public void deploy(@PathVariable String assetCode,
|
||||||
@RequestBody OutboundMessageResource resource) {
|
@RequestBody OutboundMessageResource resource,
|
||||||
|
HttpServletRequest httpServletRequest) {
|
||||||
log.info("[deploy] assetCode = {}, resource = {}", assetCode, resource);
|
log.info("[deploy] assetCode = {}, resource = {}", assetCode, resource);
|
||||||
|
String authorization = httpServletRequest.getHeader("Authorization");
|
||||||
String requestId = UUID.randomUUID().toString();
|
String requestId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
OutboundMessage outboundMessage = outboundMessageResourceConverter.fromResource(resource);
|
OutboundMessage outboundMessage = outboundMessageResourceConverter.fromResource(resource);
|
||||||
outboundMessage.setRequestId(requestId);
|
outboundMessage.setRequestId(requestId);
|
||||||
|
outboundMessage.setAssetCode(assetCode);
|
||||||
|
outboundMessage.setCommandInfo(commandInvoker.invoke(outboundMessage));
|
||||||
|
|
||||||
|
if(resource.commandType() == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(resource.commandType() == CommandType.deploy) {
|
||||||
|
giteaApiRequestHandler.get(authorization, outboundMessage);
|
||||||
|
}
|
||||||
|
|
||||||
DeployRequest deployRequest = DeployRequest.builder()
|
DeployRequest deployRequest = DeployRequest.builder()
|
||||||
.requestId(requestId)
|
.requestId(requestId)
|
||||||
.assetCode(assetCode)
|
.assetCode(assetCode)
|
||||||
.appName(outboundMessage.getName())
|
.appName(outboundMessage.getName())
|
||||||
.operationType(OperationType.DEPLOY)
|
.operationType(OperationType.DEPLOY)
|
||||||
.deviceType(resource.deviceType())
|
|
||||||
.commandType(resource.commandType())
|
.commandType(resource.commandType())
|
||||||
.subCommandType(resource.subCommandType())
|
.subCommandType(resource.subCommandType())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
DeployRequest request = deployerService.save(deployRequest);
|
deployerService.save(deployRequest);
|
||||||
deployerService.publish(outboundMessage, assetCode);
|
deployerService.publish(outboundMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.SubCommandType;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.presentation.exception.NotFoundException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class GiteaApiRequestHandler {
|
||||||
|
private final Logger log;
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
private final String url;
|
||||||
|
private final List<String> extensions;
|
||||||
|
|
||||||
|
public GiteaApiRequestHandler(RestTemplate restTemplate,
|
||||||
|
@Value("${stackbase.api.host}") String url) {
|
||||||
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
this.restTemplate = restTemplate;
|
||||||
|
this.url = url;
|
||||||
|
this.extensions = Arrays.asList(".py", ".jar", ".sh", ".service", ".json", ".yaml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void get(String authorization, OutboundMessage message) {
|
||||||
|
log.info("[get] message = {}", message);
|
||||||
|
if(message.getSubCommandType() == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.getSubCommandType() == SubCommandType.systemd) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set("Authorization", authorization);
|
||||||
|
|
||||||
|
try {
|
||||||
|
download(message.getAssetCode(), message.getUrl());
|
||||||
|
}catch (IOException e) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void download(String assetCode, String url) throws IOException {
|
||||||
|
log.info("[download] assetCode = {}, url = {}", assetCode, url);
|
||||||
|
byte[] bytes = restTemplate.getForObject(url, byte[].class);
|
||||||
|
|
||||||
|
File tempFile = File.createTempFile(assetCode+"_"+LocalDateTime.now(), ".zip");
|
||||||
|
try(FileOutputStream fos = new FileOutputStream(tempFile)) {
|
||||||
|
assert bytes != null;
|
||||||
|
fos.write(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
try(ZipInputStream zis = new ZipInputStream(Files.newInputStream(Path.of(tempFile.getAbsolutePath())))) {
|
||||||
|
ZipEntry zipEntry;
|
||||||
|
while((zipEntry = zis.getNextEntry()) != null) {
|
||||||
|
if(!zipEntry.isDirectory()) {
|
||||||
|
String extension = zipEntry.getName().split("\\.")[1];
|
||||||
|
if(!extensions.toString().contains(extension)) {
|
||||||
|
throw new NotFoundException("Executable file not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,17 +4,17 @@ import inc.sdt.blokworks.devicedeployer.domain.CommandType;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.DeviceType;
|
import inc.sdt.blokworks.devicedeployer.domain.DeviceType;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.SubCommandType;
|
import inc.sdt.blokworks.devicedeployer.domain.SubCommandType;
|
||||||
import org.wildfly.common.annotation.NotNull;
|
import org.wildfly.common.annotation.NotNull;
|
||||||
|
import org.wildfly.common.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
record OutboundMessageResource(
|
record OutboundMessageResource(
|
||||||
String fileId,
|
String url,
|
||||||
String fileType,
|
String fileType,
|
||||||
String appName, // 사용자가 정한 파일 이름
|
String appName, // 사용자가 정한 파일 이름
|
||||||
String name, // stackbase 에 저장된 파일 이름
|
String name, // stackbase 에 저장된 파일 이름
|
||||||
String image,
|
String image,
|
||||||
String command,
|
String command,
|
||||||
DeviceType deviceType,
|
|
||||||
CommandType commandType,
|
CommandType commandType,
|
||||||
SubCommandType subCommandType,
|
SubCommandType subCommandType,
|
||||||
LinkedHashMap<String, Object> options,
|
LinkedHashMap<String, Object> options,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.presentation;
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.CommandType;
|
import inc.sdt.blokworks.devicedeployer.domain.CommandType;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.DeviceType;
|
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.SubCommandType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -11,15 +11,15 @@ import java.util.*;
|
||||||
public class OutboundMessageResourceConverter {
|
public class OutboundMessageResourceConverter {
|
||||||
public OutboundMessage fromResource(OutboundMessageResource resource) {
|
public OutboundMessage fromResource(OutboundMessageResource resource) {
|
||||||
return OutboundMessage.builder()
|
return OutboundMessage.builder()
|
||||||
.fileId(resource.fileId())
|
.url(resource.url())
|
||||||
.fileType(resource.fileType())
|
.fileType(resource.fileType())
|
||||||
.appName(resource.appName() == null ? "" : resource.appName())
|
.appName(resource.appName())
|
||||||
.name(resource.name())
|
.name(resource.name())
|
||||||
.image(resource.image() == null ? "" : resource.image())
|
.image(resource.image())
|
||||||
.command(resource.command())
|
.command(resource.command())
|
||||||
.options(resource.options() == null ? new LinkedHashMap<>() : resource.options())
|
.options(resource.options() == null ? new LinkedHashMap<>() : resource.options())
|
||||||
.deviceType(resource.deviceType() == null ? DeviceType.ecn : resource.deviceType())
|
|
||||||
.commandType(resource.commandType() == null ? CommandType.deploy : resource.commandType())
|
.commandType(resource.commandType() == null ? CommandType.deploy : resource.commandType())
|
||||||
|
.subCommandType(resource.subCommandType() == null ? SubCommandType.single : resource.subCommandType())
|
||||||
.parameters(resource.parameters() == null ? new LinkedHashMap<>() : resource.parameters())
|
.parameters(resource.parameters() == null ? new LinkedHashMap<>() : resource.parameters())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,16 @@ class ControllerAdvice {
|
||||||
public ErrorResponse handleConflictException(Exception exception) {
|
public ErrorResponse handleConflictException(Exception exception) {
|
||||||
return new ErrorResponse(HttpStatus.CONFLICT, exception.getMessage());
|
return new ErrorResponse(HttpStatus.CONFLICT, exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(NotFoundException.class)
|
||||||
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
|
public ErrorResponse handleNotFoundException(Exception exception) {
|
||||||
|
return new ErrorResponse(HttpStatus.NOT_FOUND, exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(UnauthorizedException.class)
|
||||||
|
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||||
|
public ErrorResponse handleUnauthorizedException(Exception exception) {
|
||||||
|
return new ErrorResponse(HttpStatus.UNAUTHORIZED, exception.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation.exception;
|
||||||
|
|
||||||
|
public class NotFoundException extends RuntimeException{
|
||||||
|
private static final String DEFAULT_MESSAGE = "File not found";
|
||||||
|
public NotFoundException() {
|
||||||
|
super(DEFAULT_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation.rest;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.presentation.exception.UnauthorizedException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.HttpStatusCode;
|
||||||
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class RestTemplateResponseErrorHandler extends DefaultResponseErrorHandler {
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
public RestTemplateResponseErrorHandler() {
|
||||||
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleError(ClientHttpResponse response, HttpStatusCode statusCode) throws IOException {
|
||||||
|
log.error("[handleError] statusCode = {}, response = {}", statusCode, response);
|
||||||
|
if(response.getStatusCode() == HttpStatus.UNAUTHORIZED) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ inbound:
|
||||||
username: ${INBOUND_MQTT_CREDENTIALS_USERNAME}
|
username: ${INBOUND_MQTT_CREDENTIALS_USERNAME}
|
||||||
password: ${INBOUND_MQTT_CREDENTIALS_PASSWORD}
|
password: ${INBOUND_MQTT_CREDENTIALS_PASSWORD}
|
||||||
topics:
|
topics:
|
||||||
- /devicecontrol/result/+/+/+
|
- /device-control/+/result
|
||||||
|
|
||||||
iam:
|
iam:
|
||||||
enabled: ${IAM_REGISTER_ENABLED}
|
enabled: ${IAM_REGISTER_ENABLED}
|
||||||
|
|
|
@ -17,7 +17,7 @@ inbound:
|
||||||
username: sdt
|
username: sdt
|
||||||
password: 251327
|
password: 251327
|
||||||
topics:
|
topics:
|
||||||
- /devicecontrol/result/+/+/+
|
- /device-control/+/result
|
||||||
|
|
||||||
stackbase:
|
stackbase:
|
||||||
api:
|
api:
|
||||||
|
|
Loading…
Reference in New Issue