Browse Source

feat: socket - storage 통합

- 건수가 많을 경우 마지막 인덱스를 찾아오는 성능 테스트 진행 필요
feature/socket
지대한 6 months ago
parent
commit
f39c5b1403
  1. 3
      app/kac-app/src/main/java/kr/co/palnet/kac/app/api/v1/inner/socket/service/InnerSocketService.java
  2. 28
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AdsbDroneCommandImpl.java
  3. 32
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AntosDroneCommandImpl.java
  4. 29
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/SandboxDroneCommandImpl.java
  5. 54
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/storage/DroneCacheStorage.java
  6. 10
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/storage/DroneStorage.java
  7. 3
      common/model/src/main/java/kr/co/palnet/kac/common/model/common/SimpleControlDto.java

3
app/kac-app/src/main/java/kr/co/palnet/kac/app/api/v1/inner/socket/service/InnerSocketService.java

@ -76,17 +76,18 @@ public class InnerSocketService {
simpleControlDto.setControlId(latestControl.getCntrlId()); simpleControlDto.setControlId(latestControl.getCntrlId());
simpleControlDto.setTypeCd("02"); simpleControlDto.setTypeCd("02");
simpleControlDto.setAreaTrnsYn("E"); simpleControlDto.setAreaTrnsYn("E");
simpleControlDto.setControlStartDt(latestControl.getCntrlStDt());
} else { } else {
String controlId = UUID.randomUUID().toString(); String controlId = UUID.randomUUID().toString();
simpleControlDto.setControlId(controlId); simpleControlDto.setControlId(controlId);
simpleControlDto.setTypeCd("01"); simpleControlDto.setTypeCd("01");
simpleControlDto.setAreaTrnsYn("N"); simpleControlDto.setAreaTrnsYn("N");
simpleControlDto.setControlStartDt(Instant.now());
// 기체 식별번호의 관제 ID 저장 (single ton) // 기체 식별번호의 관제 ID 저장 (single ton)
ControlGpsStorage simpleControlStorage = ControlGpsStorage.getInstance(); ControlGpsStorage simpleControlStorage = ControlGpsStorage.getInstance();
simpleControlStorage.put(objectId, controlId); simpleControlStorage.put(objectId, controlId);
} }
return simpleControlDto; return simpleControlDto;
} }

28
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AdsbDroneCommandImpl.java

@ -5,7 +5,6 @@ import kr.co.palnet.kac.common.model.common.DroneHistoryDto;
import kr.co.palnet.kac.common.model.common.SimpleControlDto; import kr.co.palnet.kac.common.model.common.SimpleControlDto;
import kr.co.palnet.kac.socket.core.command.DroneCommand; import kr.co.palnet.kac.socket.core.command.DroneCommand;
import kr.co.palnet.kac.socket.core.model.DroneRq; import kr.co.palnet.kac.socket.core.model.DroneRq;
import kr.co.palnet.kac.socket.core.storage.DroneCacheStorage;
import kr.co.palnet.kac.socket.core.storage.DroneStorage; import kr.co.palnet.kac.socket.core.storage.DroneStorage;
import kr.co.palnet.kac.socket.service.KacAppService; import kr.co.palnet.kac.socket.service.KacAppService;
import kr.co.palnet.kac.socket.service.WebSocketService; import kr.co.palnet.kac.socket.service.WebSocketService;
@ -72,10 +71,10 @@ public class AdsbDroneCommandImpl implements DroneCommand {
// STEP 1. 전에 내부 메모리에서 controlId 조회 // STEP 1. 전에 내부 메모리에서 controlId 조회
DroneCacheStorage droneCacheStorage = DroneCacheStorage.getInstance(); DroneStorage droneStorage = DroneStorage.getInstance();
DroneDto droneCacheDto = droneCacheStorage.get(drone.getObjectId()); DroneDto lastDroneDto = droneStorage.getLast(drone.getObjectId());
if (droneCacheDto == null) { if (lastDroneDto == null) {
// STEP 1. Control ID 발급 -> Application Server Http 통신 // STEP 1. Control ID 발급 -> Application Server Http 통신
try { try {
SimpleControlDto simpleControlDto = kacAppService.getControlId(drone.getObjectId()); SimpleControlDto simpleControlDto = kacAppService.getControlId(drone.getObjectId());
@ -84,13 +83,6 @@ public class AdsbDroneCommandImpl implements DroneCommand {
drone.setTypeCd(simpleControlDto.getTypeCd()); drone.setTypeCd(simpleControlDto.getTypeCd());
drone.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn()); drone.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn());
drone.setControlStartDt(Instant.now()); drone.setControlStartDt(Instant.now());
// ControlDto controlDto = new ControlDto();
// controlDto.setControlId(simpleControlDto.getControlId());
// controlDto.setTypeCd(simpleControlDto.getTypeCd());
// controlDto.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn());
// controlDto.setRegTime(System.currentTimeMillis());
drone.setRegDt(Instant.now()); drone.setRegDt(Instant.now());
} catch (Exception e) { } catch (Exception e) {
@ -98,23 +90,19 @@ public class AdsbDroneCommandImpl implements DroneCommand {
} }
} else { } else {
drone.setControlId(droneCacheDto.getControlId()); drone.setControlId(lastDroneDto.getControlId());
drone.setTypeCd("02"); drone.setTypeCd("02");
drone.setAreaTrnsYn(droneCacheDto.getAreaTrnsYn()); drone.setAreaTrnsYn(lastDroneDto.getAreaTrnsYn());
drone.setControlWarnCd(droneCacheDto.isControlWarnCd()); drone.setControlWarnCd(lastDroneDto.isControlWarnCd());
drone.setControlStartDt(droneCacheDto.getControlStartDt()); drone.setControlStartDt(lastDroneDto.getControlStartDt());
// droneCacheDTO.setRegTime(System.currentTimeMillis());
drone.setRegDt(Instant.now()); drone.setRegDt(Instant.now());
droneCacheStorage.put(drone.getObjectId(), drone);
} }
// STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리 // STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리
try { try {
// 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM) // 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM)
DroneStorage dronStorage = DroneStorage.getInstance(); droneStorage.add(drone);
dronStorage.add(drone);
} catch (Exception e) { } catch (Exception e) {
log.error("ERROR : {}", e.getMessage(), e); log.error("ERROR : {}", e.getMessage(), e);
} }

32
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/AntosDroneCommandImpl.java

@ -5,14 +5,12 @@ import kr.co.palnet.kac.common.model.common.DroneHistoryDto;
import kr.co.palnet.kac.common.model.common.SimpleControlDto; import kr.co.palnet.kac.common.model.common.SimpleControlDto;
import kr.co.palnet.kac.socket.core.command.DroneCommand; import kr.co.palnet.kac.socket.core.command.DroneCommand;
import kr.co.palnet.kac.socket.core.model.DroneRq; import kr.co.palnet.kac.socket.core.model.DroneRq;
import kr.co.palnet.kac.socket.core.storage.DroneCacheStorage;
import kr.co.palnet.kac.socket.core.storage.DroneStorage; import kr.co.palnet.kac.socket.core.storage.DroneStorage;
import kr.co.palnet.kac.socket.service.KacAppService; import kr.co.palnet.kac.socket.service.KacAppService;
import kr.co.palnet.kac.socket.service.WebSocketService; import kr.co.palnet.kac.socket.service.WebSocketService;
import kr.co.palnet.kac.util.DroneUtil; import kr.co.palnet.kac.util.DroneUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.Instant; import java.time.Instant;
@ -73,11 +71,10 @@ public class AntosDroneCommandImpl implements DroneCommand {
// STEP 1. 전에 내부 메모리에서 controlId 조회 // STEP 1. 전에 내부 메모리에서 controlId 조회
DroneCacheStorage droneCacheStorage = DroneCacheStorage.getInstance(); DroneStorage droneStorage = DroneStorage.getInstance();
// ControlDto dronCacheDTO = controlStorage.get(drone.getObjectId()); DroneDto lastDroneDto = droneStorage.getLast(drone.getObjectId());
DroneDto dronCacheDto = droneCacheStorage.get(drone.getObjectId());
if (dronCacheDto == null) { if (lastDroneDto == null) {
// STEP 1. Control ID 발급 -> Application Server Http 통신 // STEP 1. Control ID 발급 -> Application Server Http 통신
try { try {
SimpleControlDto simpleControlDto = kacAppService.getControlId(drone.getObjectId()); SimpleControlDto simpleControlDto = kacAppService.getControlId(drone.getObjectId());
@ -85,16 +82,8 @@ public class AntosDroneCommandImpl implements DroneCommand {
drone.setControlId(simpleControlDto.getControlId()); drone.setControlId(simpleControlDto.getControlId());
drone.setTypeCd(simpleControlDto.getTypeCd()); drone.setTypeCd(simpleControlDto.getTypeCd());
drone.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn()); drone.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn());
drone.setControlStartDt(Instant.now()); drone.setControlStartDt(simpleControlDto.getControlStartDt() != null ? simpleControlDto.getControlStartDt() : Instant.now());
// ControlDto controlDto = new ControlDto();
// controlDto.setControlId(simpleControlDto.getControlId());
// controlDto.setTypeCd(simpleControlDto.getTypeCd());
// controlDto.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn());
// controlDto.setRegTime(System.currentTimeMillis());
// controlStorage.put(drone.getObjectId(), controlDto);
// controlStorage.put(drone.getObjectId(), controlDto);
drone.setRegDt(Instant.now()); drone.setRegDt(Instant.now());
} catch (Exception e) { } catch (Exception e) {
@ -102,21 +91,18 @@ public class AntosDroneCommandImpl implements DroneCommand {
} }
} else { } else {
drone.setControlId(dronCacheDto.getControlId()); drone.setControlId(lastDroneDto.getControlId());
drone.setTypeCd("02"); drone.setTypeCd("02");
drone.setAreaTrnsYn(dronCacheDto.getAreaTrnsYn()); drone.setAreaTrnsYn(lastDroneDto.getAreaTrnsYn());
drone.setControlWarnCd(dronCacheDto.isControlWarnCd()); drone.setControlWarnCd(lastDroneDto.isControlWarnCd());
drone.setControlStartDt(dronCacheDto.getControlStartDt()); drone.setControlStartDt(lastDroneDto.getControlStartDt());
drone.setRegDt(Instant.now()); drone.setRegDt(Instant.now());
droneCacheStorage.put(drone.getObjectId(), drone);
} }
// STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리 // STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리
try { try {
// 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM) // 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM)
DroneStorage dronStorage = DroneStorage.getInstance(); droneStorage.add(drone);
dronStorage.add(drone);
} catch (Exception e) { } catch (Exception e) {
log.error("ERROR : {}", e.getMessage(), e); log.error("ERROR : {}", e.getMessage(), e);
} }

29
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/SandboxDroneCommandImpl.java

@ -5,7 +5,6 @@ import kr.co.palnet.kac.common.model.common.DroneHistoryDto;
import kr.co.palnet.kac.common.model.common.SimpleControlDto; import kr.co.palnet.kac.common.model.common.SimpleControlDto;
import kr.co.palnet.kac.socket.core.command.DroneCommand; import kr.co.palnet.kac.socket.core.command.DroneCommand;
import kr.co.palnet.kac.socket.core.model.DroneRq; import kr.co.palnet.kac.socket.core.model.DroneRq;
import kr.co.palnet.kac.socket.core.storage.DroneCacheStorage;
import kr.co.palnet.kac.socket.core.storage.DroneStorage; import kr.co.palnet.kac.socket.core.storage.DroneStorage;
import kr.co.palnet.kac.socket.service.KacAppService; import kr.co.palnet.kac.socket.service.KacAppService;
import kr.co.palnet.kac.socket.service.WebSocketService; import kr.co.palnet.kac.socket.service.WebSocketService;
@ -71,10 +70,10 @@ public class SandboxDroneCommandImpl implements DroneCommand {
Long start = System.currentTimeMillis(); Long start = System.currentTimeMillis();
// STEP 1. 전에 내부 메모리에서 controlId 조회 // STEP 1. 전에 내부 메모리에서 controlId 조회
DroneCacheStorage droneCacheStorage = DroneCacheStorage.getInstance(); DroneStorage droneStorage = DroneStorage.getInstance();
DroneDto droneCacheDto = droneCacheStorage.get(drone.getObjectId()); DroneDto lastDroneDto = droneStorage.getLast(drone.getObjectId());
if (droneCacheDto == null) { if (lastDroneDto == null) {
// STEP 1. Control ID 발급 -> Application Server Http 통신 // STEP 1. Control ID 발급 -> Application Server Http 통신
try { try {
SimpleControlDto simpleControlDto = kacAppService.getControlId(drone.getObjectId()); SimpleControlDto simpleControlDto = kacAppService.getControlId(drone.getObjectId());
@ -84,37 +83,23 @@ public class SandboxDroneCommandImpl implements DroneCommand {
drone.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn()); drone.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn());
drone.setControlStartDt(Instant.now()); drone.setControlStartDt(Instant.now());
// DroneDto newDroneCacheDto = new DroneDto();
// newDroneCacheDto.setControlId(simpleControlDto.getControlId());
// newDroneCacheDto.setTypeCd(simpleControlDto.getTypeCd());
// newDroneCacheDto.setAreaTrnsYn(simpleControlDto.getAreaTrnsYn());
// newDroneCacheDto.setRegDt(Instant.now());
// controlStorage.put(drone.getObjectId(), newDroneCacheDto);
droneCacheStorage.put(drone.getObjectId(), drone);
} catch (Exception e) { } catch (Exception e) {
log.error("ERROR : {}", e.getMessage(), e); log.error("ERROR : {}", e.getMessage(), e);
} }
} else { } else {
drone.setControlId(droneCacheDto.getControlId()); drone.setControlId(lastDroneDto.getControlId());
drone.setTypeCd("02"); drone.setTypeCd("02");
drone.setAreaTrnsYn(droneCacheDto.getAreaTrnsYn()); drone.setAreaTrnsYn(lastDroneDto.getAreaTrnsYn());
drone.setControlWarnCd(droneCacheDto.isControlWarnCd()); drone.setControlWarnCd(lastDroneDto.isControlWarnCd());
drone.setControlStartDt(droneCacheDto.getControlStartDt()); drone.setControlStartDt(lastDroneDto.getControlStartDt());
// droneCacheDto.setRegTime(System.currentTimeMillis());
// controlStorage.put(drone.getObjectId(), droneCacheDto);
drone.setRegDt(Instant.now()); drone.setRegDt(Instant.now());
droneCacheStorage.put(drone.getObjectId(), drone);
} }
// STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리 // STEP 2. 이력 생성할 전문 전달 -> DRON의 대한 식별정보만 이력 관리
try { try {
// 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM) // 저장 해 놓았다가 한거번에 전송 - 필요한 곳에 전송(HISTORY, UTM)
DroneStorage droneStorage = DroneStorage.getInstance();
droneStorage.add(drone); droneStorage.add(drone);
} catch (Exception e) { } catch (Exception e) {
log.error("ERROR : {}", e.getMessage(), e); log.error("ERROR : {}", e.getMessage(), e);

54
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/storage/DroneCacheStorage.java

@ -1,54 +0,0 @@
package kr.co.palnet.kac.socket.core.storage;
import kr.co.palnet.kac.common.model.common.DroneDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class DroneCacheStorage {
private final Map<String, DroneDto> controlMap;
private final int REMOVE_TIME = 1000 * 10;
private DroneCacheStorage() {
controlMap = new ConcurrentHashMap<>();
}
public static DroneCacheStorage getInstance() {
return LazyHolder.INSTANCE;
}
public static class LazyHolder {
private static final DroneCacheStorage INSTANCE = new DroneCacheStorage();
}
public DroneDto get(String objectId) {
return controlMap.get(objectId);
}
public DroneDto put(String objectId, DroneDto control) {
return controlMap.put(objectId, control);
}
public DroneDto remove(String objectId) {
return controlMap.remove(objectId);
}
// TODO scheduler 테스트 필요(현재 Bean등록 안함)
@Scheduled(fixedDelay = 1000 * 10)
public void remove() {
for (String key : controlMap.keySet()) {
DroneDto droneCacheDTO = controlMap.get(key);
long diff = Instant.now().toEpochMilli() - droneCacheDTO.getRegDt().toEpochMilli();
if(diff > REMOVE_TIME){
remove(key);
}
}
}
}

10
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/storage/DroneStorage.java

@ -25,6 +25,7 @@ public class DroneStorage {
return LazyHolder.INSTANCE; return LazyHolder.INSTANCE;
} }
public static class LazyHolder { public static class LazyHolder {
private static final DroneStorage INSTANCE = new DroneStorage(); private static final DroneStorage INSTANCE = new DroneStorage();
} }
@ -46,6 +47,13 @@ public class DroneStorage {
return droneMap.get(objectId); return droneMap.get(objectId);
} }
public DroneDto getLast(String objectId) {
List<DroneDto> droneDtoList = droneMap.get(objectId);
if (droneDtoList == null || droneDtoList.isEmpty()) return null;
return droneDtoList.getLast();
// return droneDtoList.get(droneDtoList.size() - 1);
}
public void add(DroneDto drone) { public void add(DroneDto drone) {
if (drone == null || drone.getObjectId() == null || drone.getObjectId().isEmpty()) { if (drone == null || drone.getObjectId() == null || drone.getObjectId().isEmpty()) {
return; return;
@ -82,8 +90,8 @@ public class DroneStorage {
Instant compareTime = Instant.now().minusSeconds(60); Instant compareTime = Instant.now().minusSeconds(60);
// 마지막 데이터가 1분 이상된 데이터라면 삭제 // 마지막 데이터가 1분 이상된 데이터라면 삭제
DroneDto lastDroneDto = list.stream().toList().getLast();
// DroneDto lastDroneDto = list.stream().toList().get(list.size() - 1); // DroneDto lastDroneDto = list.stream().toList().get(list.size() - 1);
DroneDto lastDroneDto = list.stream().toList().getLast();
if ((lastDroneDto.isSendHistroy() && lastDroneDto.isSendUtm()) || compareTime.isAfter(lastDroneDto.getRegDt())) { if ((lastDroneDto.isSendHistroy() && lastDroneDto.isSendUtm()) || compareTime.isAfter(lastDroneDto.getRegDt())) {
// list.remove(lastDronDto); // list.remove(lastDronDto);

3
common/model/src/main/java/kr/co/palnet/kac/common/model/common/SimpleControlDto.java

@ -5,6 +5,8 @@ import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.time.Instant;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ -13,4 +15,5 @@ public class SimpleControlDto {
private String controlId; private String controlId;
private String typeCd; private String typeCd;
private String areaTrnsYn; private String areaTrnsYn;
private Instant controlStartDt;
} }

Loading…
Cancel
Save