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'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
version = '0.0.1'
|
||||
|
||||
java {
|
||||
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 {
|
||||
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()
|
||||
}
|
||||
|
||||
|
@ -21,6 +32,7 @@ dependencies {
|
|||
}
|
||||
implementation("org.springframework.boot:spring-boot-starter-undertow")
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ package inc.sdt.controlcentermanagement;
|
|||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ControlCenterManagementApplication {
|
||||
|
@ -10,4 +12,8 @@ public class ControlCenterManagementApplication {
|
|||
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