feat: 배포된 App 정보 조회
- 장비의 App 목록 조회 - 장비의 Process 목록 조회 Closed: #SCDD-197
This commit is contained in:
parent
59cb705c10
commit
9470a02ccb
|
@ -23,6 +23,7 @@ dependencies {
|
||||||
implementation("org.springframework.boot:spring-boot-starter-undertow")
|
implementation("org.springframework.boot:spring-boot-starter-undertow")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-amqp")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
implementation("org.springframework.integration:spring-integration-mqtt")
|
implementation("org.springframework.integration:spring-integration-mqtt")
|
||||||
runtimeOnly("org.postgresql:postgresql")
|
runtimeOnly("org.postgresql:postgresql")
|
||||||
|
|
|
@ -7,6 +7,8 @@ import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.OperationType;
|
import inc.sdt.blokworks.devicedeployer.domain.OperationType;
|
||||||
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.exception.ConflictException;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
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;
|
||||||
|
@ -22,6 +24,7 @@ public class DefaultDeployerService implements DeployerService{
|
||||||
private final IMqttClient mqttClient;
|
private final IMqttClient mqttClient;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
private final DeployerRepositoryDelegate deployerRepositoryDelegate;
|
private final DeployerRepositoryDelegate deployerRepositoryDelegate;
|
||||||
|
private String requestId;
|
||||||
|
|
||||||
public DefaultDeployerService(IMqttClient mqttClient,
|
public DefaultDeployerService(IMqttClient mqttClient,
|
||||||
ObjectMapper objectMapper,
|
ObjectMapper objectMapper,
|
||||||
|
@ -50,35 +53,31 @@ public class DefaultDeployerService implements DeployerService{
|
||||||
message.setPayload(bytes);
|
message.setPayload(bytes);
|
||||||
|
|
||||||
mqttClient.publish("/assets/"+assetCode+"/apps/deploy", message);
|
mqttClient.publish("/assets/"+assetCode+"/apps/deploy", message);
|
||||||
|
requestId = deployMessage.getRequestId();
|
||||||
|
log.info("[publish] message = {}", message);
|
||||||
}catch (JsonProcessingException | MqttException e) {
|
}catch (JsonProcessingException | MqttException e) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> apply(InboundDeployMessagePayload inboundDeployMessagePayload) {
|
public Mono<Void> apply(InboundDeployMessagePayload payload) {
|
||||||
log.info("[apply] inboundDeployMessagePayload = {}", inboundDeployMessagePayload);
|
log.info("[apply] inboundDeployMessagePayload = {}", payload);
|
||||||
// 배포된 앱 정보 저장
|
// 배포된 앱 정보 저장
|
||||||
// request Id 판별
|
// request Id 판별
|
||||||
|
if(requestId.equals(payload.requestId())) {
|
||||||
AssetApp assetApp = deployerRepositoryDelegate.save(fromMessage(inboundDeployMessagePayload));
|
return Mono.just(payload)
|
||||||
return null;
|
.doOnNext(deployerRepositoryDelegate)
|
||||||
|
.then();
|
||||||
|
}else {
|
||||||
|
throw new ConflictException("This process is already exists.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<AssetApp> getAll(String assetCode, int page, int size) {
|
public Page<AssetApp> getAll(String assetCode, int page, int size) {
|
||||||
log.debug("[getAll] assetCode = {}, page = {}, size = {}", assetCode, page, size);
|
log.info("[getAll] assetCode = {}, page = {}, size = {}", assetCode, page, size);
|
||||||
return deployerRepositoryDelegate.findAllByAssetCode(assetCode, page, size);
|
return deployerRepositoryDelegate.findAllByAssetCode(assetCode, page, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AssetApp fromMessage(InboundDeployMessagePayload payload) {
|
|
||||||
return AssetApp.builder()
|
|
||||||
.assetCode(payload.assetCode())
|
|
||||||
.name(payload.name())
|
|
||||||
.size(payload.size())
|
|
||||||
.releasedAt(payload.releasedAt())
|
|
||||||
.modifiedAt(payload.modifiedAt())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,37 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.application;
|
package inc.sdt.blokworks.devicedeployer.application;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Process;
|
||||||
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundProcessMessagePayload;
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundProcessMessagePayload;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
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;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class DefaultProcessService implements ProcessService{
|
public class DefaultProcessService implements ProcessService{
|
||||||
|
private final Logger log;
|
||||||
|
private final ProcessRepositoryDelegate processRepositoryDelegate;
|
||||||
|
|
||||||
|
public DefaultProcessService(ProcessRepositoryDelegate processRepositoryDelegate) {
|
||||||
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
this.processRepositoryDelegate = processRepositoryDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> apply(InboundProcessMessagePayload inboundProcessMessagePayload) {
|
public Mono<Void> apply(InboundProcessMessagePayload inboundProcessMessagePayload) {
|
||||||
return null;
|
log.info("[apply] inboundProcessMessagePayload = {}", inboundProcessMessagePayload);
|
||||||
|
// 프로세스 저장
|
||||||
|
return Mono.just(inboundProcessMessagePayload)
|
||||||
|
.doOnNext(processRepositoryDelegate)
|
||||||
|
.then();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<Process> getAll(String assetCode, int page, int size) {
|
||||||
|
log.info("[getAll] assetCode = {}, page = {}, size = {}", assetCode, page, size);
|
||||||
|
return processRepositoryDelegate.findAllByAssetCode(assetCode, page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.application;
|
package inc.sdt.blokworks.devicedeployer.application;
|
||||||
|
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.AssetApp;
|
import inc.sdt.blokworks.devicedeployer.domain.AssetApp;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessagePayload;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
public interface DeployerRepositoryDelegate {
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public interface DeployerRepositoryDelegate extends Consumer<InboundDeployMessagePayload> {
|
||||||
AssetApp save(AssetApp assetApp);
|
AssetApp save(AssetApp assetApp);
|
||||||
Page<AssetApp> findAllByAssetCode(String assetCode, int page, int size);
|
Page<AssetApp> findAllByAssetCode(String assetCode, int page, int size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.application;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Process;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundProcessMessagePayload;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public interface ProcessRepositoryDelegate extends Consumer<InboundProcessMessagePayload> {
|
||||||
|
Process save(Process process);
|
||||||
|
Page<Process> findAllByAssetCode(String assetCode, int page, int size);
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.application;
|
package inc.sdt.blokworks.devicedeployer.application;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Process;
|
||||||
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundProcessMessagePayload;
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundProcessMessagePayload;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface ProcessService extends Function<InboundProcessMessagePayload, Mono<Void>> {
|
public interface ProcessService extends Function<InboundProcessMessagePayload, Mono<Void>> {
|
||||||
|
Page<Process> getAll(String assetCode, int page, int size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,16 @@ public class AssetApp {
|
||||||
private String name;
|
private String name;
|
||||||
private Long size;
|
private Long size;
|
||||||
private Long releaseAt;
|
private Long releaseAt;
|
||||||
private Long modifiedAt;
|
private Long updatedAt;
|
||||||
|
|
||||||
protected AssetApp() {}
|
protected AssetApp() {}
|
||||||
|
|
||||||
public AssetApp(String assetCode, String name, Long size, Long releaseAt, Long modifiedAt) {
|
public AssetApp(String assetCode, String name, Long size, Long releaseAt, Long updatedAt) {
|
||||||
this.assetCode = assetCode;
|
this.assetCode = assetCode;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.releaseAt = releaseAt;
|
this.releaseAt = releaseAt;
|
||||||
this.modifiedAt = modifiedAt;
|
this.updatedAt = updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAssetCode() {
|
public String getAssetCode() {
|
||||||
|
@ -33,8 +33,19 @@ public class AssetApp {
|
||||||
return releaseAt;
|
return releaseAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getModifiedAt() {
|
public Long getUpdatedAt() {
|
||||||
return modifiedAt;
|
return updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AssetApp{" +
|
||||||
|
"assetCode='" + assetCode + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", size=" + size +
|
||||||
|
", releaseAt=" + releaseAt +
|
||||||
|
", updatedAt=" + updatedAt +
|
||||||
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
@ -46,7 +57,7 @@ public class AssetApp {
|
||||||
private String name;
|
private String name;
|
||||||
private Long size;
|
private Long size;
|
||||||
private Long releasedAt;
|
private Long releasedAt;
|
||||||
private Long modifiedAt;
|
private Long updatedAt;
|
||||||
|
|
||||||
public Builder assetCode(String assetCode) {
|
public Builder assetCode(String assetCode) {
|
||||||
this.assetCode = assetCode;
|
this.assetCode = assetCode;
|
||||||
|
@ -68,8 +79,8 @@ public class AssetApp {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder modifiedAt(Long modifiedAt) {
|
public Builder updatedAt(Long updatedAt) {
|
||||||
this.modifiedAt = modifiedAt;
|
this.updatedAt = updatedAt;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +90,7 @@ public class AssetApp {
|
||||||
assetApp.name = this.name;
|
assetApp.name = this.name;
|
||||||
assetApp.size = this.size;
|
assetApp.size = this.size;
|
||||||
assetApp.releaseAt = this.releasedAt;
|
assetApp.releaseAt = this.releasedAt;
|
||||||
assetApp.modifiedAt = this.modifiedAt;
|
assetApp.updatedAt = this.updatedAt;
|
||||||
return assetApp;
|
return assetApp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.domain;
|
||||||
|
|
||||||
|
public class Process {
|
||||||
|
private String assetCode;
|
||||||
|
private Integer pid;
|
||||||
|
private String name;
|
||||||
|
private Integer cpu;
|
||||||
|
private Integer memory;
|
||||||
|
private Integer network;
|
||||||
|
private Long processedAt;
|
||||||
|
private OperationType operationType;
|
||||||
|
|
||||||
|
protected Process() {}
|
||||||
|
|
||||||
|
public Process(String assetCode, Integer pid, String name, Integer cpu, Integer memory, Integer network, Long processedAt, OperationType operationType) {
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
this.pid = pid;
|
||||||
|
this.name = name;
|
||||||
|
this.cpu = cpu;
|
||||||
|
this.memory = memory;
|
||||||
|
this.network = network;
|
||||||
|
this.processedAt = processedAt;
|
||||||
|
this.operationType = operationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssetCode() {
|
||||||
|
return assetCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPid() {
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCpu() {
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMemory() {
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getNetwork() {
|
||||||
|
return network;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getProcessedAt() {
|
||||||
|
return processedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperationType getOperationType() {
|
||||||
|
return operationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Process{" +
|
||||||
|
"assetCode='" + assetCode + '\'' +
|
||||||
|
", pid=" + pid +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", cpu=" + cpu +
|
||||||
|
", memory=" + memory +
|
||||||
|
", network=" + network +
|
||||||
|
", processedAt=" + processedAt +
|
||||||
|
", operationType=" + operationType +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder {
|
||||||
|
private String assetCode;
|
||||||
|
private Integer pid;
|
||||||
|
private String name;
|
||||||
|
private Integer cpu;
|
||||||
|
private Integer memory;
|
||||||
|
private Integer network;
|
||||||
|
private Long processedAt;
|
||||||
|
private OperationType operationType;
|
||||||
|
|
||||||
|
public Builder assetCode(String assetCode) {
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder pid(Integer pid) {
|
||||||
|
this.pid = pid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder cpu(Integer cpu) {
|
||||||
|
this.cpu = cpu;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder memory(Integer memory) {
|
||||||
|
this.memory = memory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder network(Integer network) {
|
||||||
|
this.network = network;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder processedAt(Long processedAt) {
|
||||||
|
this.processedAt = processedAt;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder operationType(OperationType operationType) {
|
||||||
|
this.operationType = operationType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process build() {
|
||||||
|
Process process = new Process();
|
||||||
|
process.assetCode = this.assetCode;
|
||||||
|
process.pid = this.pid;
|
||||||
|
process.name = this.name;
|
||||||
|
process.cpu = this.cpu;
|
||||||
|
process.memory = this.memory;
|
||||||
|
process.network = this.network;
|
||||||
|
process.processedAt = this.processedAt;
|
||||||
|
process.operationType = this.operationType;
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.infrastructure.amqp;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "iam.amqp")
|
||||||
|
public class IamAmqpConnectionProperties {
|
||||||
|
private String host;
|
||||||
|
private Integer port;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String exchange;
|
||||||
|
private String routingKey;
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExchange() {
|
||||||
|
return exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoutingKey() {
|
||||||
|
return routingKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(Integer port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExchange(String exchange) {
|
||||||
|
this.exchange = exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoutingKey(String routingKey) {
|
||||||
|
this.routingKey = routingKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "IamAmqpConnectionProperties{" +
|
||||||
|
"host='" + host + '\'' +
|
||||||
|
", port=" + port +
|
||||||
|
", username='" + username + '\'' +
|
||||||
|
", password='" + password + '\'' +
|
||||||
|
", exchange='" + exchange + '\'' +
|
||||||
|
", routingKey='" + routingKey + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.infrastructure.amqp;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.method.HandlerMethod;
|
||||||
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ConditionalOnProperty(prefix = "iam", name = "enabled", havingValue = "true")
|
||||||
|
@Component
|
||||||
|
class RegisterResourceMappingDelegate {
|
||||||
|
private final String applicationName;
|
||||||
|
private final RegisterResourceProducer registerResourceProducer;
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
RegisterResourceMappingDelegate(@Value("${spring.application.name}") String applicationName,
|
||||||
|
RegisterResourceProducer registerResourceProducer) {
|
||||||
|
this.log = LoggerFactory.getLogger(RegisterResourceMappingDelegate.class);
|
||||||
|
log.info("[Constructor] applicationName={}", applicationName);
|
||||||
|
this.registerResourceProducer = registerResourceProducer;
|
||||||
|
this.applicationName = applicationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener
|
||||||
|
public void handleContextRefreshedEvent(ContextRefreshedEvent event) {
|
||||||
|
log.info("[handleContextRefreshedEvent] event = {}", event);
|
||||||
|
ApplicationContext applicationContext = event.getApplicationContext();
|
||||||
|
RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
|
||||||
|
Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
|
||||||
|
|
||||||
|
map.values().stream()
|
||||||
|
.filter(value -> Objects.nonNull(value.getMethod().getDeclaredAnnotation(ResourceMapping.class)))
|
||||||
|
.map(value -> value.getMethod().getDeclaredAnnotation(ResourceMapping.class))
|
||||||
|
.map(annotation -> new ResourceMessagePayload(annotation.name(), annotation.method(), annotation.uri(), applicationName, annotation.description()))
|
||||||
|
.forEach(registerResourceProducer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.infrastructure.amqp;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
import org.springframework.amqp.core.MessageProperties;
|
||||||
|
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
|
import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@ConditionalOnProperty(prefix = "iam", name = "enabled", havingValue = "true")
|
||||||
|
@EnableConfigurationProperties({IamAmqpConnectionProperties.class})
|
||||||
|
@Component
|
||||||
|
class RegisterResourceProducer implements Consumer<ResourceMessagePayload> {
|
||||||
|
private final RabbitTemplate rabbitTemplate;
|
||||||
|
private final MessageConverter messageConverter;
|
||||||
|
private final MessageProperties messageProperties;
|
||||||
|
private final String exchange;
|
||||||
|
private final String routingKey;
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
RegisterResourceProducer(IamAmqpConnectionProperties connectionProperties) {
|
||||||
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
log.info("[Constructor] connectionProperties={}", connectionProperties);
|
||||||
|
|
||||||
|
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
|
||||||
|
connectionFactory.setHost(connectionProperties.getHost());
|
||||||
|
connectionFactory.setPort(connectionProperties.getPort());
|
||||||
|
connectionFactory.setUsername(connectionProperties.getUsername());
|
||||||
|
connectionFactory.setPassword(connectionProperties.getPassword());
|
||||||
|
|
||||||
|
this.messageConverter = new Jackson2JsonMessageConverter();
|
||||||
|
this.rabbitTemplate = new RabbitTemplate(connectionFactory);
|
||||||
|
this.rabbitTemplate.setMessageConverter(this.messageConverter);
|
||||||
|
|
||||||
|
this. exchange = connectionProperties.getExchange();
|
||||||
|
this.routingKey = connectionProperties.getRoutingKey();
|
||||||
|
|
||||||
|
this.messageProperties = new MessageProperties();
|
||||||
|
this.messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
|
||||||
|
this.messageProperties.setHeader("Command", "CREATE");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(ResourceMessagePayload payload) {
|
||||||
|
log.info("[accept] payload={}", payload);
|
||||||
|
Message message = messageConverter.toMessage(payload, messageProperties);
|
||||||
|
rabbitTemplate.send(exchange, routingKey, message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.infrastructure.amqp;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface ResourceMapping {
|
||||||
|
String name();
|
||||||
|
String method();
|
||||||
|
String uri();
|
||||||
|
String description();
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.infrastructure.amqp;
|
||||||
|
|
||||||
|
record ResourceMessagePayload(
|
||||||
|
String name,
|
||||||
|
String method,
|
||||||
|
String uri,
|
||||||
|
String applicationName,
|
||||||
|
String description
|
||||||
|
) {
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ public record InboundDeployMessagePayload(
|
||||||
String name,
|
String name,
|
||||||
Long size,
|
Long size,
|
||||||
Long releasedAt,
|
Long releasedAt,
|
||||||
Long modifiedAt,
|
Long updatedAt,
|
||||||
String requestId
|
String requestId
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,17 @@ class AssetAppEntity {
|
||||||
private Long size;
|
private Long size;
|
||||||
@Column(name = "released_at")
|
@Column(name = "released_at")
|
||||||
private Long releasedAt;
|
private Long releasedAt;
|
||||||
@Column(name = "modfied_at")
|
@Column(name = "updated_at")
|
||||||
private Long modifiedAt;
|
private Long updatedAt;
|
||||||
|
|
||||||
protected AssetAppEntity() {}
|
protected AssetAppEntity() {}
|
||||||
|
|
||||||
public AssetAppEntity(String assetCode, String name, long size, Long releasedAt, Long modifiedAt) {
|
public AssetAppEntity(String assetCode, String name, long size, Long releasedAt, Long updatedAt) {
|
||||||
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.modifiedAt = modifiedAt;
|
this.updatedAt = updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -51,8 +51,8 @@ class AssetAppEntity {
|
||||||
return releasedAt;
|
return releasedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getModifiedAt() {
|
public Long getUpdatedAt() {
|
||||||
return modifiedAt;
|
return updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.infrastructure.mqtt.InboundDeployMessagePayload;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
@ -20,9 +21,15 @@ public class AssetAppRelationalRepository implements DeployerRepositoryDelegate
|
||||||
this.assetAppJpaRepository = assetAppJpaRepository;
|
this.assetAppJpaRepository = assetAppJpaRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(InboundDeployMessagePayload inboundDeployMessagePayload) {
|
||||||
|
this.save(this.fromMessage(inboundDeployMessagePayload));
|
||||||
|
}
|
||||||
|
|
||||||
// 앱 정보 저장
|
// 앱 정보 저장
|
||||||
@Override
|
@Override
|
||||||
public AssetApp save(AssetApp assetApp) {
|
public AssetApp save(AssetApp assetApp) {
|
||||||
|
log.info("[save] assetApp = {}", assetApp);
|
||||||
AssetAppEntity entity = this.toEntity(assetApp);
|
AssetAppEntity entity = this.toEntity(assetApp);
|
||||||
assetAppJpaRepository.save(entity);
|
assetAppJpaRepository.save(entity);
|
||||||
return assetApp;
|
return assetApp;
|
||||||
|
@ -30,7 +37,7 @@ public class AssetAppRelationalRepository implements DeployerRepositoryDelegate
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<AssetApp> findAllByAssetCode(String assetCode, int page, int size) {
|
public Page<AssetApp> findAllByAssetCode(String assetCode, int page, int size) {
|
||||||
log.debug("[findAllByAssetCode] assetCode = {}", assetCode);
|
log.info("[findAllByAssetCode] assetCode = {}", assetCode);
|
||||||
Pageable pageable = page < 0 ? Pageable.unpaged() : PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "releasedAt"));
|
Pageable pageable = page < 0 ? Pageable.unpaged() : PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "releasedAt"));
|
||||||
return assetAppJpaRepository.findAllByAssetCode(assetCode, pageable)
|
return assetAppJpaRepository.findAllByAssetCode(assetCode, pageable)
|
||||||
.map(this::fromEntity);
|
.map(this::fromEntity);
|
||||||
|
@ -42,7 +49,7 @@ public class AssetAppRelationalRepository implements DeployerRepositoryDelegate
|
||||||
assetApp.getName(),
|
assetApp.getName(),
|
||||||
assetApp.getSize(),
|
assetApp.getSize(),
|
||||||
assetApp.getReleaseAt(),
|
assetApp.getReleaseAt(),
|
||||||
assetApp.getModifiedAt()
|
assetApp.getUpdatedAt()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +59,17 @@ public class AssetAppRelationalRepository implements DeployerRepositoryDelegate
|
||||||
.name(entity.getName())
|
.name(entity.getName())
|
||||||
.size(entity.getSize())
|
.size(entity.getSize())
|
||||||
.releasedAt(entity.getReleasedAt())
|
.releasedAt(entity.getReleasedAt())
|
||||||
.modifiedAt(entity.getModifiedAt())
|
.updatedAt(entity.getUpdatedAt())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AssetApp fromMessage(InboundDeployMessagePayload payload) {
|
||||||
|
return AssetApp.builder()
|
||||||
|
.assetCode(payload.assetCode())
|
||||||
|
.name(payload.name())
|
||||||
|
.size(payload.size())
|
||||||
|
.releasedAt(payload.releasedAt())
|
||||||
|
.updatedAt(payload.updatedAt())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,44 +3,42 @@ package inc.sdt.blokworks.devicedeployer.infrastructure.relational;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
@Entity(name = "app_process")
|
@Entity(name = "app_process")
|
||||||
class AppProcessEntity {
|
class ProcessEntity {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.UUID)
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
@Column(name = "id")
|
@Column(name = "process_id", length = 36)
|
||||||
private String id;
|
private String id;
|
||||||
@Column(name = "app_id", length = 36)
|
|
||||||
private String appId;
|
|
||||||
@Column(name = "asset_code", length = 255)
|
@Column(name = "asset_code", length = 255)
|
||||||
private String assetCode;
|
private String assetCode;
|
||||||
@Column(name = "pid")
|
@Column(name = "pid")
|
||||||
private Integer pid;
|
private Integer pid;
|
||||||
|
@Column(name = "app_name", length = 255)
|
||||||
|
private String appName;
|
||||||
@Column(name = "cpu")
|
@Column(name = "cpu")
|
||||||
private Integer cpu;
|
private Integer cpu;
|
||||||
@Column(name = "memory")
|
@Column(name = "memory")
|
||||||
private Integer memory;
|
private Integer memory;
|
||||||
@Column(name = "network")
|
@Column(name = "network")
|
||||||
private Integer network;
|
private Integer network;
|
||||||
|
@Column(name = "processed_at")
|
||||||
|
private Long processedAt;
|
||||||
|
|
||||||
protected AppProcessEntity() {}
|
protected ProcessEntity() {}
|
||||||
|
|
||||||
public AppProcessEntity(String id, String appId, String assetCode, Integer pid, Integer cpu, Integer memory, Integer network) {
|
public ProcessEntity(String assetCode, Integer pid, String appName, Integer cpu, Integer memory, Integer network, Long processedAt) {
|
||||||
this.id = id;
|
|
||||||
this.appId = appId;
|
|
||||||
this.assetCode = assetCode;
|
this.assetCode = assetCode;
|
||||||
this.pid = pid;
|
this.pid = pid;
|
||||||
|
this.appName = appName;
|
||||||
this.cpu = cpu;
|
this.cpu = cpu;
|
||||||
this.memory = memory;
|
this.memory = memory;
|
||||||
this.network = network;
|
this.network = network;
|
||||||
|
this.processedAt = processedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAppId() {
|
|
||||||
return appId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAssetCode() {
|
public String getAssetCode() {
|
||||||
return assetCode;
|
return assetCode;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +47,10 @@ class AppProcessEntity {
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAppName() {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getCpu() {
|
public Integer getCpu() {
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
@ -60,4 +62,8 @@ class AppProcessEntity {
|
||||||
public Integer getNetwork() {
|
public Integer getNetwork() {
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getProcessedAt() {
|
||||||
|
return processedAt;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.infrastructure.relational;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface ProcessJpaRepository extends JpaRepository<ProcessEntity, String> {
|
||||||
|
Page<ProcessEntity> findAllByAssetCode(String assetCode, Pageable pageable);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.infrastructure.relational;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.application.ProcessRepositoryDelegate;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Process;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundProcessMessagePayload;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ProcessRelationalRepository implements ProcessRepositoryDelegate {
|
||||||
|
private final Logger log;
|
||||||
|
private final ProcessJpaRepository processJpaRepository;
|
||||||
|
|
||||||
|
public ProcessRelationalRepository(ProcessJpaRepository processJpaRepository) {
|
||||||
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
this.processJpaRepository = processJpaRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(InboundProcessMessagePayload payload) {
|
||||||
|
this.save(this.fromMessage(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Process save(Process process) {
|
||||||
|
log.info("[save] process = {}", process);
|
||||||
|
ProcessEntity entity = this.toEntity(process);
|
||||||
|
processJpaRepository.save(entity);
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<Process> findAllByAssetCode(String assetCode, int page, int size) {
|
||||||
|
log.info("[findAllByAssetCode] assetCode = {}", assetCode);
|
||||||
|
Pageable pageable = page < 0 ? Pageable.unpaged() : PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "processedAt"));
|
||||||
|
return processJpaRepository.findAllByAssetCode(assetCode, pageable)
|
||||||
|
.map(this::fromEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProcessEntity toEntity(Process process) {
|
||||||
|
return new ProcessEntity(
|
||||||
|
process.getAssetCode(),
|
||||||
|
process.getPid(),
|
||||||
|
process.getName(),
|
||||||
|
process.getCpu(),
|
||||||
|
process.getMemory(),
|
||||||
|
process.getNetwork(),
|
||||||
|
process.getProcessedAt()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Process fromEntity(ProcessEntity entity) {
|
||||||
|
return Process.builder()
|
||||||
|
.assetCode(entity.getAssetCode())
|
||||||
|
.pid(entity.getPid())
|
||||||
|
.name(entity.getAppName())
|
||||||
|
.cpu(entity.getCpu())
|
||||||
|
.memory(entity.getMemory())
|
||||||
|
.network(entity.getNetwork())
|
||||||
|
.processedAt(entity.getProcessedAt())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Process fromMessage(InboundProcessMessagePayload payload) {
|
||||||
|
return Process.builder()
|
||||||
|
.assetCode(payload.assetCode())
|
||||||
|
.pid(payload.pid())
|
||||||
|
.name(payload.name())
|
||||||
|
.cpu(payload.cpu())
|
||||||
|
.memory(payload.memory())
|
||||||
|
.network(payload.network())
|
||||||
|
.processedAt(payload.processedAt())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,6 @@ record AssetAppResource(
|
||||||
String name,
|
String name,
|
||||||
Long size,
|
Long size,
|
||||||
Long releaseAt,
|
Long releaseAt,
|
||||||
Long modifiedAt
|
Long updatedAt
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ public class AssetAppResourceConverter {
|
||||||
.name(resource.name())
|
.name(resource.name())
|
||||||
.size(resource.size())
|
.size(resource.size())
|
||||||
.releasedAt(resource.releaseAt())
|
.releasedAt(resource.releaseAt())
|
||||||
.modifiedAt(resource.modifiedAt())
|
.updatedAt(resource.updatedAt())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ public class AssetAppResourceConverter {
|
||||||
assetApp.getName(),
|
assetApp.getName(),
|
||||||
assetApp.getSize(),
|
assetApp.getSize(),
|
||||||
assetApp.getReleaseAt(),
|
assetApp.getReleaseAt(),
|
||||||
assetApp.getModifiedAt()
|
assetApp.getUpdatedAt()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.presentation;
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
import inc.sdt.blokworks.devicedeployer.application.DeployerService;
|
import inc.sdt.blokworks.devicedeployer.application.DeployerService;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.application.ProcessService;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.AssetApp;
|
import inc.sdt.blokworks.devicedeployer.domain.AssetApp;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.OperationType;
|
import inc.sdt.blokworks.devicedeployer.domain.OperationType;
|
||||||
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
import inc.sdt.blokworks.devicedeployer.domain.OutboundMessage;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Process;
|
||||||
import jakarta.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -40,9 +42,10 @@ public class DeployerController {
|
||||||
public void deploy(@PathVariable String assetCode,
|
public void deploy(@PathVariable String assetCode,
|
||||||
@Valid @RequestBody OutboundMessageResource assetAppResource) {
|
@Valid @RequestBody OutboundMessageResource assetAppResource) {
|
||||||
log.info("[deploy] assetCode = {}, assetAppResource = {}", assetCode, assetAppResource);
|
log.info("[deploy] assetCode = {}, assetAppResource = {}", assetCode, assetAppResource);
|
||||||
|
String requestId = UUID.randomUUID().toString();
|
||||||
OutboundMessage outboundMessage = outboundMessageResourceConverter.fromResource(assetAppResource);
|
OutboundMessage outboundMessage = outboundMessageResourceConverter.fromResource(assetAppResource);
|
||||||
outboundMessage.setRequestId("requestId");
|
outboundMessage.setRequestId(requestId);
|
||||||
deployerService.publish(outboundMessageResourceConverter.fromResource(assetAppResource), assetCode);
|
deployerService.publish(outboundMessage, assetCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,8 +55,8 @@ public class DeployerController {
|
||||||
@ResponseStatus(HttpStatus.OK)
|
@ResponseStatus(HttpStatus.OK)
|
||||||
@GetMapping("/assets/{assetCode}/apps")
|
@GetMapping("/assets/{assetCode}/apps")
|
||||||
public PageableResponse<AssetAppResource> get(@PathVariable String assetCode,
|
public PageableResponse<AssetAppResource> get(@PathVariable String assetCode,
|
||||||
@RequestParam(required = false, defaultValue = "0") int page,
|
@RequestParam(required = false, defaultValue = "0") int page,
|
||||||
@RequestParam(required = false, defaultValue = "20") int size) {
|
@RequestParam(required = false, defaultValue = "20") int size) {
|
||||||
log.info("[get] assetCode = {}, page = {}, size = {}", assetCode, page, size);
|
log.info("[get] assetCode = {}, page = {}, size = {}", assetCode, page, size);
|
||||||
Page<AssetApp> assetApps = deployerService.getAll(assetCode, page, size);
|
Page<AssetApp> assetApps = deployerService.getAll(assetCode, page, size);
|
||||||
return PageableResponse.from(assetApps, assetAppResourceConverter::toResource);
|
return PageableResponse.from(assetApps, assetAppResourceConverter::toResource);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package inc.sdt.blokworks.devicedeployer.presentation;
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import inc.sdt.blokworks.devicedeployer.application.DeployerService;
|
import inc.sdt.blokworks.devicedeployer.application.DeployerService;
|
||||||
import inc.sdt.blokworks.devicedeployer.application.ProcessService;
|
import inc.sdt.blokworks.devicedeployer.application.ProcessService;
|
||||||
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessagePayload;
|
import inc.sdt.blokworks.devicedeployer.infrastructure.mqtt.InboundDeployMessagePayload;
|
||||||
|
@ -17,30 +16,27 @@ public class MqttMessageHandler {
|
||||||
private final Logger log;
|
private final Logger log;
|
||||||
private final DeployerService deployerService;
|
private final DeployerService deployerService;
|
||||||
private final ProcessService processService;
|
private final ProcessService processService;
|
||||||
private final ObjectMapper objectMapper;
|
|
||||||
private final MqttMessageConverter<InboundDeployMessagePayload> deployMessagePayloadConverter;
|
private final MqttMessageConverter<InboundDeployMessagePayload> deployMessagePayloadConverter;
|
||||||
private final MqttMessageConverter<InboundProcessMessagePayload> processMessagePayloadConverter;
|
private final MqttMessageConverter<InboundProcessMessagePayload> processMessagePayloadConverter;
|
||||||
|
|
||||||
public MqttMessageHandler(DeployerService deployerService,
|
public MqttMessageHandler(DeployerService deployerService,
|
||||||
ProcessService processService,
|
ProcessService processService,
|
||||||
ObjectMapper objectMapper,
|
|
||||||
MqttMessageConverter<InboundDeployMessagePayload> deployMessagePayloadConverter,
|
MqttMessageConverter<InboundDeployMessagePayload> deployMessagePayloadConverter,
|
||||||
MqttMessageConverter<InboundProcessMessagePayload> processMessagePayloadConverter) {
|
MqttMessageConverter<InboundProcessMessagePayload> processMessagePayloadConverter) {
|
||||||
this.log = LoggerFactory.getLogger(this.getClass());
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
this.deployerService = deployerService;
|
this.deployerService = deployerService;
|
||||||
this.processService = processService;
|
this.processService = processService;
|
||||||
this.objectMapper = objectMapper;
|
|
||||||
this.deployMessagePayloadConverter = deployMessagePayloadConverter;
|
this.deployMessagePayloadConverter = deployMessagePayloadConverter;
|
||||||
this.processMessagePayloadConverter = processMessagePayloadConverter;
|
this.processMessagePayloadConverter = processMessagePayloadConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ServiceActivator(inputChannel = "mqttInboundChannel")
|
@ServiceActivator(inputChannel = "mqttInboundChannel")
|
||||||
void handleMessage(Message<String> message) {
|
void handleMessage(Message<String> message) {
|
||||||
log.debug("[handleMessage] message={}", message);
|
log.info("[handleMessage] message={}", message);
|
||||||
|
|
||||||
if(!message.getPayload().contains("pid")) {
|
if(!message.getPayload().contains("pid")) {
|
||||||
String topic = String.valueOf(message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC));
|
String topic = String.valueOf(message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC));
|
||||||
String id = topic.split("/")[1];
|
String id = topic.split("/")[4];
|
||||||
|
|
||||||
log.info("[handleMessage] topic = {}, id = {}", topic, id);
|
log.info("[handleMessage] topic = {}, id = {}", topic, id);
|
||||||
|
|
||||||
|
@ -51,7 +47,7 @@ public class MqttMessageHandler {
|
||||||
p.name(),
|
p.name(),
|
||||||
p.size(),
|
p.size(),
|
||||||
p.releasedAt(),
|
p.releasedAt(),
|
||||||
p.modifiedAt(),
|
p.updatedAt(),
|
||||||
id))
|
id))
|
||||||
.flatMap(deployerService)
|
.flatMap(deployerService)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.application.ProcessService;
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Process;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class ProcessController {
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
private final ProcessService processService;
|
||||||
|
private final ProcessResourceConverter processResourceConverter;
|
||||||
|
|
||||||
|
public ProcessController(ProcessService processService,
|
||||||
|
ProcessResourceConverter processResourceConverter) {
|
||||||
|
this.log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
this.processService = processService;
|
||||||
|
this.processResourceConverter = processResourceConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 배포된 앱 내의 프로세스 정보 조회 (페이지 조회)
|
||||||
|
* @param assetCode 자산 코드
|
||||||
|
*/
|
||||||
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
@GetMapping("/assets/{assetCode}/apps/process")
|
||||||
|
public PageableResponse<ProcessResource> get(@PathVariable String assetCode,
|
||||||
|
@RequestParam(required = false, defaultValue = "0") int page,
|
||||||
|
@RequestParam(required = false, defaultValue = "20") int size) {
|
||||||
|
log.info("[get] assetCode = {}, page = {}, size = {}", assetCode, page, size);
|
||||||
|
Page<Process> process = processService.getAll(assetCode, page, size);
|
||||||
|
return PageableResponse.from(process, processResourceConverter::toResource);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.OperationType;
|
||||||
|
|
||||||
|
record ProcessResource(
|
||||||
|
String assetCode,
|
||||||
|
Integer pid,
|
||||||
|
String name,
|
||||||
|
Integer cpu,
|
||||||
|
Integer memory,
|
||||||
|
Integer network,
|
||||||
|
Long processedAt,
|
||||||
|
OperationType operationType
|
||||||
|
) {
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation;
|
||||||
|
|
||||||
|
import inc.sdt.blokworks.devicedeployer.domain.Process;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ProcessResourceConverter {
|
||||||
|
public Process fromResource(ProcessResource resource) {
|
||||||
|
return Process.builder()
|
||||||
|
.assetCode(resource.assetCode())
|
||||||
|
.name(resource.name())
|
||||||
|
.pid(resource.pid())
|
||||||
|
.cpu(resource.cpu())
|
||||||
|
.memory(resource.memory())
|
||||||
|
.network(resource.network())
|
||||||
|
.processedAt(resource.processedAt())
|
||||||
|
.operationType(resource.operationType())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcessResource toResource(Process process) {
|
||||||
|
return new ProcessResource(
|
||||||
|
process.getAssetCode(),
|
||||||
|
process.getPid(),
|
||||||
|
process.getName(),
|
||||||
|
process.getCpu(),
|
||||||
|
process.getMemory(),
|
||||||
|
process.getNetwork(),
|
||||||
|
process.getProcessedAt(),
|
||||||
|
process.getOperationType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
|
||||||
import org.springframework.messaging.MessageChannel;
|
import org.springframework.messaging.MessageChannel;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(MqttConfigurationProperties.class)
|
@EnableConfigurationProperties({MqttConfigurationProperties.class})
|
||||||
public class MqttConfiguration {
|
public class MqttConfiguration {
|
||||||
@Bean(name = "mqttInboundChannel")
|
@Bean(name = "mqttInboundChannel")
|
||||||
MessageChannel mqttMessageChannel() {
|
MessageChannel mqttMessageChannel() {
|
||||||
|
@ -20,7 +20,7 @@ public class MqttConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
MessageProducer messageChannel(MessageChannel mqttMessageChannel,
|
MessageProducer inboundChannel(MessageChannel mqttInboundChannel,
|
||||||
MqttConfigurationProperties mqttConfigurationProperties) {
|
MqttConfigurationProperties mqttConfigurationProperties) {
|
||||||
MqttConnectOptions options = new MqttConnectOptions();
|
MqttConnectOptions options = new MqttConnectOptions();
|
||||||
options.setUserName(mqttConfigurationProperties.getUsername());
|
options.setUserName(mqttConfigurationProperties.getUsername());
|
||||||
|
@ -39,7 +39,7 @@ public class MqttConfiguration {
|
||||||
adapter.setConverter(new DefaultPahoMessageConverter());
|
adapter.setConverter(new DefaultPahoMessageConverter());
|
||||||
adapter.setQos(1);
|
adapter.setQos(1);
|
||||||
adapter.addTopic(mqttConfigurationProperties.getTopics());
|
adapter.addTopic(mqttConfigurationProperties.getTopics());
|
||||||
adapter.setOutputChannel(mqttMessageChannel);
|
adapter.setOutputChannel(mqttInboundChannel);
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation.exception;
|
||||||
|
|
||||||
|
public class ConflictException extends RuntimeException{
|
||||||
|
private static final String DEFAULT_MESSAGE = "Already exists";
|
||||||
|
|
||||||
|
public ConflictException() {
|
||||||
|
super(DEFAULT_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConflictException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation.exception;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
@RestControllerAdvice
|
||||||
|
class ControllerAdvice {
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
ControllerAdvice() {
|
||||||
|
this.log = LoggerFactory.getLogger(ControllerAdvice.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(NoContentException.class)
|
||||||
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
|
public void handleNoContentException(Exception exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(IllegalArgumentException.class)
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public ErrorResponse handleIllegalArgumentException(IllegalArgumentException exception) {
|
||||||
|
return new ErrorResponse(HttpStatus.BAD_REQUEST, exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(ConflictException.class)
|
||||||
|
@ResponseStatus(HttpStatus.CONFLICT)
|
||||||
|
public ErrorResponse handleConflictException(Exception exception) {
|
||||||
|
return new ErrorResponse(HttpStatus.CONFLICT, exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation.exception;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
import java.time.Clock;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
|
class ErrorResponse {
|
||||||
|
private final int code;
|
||||||
|
private final String error;
|
||||||
|
private final String message;
|
||||||
|
private final Long timestamp;
|
||||||
|
|
||||||
|
public ErrorResponse(HttpStatus code, String message) {
|
||||||
|
this.code = code.value();
|
||||||
|
this.error = code.getReasonPhrase();
|
||||||
|
this.message = message;
|
||||||
|
this.timestamp = Instant.now(Clock.system(ZoneOffset.UTC)).toEpochMilli();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package inc.sdt.blokworks.devicedeployer.presentation.exception;
|
||||||
|
|
||||||
|
public class NoContentException extends RuntimeException{
|
||||||
|
private static final String DEFAULT_MESSAGE = "No Content";
|
||||||
|
public NoContentException() {
|
||||||
|
super(DEFAULT_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoContentException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
iam:
|
||||||
|
enabled: ${IAM_REGISTER_ENABLED}
|
||||||
|
amqp:
|
||||||
|
host: ${IAM_AMQP_HOST}
|
||||||
|
port: ${IAM_AMQP_PORT}
|
||||||
|
username: ${IAM_AMQP_CREDENTIALS_USERNAME}
|
||||||
|
password: ${IAM_AMQP_CREDENTIALS_PASSWORD}
|
||||||
|
exchange: ${IAM_AMQP_EXCHANGE}
|
||||||
|
routing-key: ${IAM_AMQP_ROUTING_KEY}
|
Loading…
Reference in New Issue