1. Tube On/Off 제어 코드 수정

2. k8s 배포 관련 파일 추가
This commit is contained in:
장선애 2023-09-08 10:43:51 +09:00
parent 8cc8097f33
commit e4f24bf3a6
10 changed files with 153 additions and 16 deletions

View File

@ -0,0 +1,4 @@
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 003960268191.dkr.ecr.ap-northeast-2.amazonaws.com
docker build --platform linux/amd64 -t control-center-management ../../
docker tag control-center-management:latest 003960268191.dkr.ecr.ap-northeast-2.amazonaws.com/sdt-cloud/control-center-management:0.0.1
docker push 003960268191.dkr.ecr.ap-northeast-2.amazonaws.com/sdt-cloud/control-center-management:0.0.1

View File

@ -0,0 +1,3 @@
SERVER_PORT: 8087
MONGODB_URL: mongodb://sdt:251327@13.209.39.139:27017/awexomeray?authSource=admin
DEPLOYER_ENDPOINT: http://device-deployer.sdt-cloud.svc.cluster.local:8085

42
k8s/deploy.yaml Normal file
View File

@ -0,0 +1,42 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: control-center-management
namespace: sdt-cloud
labels:
name: control-center-management
spec:
selector:
matchLabels:
name: control-center-management
replicas: 1
template:
metadata:
labels:
name: control-center-management
spec:
imagePullSecrets:
- name: regcred
containers:
- name: control-center-management
image: 003960268191.dkr.ecr.ap-northeast-2.amazonaws.com/sdt-cloud/control-center-management:0.0.1
imagePullPolicy: Always
ports:
- containerPort: 8087
env:
- name: SPRING_PROFILES_ACTIVE
value: "k8s"
- name: SERVER_PORT
value: "8087"
- name: MONGODB_URL
value: "mongodb://sdt:251327@mongo-db.database.svc.cluster.local/awexomeray?authSource=admin"
- name: DEPLOYER_ENDPOINT
value: "http://device-deployer.sdt-cloud.svc.cluster.local:8085"
- name: IAM_AMQP_HOST
value: "rabbitmq.sdt-cloud.svc.cluster.local"
- name: IAM_AMQP_PORT
value: "5672"
- name: IAM_AMQP_CREDENTIALS_USERNAME
value: "sdt"
- name: IAM_AMQP_CREDENTIALS_PASSWORD
value: "251327"

15
k8s/svc.yaml Normal file
View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: control-center-management
namespace: sdt-cloud
spec:
ports:
- port: 8087
targetPort: 8087
protocol: TCP
name: control-center-management
nodePort: 30870
type: NodePort
selector:
name: control-center-management

16
rest/api.http Normal file
View File

@ -0,0 +1,16 @@
### ON/OFF 제어
#PATCH http://13.209.39.139:30870/chamber/1/tube/toggle
PATCH http://localhost:8087/chamber/1/tube/toggle
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJvcmdhbml6YXRpb25JZCI6ImQxZGJlYWExLWY5ZTUtNGE4OC1hMWM4LTYzMWQ4NTMyOWJmYyIsInJvbGVzIjpbIlJPTEVfQURNSU5JU1RSQVRPUiJdLCJpZCI6IjcyYTUxZDUwLTYwMDEtNDAwYy04NjNmLWZlOGU2OGE1MGExMCIsInN1YiI6InNhLmphbmdAc2R0LmluYyIsImlhdCI6MTY5NDEzNjg4OCwiZXhwIjoxNjk0MTQwNDg4fQ.likh7Ix7p4Yf2iwankLG71VGrgCDzQzhn9Z7QJK0blg
{
"command" : "OFF",
"assetCode" : "NODEQ-TEST-1",
"slotNumber" : "1-1",
"tube": [
{"code": "1"}, {"code": "3"}, {"code": "11"}, {"code": "16"}
]
}
//{"command": "ON"}

View File

@ -1,10 +1,7 @@
package inc.sdt.controlcentermanagement.application; package inc.sdt.controlcentermanagement.application;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import inc.sdt.controlcentermanagement.domain.CommandType; import inc.sdt.controlcentermanagement.domain.*;
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 inc.sdt.controlcentermanagement.infrastructure.resttemplate.RestTemplateRequestHandler;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -45,7 +42,7 @@ class DefaultTubeService implements TubeService {
log.info("[controlByTubeCode] request: {}", request); log.info("[controlByTubeCode] request: {}", request);
Map<String, String> tubeMap = new LinkedHashMap<>(); Map<String, String> tubeMap = new LinkedHashMap<>();
for (Tube tube : request.getTube()) { for (Tube tube : request.getTube()) {
Map<String, Integer> tubeOffsetMap = this.tubeOffset(request); Map<String, Integer> tubeOffsetMap = this.tubeOffset();
String offsetKey = request.getSlotNumber().substring(request.getSlotNumber().length() - 1); String offsetKey = request.getSlotNumber().substring(request.getSlotNumber().length() - 1);
int tubeOffset = tubeOffsetMap.getOrDefault(offsetKey, 1); int tubeOffset = tubeOffsetMap.getOrDefault(offsetKey, 1);
int tubeKey = Integer.parseInt(tube.getCode()) + tubeOffset; int tubeKey = Integer.parseInt(tube.getCode()) + tubeOffset;
@ -64,10 +61,9 @@ class DefaultTubeService implements TubeService {
} }
@Override @Override
public void controlAll(String authorization, Slot request) { public void controlAll(String authorization, List<Slot> slots, Command command) {
log.info("[controlAll] request: {}", request); log.info("[controlAll] chamberNumber: {}, command: {}", slots.get(0).getChamberNumber(), command);
List<Slot> slots = this.get(request.getChamberNumber());
Map<String, Map<String, Map<String, String>>> resultMap = new LinkedHashMap<>(); Map<String, Map<String, Map<String, String>>> resultMap = new LinkedHashMap<>();
for (Slot slot : slots) { for (Slot slot : slots) {
String assetCode = slot.getAssetCode(); String assetCode = slot.getAssetCode();
@ -78,12 +74,11 @@ class DefaultTubeService implements TubeService {
Map<String, String> slotMap = assetMap.computeIfAbsent(slotNumber, k -> new HashMap<>()); Map<String, String> slotMap = assetMap.computeIfAbsent(slotNumber, k -> new HashMap<>());
for (Tube tube : tubes) { for (Tube tube : tubes) {
Map<String, Integer> tubeOffsetMap = this.tubeOffset(request); Map<String, Integer> tubeOffsetMap = this.tubeOffset();
String offsetKey = slotNumber.substring(slotNumber.length() - 1); String offsetKey = slotNumber.substring(slotNumber.length() - 1);
int tubeOffset = tubeOffsetMap.getOrDefault(offsetKey, 1); int tubeOffset = tubeOffsetMap.getOrDefault(offsetKey, 1);
int offsetResult = Integer.parseInt(tube.getCode()) + tubeOffset; int offsetResult = Integer.parseInt(tube.getCode()) + tubeOffset;
slotMap.put(String.valueOf(offsetResult), String.valueOf(command.ordinal()));
slotMap.put(String.valueOf(offsetResult), String.valueOf(request.getCommand().ordinal()));
} }
} }
@ -100,9 +95,7 @@ class DefaultTubeService implements TubeService {
})); }));
} }
private Map<String, Integer> tubeOffset(Slot request) { private Map<String, Integer> tubeOffset() {
log.info("[tubeOffset] request: {}", request);
int offset = 0; int offset = 0;
Map<String, Integer> tubeOffsetMap = new HashMap<>(); Map<String, Integer> tubeOffsetMap = new HashMap<>();
for (int i = 1; i <= 8; i++) { for (int i = 1; i <= 8; i++) {

View File

@ -1,5 +1,6 @@
package inc.sdt.controlcentermanagement.application; package inc.sdt.controlcentermanagement.application;
import inc.sdt.controlcentermanagement.domain.Command;
import inc.sdt.controlcentermanagement.domain.Slot; import inc.sdt.controlcentermanagement.domain.Slot;
import java.util.List; import java.util.List;
@ -10,5 +11,5 @@ import java.util.List;
public interface TubeService { public interface TubeService {
List<Slot> get(String chamberNumber); List<Slot> get(String chamberNumber);
void controlByTubeCode(String authorization, Slot request); void controlByTubeCode(String authorization, Slot request);
void controlAll(String authorization, Slot request); void controlAll(String authorization, List<Slot> slots, Command command);
} }

View File

@ -8,6 +8,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.NoSuchElementException;
/** /**
* @author sunae.jang (sa.jang@sdt.inc) * @author sunae.jang (sa.jang@sdt.inc)
*/ */
@ -26,11 +29,13 @@ public class TubeController {
@PatchMapping("/chamber/{chamberNumber}/tube/toggle") @PatchMapping("/chamber/{chamberNumber}/tube/toggle")
public void toggle(@RequestHeader("Authorization") String authorization, @PathVariable String chamberNumber, @RequestBody Slot slot) { public void toggle(@RequestHeader("Authorization") String authorization, @PathVariable String chamberNumber, @RequestBody Slot slot) {
log.info("[toggle] chamberNumber: {}, slot: {}", chamberNumber, slot); log.info("[toggle] chamberNumber: {}, slot: {}", chamberNumber, slot);
List<Slot> slots = tubeService.get(chamberNumber);
if (slots.isEmpty()) throw new NoSuchElementException(chamberNumber);
slot.setChamberNumber(chamberNumber); slot.setChamberNumber(chamberNumber);
if (slot.getTube() != null) { if (slot.getTube() != null) {
tubeService.controlByTubeCode(authorization, slot); tubeService.controlByTubeCode(authorization, slot);
} else { } else {
tubeService.controlAll(authorization, slot); tubeService.controlAll(authorization, slots, slot.getCommand());
} }
} }
} }

View File

@ -0,0 +1,25 @@
package inc.sdt.controlcentermanagement.presentation.exception;
import org.springframework.http.HttpStatus;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
record ExceptionResponse(int code, String error, String message, long timestamp) {
public static Builder builder(HttpStatus httpStatus) {
return new Builder(httpStatus);
}
public static class Builder {
private HttpStatus httpStatus;
private Builder(HttpStatus httpStatus) {
this.httpStatus = httpStatus;
}
public ExceptionResponse build(String message) {
final long timeStamp = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
return new ExceptionResponse(this.httpStatus.value(), this.httpStatus.getReasonPhrase(), message, timeStamp);
}
}
}

View File

@ -0,0 +1,33 @@
package inc.sdt.controlcentermanagement.presentation.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.NoSuchElementException;
@RestControllerAdvice
class RestControllerExceptionHandler {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
ExceptionResponse handleIllegalArgumentException(IllegalArgumentException e) {
return ExceptionResponse.builder(HttpStatus.BAD_REQUEST)
.build(e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
ExceptionResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
return ExceptionResponse.builder(HttpStatus.BAD_REQUEST)
.build(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
}
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
ExceptionResponse handleNoSuchElementException(NoSuchElementException e) {
return ExceptionResponse.builder(HttpStatus.NOT_FOUND)
.build(e.getMessage() + " does not exist.");
}
}