Tube On/Off 제어 기능 개발
This commit is contained in:
parent
0998142c2c
commit
8cc8097f33
14
build.gradle
14
build.gradle
|
@ -5,13 +5,24 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'inc.sdt.controlcentermanagement'
|
group = 'inc.sdt.controlcentermanagement'
|
||||||
version = '0.0.1-SNAPSHOT'
|
version = '0.0.1'
|
||||||
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility = '17'
|
sourceCompatibility = '17'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def codeArtifactToken = "aws codeartifact get-authorization-token --domain sdt --domain-owner 003960268191 --region ap-northeast-1 --query authorizationToken --output text".execute().text
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'https://sdt-003960268191.d.codeartifact.ap-northeast-1.amazonaws.com/maven/sdt-development/'
|
||||||
|
credentials {
|
||||||
|
username "aws"
|
||||||
|
password codeArtifactToken
|
||||||
|
}
|
||||||
|
// url 'http://192.168.1.232:8081/repository/maven-releases/'
|
||||||
|
// allowInsecureProtocol true
|
||||||
|
}
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +32,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-mongodb")
|
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-amqp")
|
||||||
testImplementation ("org.springframework.boot:spring-boot-starter-test")
|
testImplementation ("org.springframework.boot:spring-boot-starter-test")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package inc.sdt.controlcentermanagement;
|
||||||
|
|
||||||
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.context.annotation.Bean;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class ControlCenterManagementApplication {
|
public class ControlCenterManagementApplication {
|
||||||
|
@ -10,4 +12,8 @@ public class ControlCenterManagementApplication {
|
||||||
SpringApplication.run(ControlCenterManagementApplication.class, args);
|
SpringApplication.run(ControlCenterManagementApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RestTemplate restTemplate() {
|
||||||
|
return new RestTemplate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
package inc.sdt.controlcentermanagement.application;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.CommandType;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.DeployRequest;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Slot;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Tube;
|
||||||
|
import inc.sdt.controlcentermanagement.infrastructure.resttemplate.RestTemplateRequestHandler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
class DefaultTubeService implements TubeService {
|
||||||
|
private final SlotRepositoryDelegate slotRepositoryDelegate;
|
||||||
|
private final RestTemplateRequestHandler restTemplateHandler;
|
||||||
|
private final String deployerEndpoint;
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
public DefaultTubeService(SlotRepositoryDelegate slotRepositoryDelegate, RestTemplateRequestHandler restTemplateHandler, @Value("${deployer.endpoint}") String deployerEndpoint) {
|
||||||
|
this.slotRepositoryDelegate = slotRepositoryDelegate;
|
||||||
|
this.restTemplateHandler = restTemplateHandler;
|
||||||
|
this.deployerEndpoint = deployerEndpoint;
|
||||||
|
this.log = LoggerFactory.getLogger(DefaultTubeService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Slot> get(String chamberNumber) {
|
||||||
|
log.info("[get] chamberNumber: {}", chamberNumber);
|
||||||
|
return slotRepositoryDelegate.get(chamberNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void controlByTubeCode(String authorization, Slot request) {
|
||||||
|
log.info("[controlByTubeCode] request: {}", request);
|
||||||
|
Map<String, String> tubeMap = new LinkedHashMap<>();
|
||||||
|
for (Tube tube : request.getTube()) {
|
||||||
|
Map<String, Integer> tubeOffsetMap = this.tubeOffset(request);
|
||||||
|
String offsetKey = request.getSlotNumber().substring(request.getSlotNumber().length() - 1);
|
||||||
|
int tubeOffset = tubeOffsetMap.getOrDefault(offsetKey, 1);
|
||||||
|
int tubeKey = Integer.parseInt(tube.getCode()) + tubeOffset;
|
||||||
|
tubeMap.put(String.valueOf(tubeKey), String.valueOf(request.getCommand().ordinal()));
|
||||||
|
}
|
||||||
|
|
||||||
|
DeployRequest deployRequest = DeployRequest.builder()
|
||||||
|
.assetCode(request.getAssetCode())
|
||||||
|
.deviceType("nodeq")
|
||||||
|
.appName(request.getSlotNumber())
|
||||||
|
.commandType(CommandType.JSON)
|
||||||
|
.parameters(tubeMap)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.invokeDeployer(request.getAssetCode(), authorization, deployRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void controlAll(String authorization, Slot request) {
|
||||||
|
log.info("[controlAll] request: {}", request);
|
||||||
|
|
||||||
|
List<Slot> slots = this.get(request.getChamberNumber());
|
||||||
|
Map<String, Map<String, Map<String, String>>> resultMap = new LinkedHashMap<>();
|
||||||
|
for (Slot slot : slots) {
|
||||||
|
String assetCode = slot.getAssetCode();
|
||||||
|
String slotNumber = slot.getSlotNumber();
|
||||||
|
List<Tube> tubes = slot.getTube();
|
||||||
|
|
||||||
|
Map<String, Map<String, String>> assetMap = resultMap.computeIfAbsent(assetCode, k -> new HashMap<>());
|
||||||
|
Map<String, String> slotMap = assetMap.computeIfAbsent(slotNumber, k -> new HashMap<>());
|
||||||
|
|
||||||
|
for (Tube tube : tubes) {
|
||||||
|
Map<String, Integer> tubeOffsetMap = this.tubeOffset(request);
|
||||||
|
String offsetKey = slotNumber.substring(slotNumber.length() - 1);
|
||||||
|
int tubeOffset = tubeOffsetMap.getOrDefault(offsetKey, 1);
|
||||||
|
int offsetResult = Integer.parseInt(tube.getCode()) + tubeOffset;
|
||||||
|
|
||||||
|
slotMap.put(String.valueOf(offsetResult), String.valueOf(request.getCommand().ordinal()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resultMap.forEach((assetCode, slot) -> slot.forEach((slotNumber, tube) -> {
|
||||||
|
DeployRequest deployRequest = DeployRequest.builder()
|
||||||
|
.assetCode(assetCode)
|
||||||
|
.deviceType("nodeq")
|
||||||
|
.appName(slotNumber)
|
||||||
|
.commandType(CommandType.JSON)
|
||||||
|
.parameters(tube)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.invokeDeployer(assetCode, authorization, deployRequest);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Integer> tubeOffset(Slot request) {
|
||||||
|
log.info("[tubeOffset] request: {}", request);
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
Map<String, Integer> tubeOffsetMap = new HashMap<>();
|
||||||
|
for (int i = 1; i <= 8; i++) {
|
||||||
|
tubeOffsetMap.put(String.valueOf(i), offset);
|
||||||
|
offset += 16;
|
||||||
|
if (i == 4) offset = 0;
|
||||||
|
}
|
||||||
|
return tubeOffsetMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invokeDeployer(String assetCode, String authorization, DeployRequest deployRequest) {
|
||||||
|
String url = UriComponentsBuilder.fromUriString(deployerEndpoint)
|
||||||
|
.path(String.format("/assets/%s/apps", assetCode))
|
||||||
|
.build()
|
||||||
|
.toUriString();
|
||||||
|
restTemplateHandler.httpPostRequestWithAuth(url, authorization, deployRequest, new TypeReference<>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package inc.sdt.controlcentermanagement.application;
|
||||||
|
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Slot;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public interface SlotRepositoryDelegate {
|
||||||
|
List<Slot> get(String chamberNumber);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package inc.sdt.controlcentermanagement.application;
|
||||||
|
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Slot;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public interface TubeService {
|
||||||
|
List<Slot> get(String chamberNumber);
|
||||||
|
void controlByTubeCode(String authorization, Slot request);
|
||||||
|
void controlAll(String authorization, Slot request);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package inc.sdt.controlcentermanagement.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public enum Command {
|
||||||
|
OFF,
|
||||||
|
ON;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package inc.sdt.controlcentermanagement.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public enum CommandType {
|
||||||
|
JSON("json");
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
CommandType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package inc.sdt.controlcentermanagement.domain;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public class DeployRequest {
|
||||||
|
private String assetCode;
|
||||||
|
private String deviceType;
|
||||||
|
private String appName;
|
||||||
|
private String commandType;
|
||||||
|
// private String fileName; // TODO: deployer에 추가되면 추가
|
||||||
|
private Map<String, String> parameters;
|
||||||
|
|
||||||
|
public DeployRequest(String assetCode, String deviceType, String appName, String commandType, Map<String, String> parameters) {
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
this.deviceType = deviceType;
|
||||||
|
this.appName = appName;
|
||||||
|
this.commandType = commandType;
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssetCode() {
|
||||||
|
return assetCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceType() {
|
||||||
|
return deviceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppName() {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommandType() {
|
||||||
|
return commandType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DeployRequest{" +
|
||||||
|
"assetCode='" + assetCode + '\'' +
|
||||||
|
", deviceType='" + deviceType + '\'' +
|
||||||
|
", appName='" + appName + '\'' +
|
||||||
|
", commandType=" + commandType +
|
||||||
|
", parameters=" + parameters +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder {
|
||||||
|
private String assetCode;
|
||||||
|
private String deviceType;
|
||||||
|
private String appName;
|
||||||
|
private String commandType;
|
||||||
|
private Map<String, String> parameters;
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder assetCode(String assetCode) {
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder deviceType(String deviceType) {
|
||||||
|
this.deviceType = deviceType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder appName(String appName) {
|
||||||
|
this.appName = appName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder commandType(CommandType commandType) {
|
||||||
|
this.commandType = commandType.toString().toLowerCase();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parameters(Map<String, String> parameters) {
|
||||||
|
this.parameters = parameters;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeployRequest build() {
|
||||||
|
return new DeployRequest(assetCode, deviceType, appName, commandType, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package inc.sdt.controlcentermanagement.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public class Slot {
|
||||||
|
private String id;
|
||||||
|
private String slotNumber;
|
||||||
|
private String assetCode;
|
||||||
|
private List<Tube> tube;
|
||||||
|
private String chamberNumber;
|
||||||
|
private Command command;
|
||||||
|
|
||||||
|
protected Slot() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Slot(String id,String slotNumber, String assetCode, List<Tube> tube, String chamberNumber, Command command) {
|
||||||
|
this.id = id;
|
||||||
|
this.slotNumber = slotNumber;
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
this.tube = tube;
|
||||||
|
this.chamberNumber = chamberNumber;
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSlotNumber() {
|
||||||
|
return slotNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssetCode() {
|
||||||
|
return assetCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Tube> getTube() {
|
||||||
|
return tube;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChamberNumber() {
|
||||||
|
return chamberNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChamberNumber(String chamberNumber) {
|
||||||
|
this.chamberNumber = chamberNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Slot{" +
|
||||||
|
"id='" + id + '\'' +
|
||||||
|
", slotNumber='" + slotNumber + '\'' +
|
||||||
|
", assetCode='" + assetCode + '\'' +
|
||||||
|
", tube=" + tube +
|
||||||
|
", chamberNumber='" + chamberNumber + '\'' +
|
||||||
|
", command=" + command +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder {
|
||||||
|
private String id;
|
||||||
|
private String slotNumber;
|
||||||
|
private String assetCode;
|
||||||
|
private List<Tube> tube;
|
||||||
|
private String chamberNumber;
|
||||||
|
private Command command;
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder id(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder slotNumber(String slotNumber) {
|
||||||
|
this.slotNumber = slotNumber;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder assetCode(String assetCode) {
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder tube(List<Tube> tube) {
|
||||||
|
this.tube = tube;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder chamberNumber(String chamberNumber) {
|
||||||
|
this.chamberNumber = chamberNumber;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder Command(Command command) {
|
||||||
|
this.command = command;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Slot build() {
|
||||||
|
return new Slot(id, slotNumber, assetCode, tube, chamberNumber, command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package inc.sdt.controlcentermanagement.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public class Tube {
|
||||||
|
private String code;
|
||||||
|
private String offset;
|
||||||
|
|
||||||
|
protected Tube() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tube(String code, String offset) {
|
||||||
|
this.code = code;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Tube{" +
|
||||||
|
"number='" + code + '\'' +
|
||||||
|
", offset=" + offset +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.amqp;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "iam.amqp")
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPort(Integer port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExchange() {
|
||||||
|
return exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setExchange(String exchange) {
|
||||||
|
this.exchange = exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoutingKey() {
|
||||||
|
return routingKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,47 @@
|
||||||
|
package inc.sdt.controlcentermanagement.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.controlcentermanagement.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(RegisterResourceProducer.class);
|
||||||
|
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.controlcentermanagement.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,4 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.amqp;
|
||||||
|
|
||||||
|
public record ResourceMessagePayload(String name, String method, String uri, String applicationName, String description) {
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.nosql;
|
||||||
|
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
@Document("slot")
|
||||||
|
public class SlotDocument {
|
||||||
|
@Id
|
||||||
|
private String id;
|
||||||
|
private String slotNumber;
|
||||||
|
private String assetCode;
|
||||||
|
private List<TubeDocument> tube;
|
||||||
|
private String chamberNumber;
|
||||||
|
|
||||||
|
public SlotDocument(String id, String slotNumber, String assetCode, List<TubeDocument> tube, String chamberNumber) {
|
||||||
|
this.id = id;
|
||||||
|
this.slotNumber = slotNumber;
|
||||||
|
this.assetCode = assetCode;
|
||||||
|
this.tube = tube;
|
||||||
|
this.chamberNumber = chamberNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSlotNumber() {
|
||||||
|
return slotNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssetCode() {
|
||||||
|
return assetCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TubeDocument> getTube() {
|
||||||
|
return tube;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChamberNumber() {
|
||||||
|
return chamberNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SlotDocument{" +
|
||||||
|
"id='" + id + '\'' +
|
||||||
|
", slotNumber='" + slotNumber + '\'' +
|
||||||
|
", assetCode='" + assetCode + '\'' +
|
||||||
|
", tube=" + tube +
|
||||||
|
", chamberNumber='" + chamberNumber + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.nosql;
|
||||||
|
|
||||||
|
import inc.sdt.controlcentermanagement.application.SlotRepositoryDelegate;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Slot;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Tube;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public class SlotNoSQLRepository implements SlotRepositoryDelegate {
|
||||||
|
|
||||||
|
private final SlotRepository slotRepository;
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
public SlotNoSQLRepository(SlotRepository slotRepository) {
|
||||||
|
this.slotRepository = slotRepository;
|
||||||
|
this.log = LoggerFactory.getLogger(SlotNoSQLRepository.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Slot> get(String chamberNumber) {
|
||||||
|
log.debug("[get] chamberNumber: {}", chamberNumber);
|
||||||
|
return slotRepository.findAllByChamberNumber(chamberNumber)
|
||||||
|
.stream()
|
||||||
|
.map(this::to)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Slot to(SlotDocument slotDocument) {
|
||||||
|
return Slot.builder()
|
||||||
|
.id(slotDocument.getId())
|
||||||
|
.slotNumber(slotDocument.getSlotNumber())
|
||||||
|
.assetCode(slotDocument.getAssetCode())
|
||||||
|
.chamberNumber(slotDocument.getChamberNumber())
|
||||||
|
.tube(slotDocument.getTube()
|
||||||
|
.stream()
|
||||||
|
.map(tubeDocument -> new Tube(tubeDocument.getCode(), tubeDocument.getOffset()))
|
||||||
|
.toList())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.nosql;
|
||||||
|
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public interface SlotRepository extends MongoRepository<SlotDocument, String> {
|
||||||
|
List<SlotDocument> findAllByChamberNumber(String chamberNumber);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.nosql;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
public class TubeDocument {
|
||||||
|
private String code;
|
||||||
|
private String offset;
|
||||||
|
|
||||||
|
public TubeDocument(String code, String offset) {
|
||||||
|
this.code = code;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TubeDocument{" +
|
||||||
|
"id='" + code + '\'' +
|
||||||
|
", offset=" + offset +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.resttemplate;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface RestTemplateHandler {
|
||||||
|
<T> Optional<T> httpPostRequestWithAuth(String url, String authorization, Object body, TypeReference<T> typeReference);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.resttemplate;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.*;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RestTemplateRequestHandler implements RestTemplateHandler {
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
public RestTemplateRequestHandler(RestTemplate restTemplate) {
|
||||||
|
this.restTemplate = restTemplate;
|
||||||
|
this.log = LoggerFactory.getLogger(RestTemplateRequestHandler.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Optional<T> httpPostRequestWithAuth(String url, String authorization, Object body, TypeReference<T> typeReference) {
|
||||||
|
log.info("[httpPostRequestWithAuth] url = {}", url);
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
headers.setBearerAuth(authorization.split(" ")[1]);
|
||||||
|
ParameterizedTypeReference<T> parameterizedType = ParameterizedTypeReference.forType(typeReference.getType());
|
||||||
|
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, headers), parameterizedType);
|
||||||
|
return Optional.ofNullable(response.getBody());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package inc.sdt.controlcentermanagement.presentation;
|
||||||
|
|
||||||
|
import inc.sdt.controlcentermanagement.application.TubeService;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Slot;
|
||||||
|
import inc.sdt.controlcentermanagement.infrastructure.amqp.ResourceMapping;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class TubeController {
|
||||||
|
private final TubeService tubeService;
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
public TubeController(TubeService tubeService) {
|
||||||
|
this.tubeService = tubeService;
|
||||||
|
this.log = LoggerFactory.getLogger(TubeController.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResourceMapping(name = "Tube_Control", method = "PATCH", uri = "/chamber/{chamberNumber}/tube/toggle", description = "Tube On/Off 제어")
|
||||||
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
@PatchMapping("/chamber/{chamberNumber}/tube/toggle")
|
||||||
|
public void toggle(@RequestHeader("Authorization") String authorization, @PathVariable String chamberNumber, @RequestBody Slot slot) {
|
||||||
|
log.info("[toggle] chamberNumber: {}, slot: {}", chamberNumber, slot);
|
||||||
|
slot.setChamberNumber(chamberNumber);
|
||||||
|
if (slot.getTube() != null) {
|
||||||
|
tubeService.controlByTubeCode(authorization, slot);
|
||||||
|
} else {
|
||||||
|
tubeService.controlAll(authorization, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
server:
|
||||||
|
port: ${SERVER_PORT}
|
||||||
|
|
||||||
|
spring:
|
||||||
|
data:
|
||||||
|
mongodb:
|
||||||
|
uri: ${MONGODB_URL}
|
||||||
|
|
||||||
|
deployer:
|
||||||
|
endpoint: ${DEPLOYER_ENDPOINT}
|
||||||
|
|
||||||
|
iam:
|
||||||
|
enabled: true
|
||||||
|
amqp:
|
||||||
|
host: ${IAM_AMQP_HOST}
|
||||||
|
port: ${IAM_AMQP_PORT}
|
||||||
|
username: ${IAM_AMQP_CREDENTIALS_USERNAME}
|
||||||
|
password: ${IAM_AMQP_CREDENTIALS_PASSWORD}
|
||||||
|
exchange: iam
|
||||||
|
routing-key: resource
|
|
@ -1 +1,22 @@
|
||||||
|
server:
|
||||||
|
port: 8087
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: control-center-management
|
||||||
|
data:
|
||||||
|
mongodb:
|
||||||
|
uri: mongodb://sdt:251327@localhost:27017/awexomeray?authSource=admin
|
||||||
|
|
||||||
|
deployer:
|
||||||
|
endpoint: http://localhost:8085
|
||||||
|
|
||||||
|
iam:
|
||||||
|
enabled: true
|
||||||
|
amqp:
|
||||||
|
host: localhost
|
||||||
|
port: 5672
|
||||||
|
username: guest
|
||||||
|
password: guest
|
||||||
|
exchange: iam
|
||||||
|
routing-key: resource
|
|
@ -0,0 +1,41 @@
|
||||||
|
package inc.sdt.controlcentermanagement.infrastructure.nosql;
|
||||||
|
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Slot;
|
||||||
|
import inc.sdt.controlcentermanagement.domain.Tube;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sunae.jang (sa.jang@sdt.inc)
|
||||||
|
*/
|
||||||
|
@SpringBootTest
|
||||||
|
@ActiveProfiles("local")
|
||||||
|
class SlotNoSQLRepositoryTest {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
@Autowired
|
||||||
|
private SlotRepository slotRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void get() {
|
||||||
|
List<SlotDocument> findAllByChamberNumber = slotRepository.findAllByChamberNumber("1");
|
||||||
|
log.info("list: {}", findAllByChamberNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Slot to(SlotDocument slotDocument) {
|
||||||
|
List<Tube> tube = slotDocument.getTube().stream()
|
||||||
|
.map(tubeDocument -> new Tube(tubeDocument.getCode(), tubeDocument.getOffset())).toList();
|
||||||
|
return Slot.builder()
|
||||||
|
.id(slotDocument.getId())
|
||||||
|
.slotNumber(slotDocument.getSlotNumber())
|
||||||
|
.assetCode(slotDocument.getAssetCode())
|
||||||
|
.chamberNumber(slotDocument.getChamberNumber())
|
||||||
|
.tube(tube)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue