shjung преди 3 години
родител
ревизия
38517f57f5
променени са 43 файла, в които са добавени 1449 реда и са изтрити 465 реда
  1. 4 0
      src/main/java/com/its/api/ItsOpServerApplication.java
  2. 1 1
      src/main/java/com/its/api/bis/controller/BisController.java
  3. 13 8
      src/main/java/com/its/api/bis/service/BitService.java
  4. 29 0
      src/main/java/com/its/api/config/VdsConfig.java
  5. 28 0
      src/main/java/com/its/api/config/VmsConfig.java
  6. 3 17
      src/main/java/com/its/api/its/controller/cctv/CctvCommonController.java
  7. 43 0
      src/main/java/com/its/api/its/controller/cctv/CctvControlController.java
  8. 6 0
      src/main/java/com/its/api/its/controller/common/CommonSttsController.java
  9. 46 0
      src/main/java/com/its/api/its/controller/vds/VdsControlController.java
  10. 53 0
      src/main/java/com/its/api/its/controller/vms/VmsControlController.java
  11. 2 2
      src/main/java/com/its/api/its/model/dto/cctv/CctvControlDto.java
  12. 121 0
      src/main/java/com/its/api/its/model/dto/vds/VdsControlDto.java
  13. 126 0
      src/main/java/com/its/api/its/model/dto/vms/VmsControlDto.java
  14. 5 0
      src/main/java/com/its/api/its/repository/vds/TbVdsCtlrRepository.java
  15. 66 0
      src/main/java/com/its/api/its/service/cctv/CctvControlProbeService.java
  16. 91 5
      src/main/java/com/its/api/its/service/cctv/CctvControlService.java
  17. 20 18
      src/main/java/com/its/api/its/service/cctv/TbCctvCtlrService.java
  18. 32 4
      src/main/java/com/its/api/its/service/common/CommonSttsService.java
  19. 20 17
      src/main/java/com/its/api/its/service/vds/TbVdsCtlrService.java
  20. 200 0
      src/main/java/com/its/api/its/service/vds/VdsControlService.java
  21. 20 17
      src/main/java/com/its/api/its/service/vms/TbVmsCtlrService.java
  22. 60 0
      src/main/java/com/its/api/its/service/vms/VmsControlService.java
  23. 1 1
      src/main/java/com/its/api/scheduler/job/FcltSttsJobThread.java
  24. 1 1
      src/main/java/com/its/api/utis/controller/UtisController.java
  25. 22 17
      src/main/java/com/its/api/utis/service/RsemstService.java
  26. 43 0
      src/main/java/com/its/api/xnettcp/client/NettyTcpClient.java
  27. 53 0
      src/main/java/com/its/api/xnettcp/client/NettyTcpClientBootstrapFactory.java
  28. 38 0
      src/main/java/com/its/api/xnettcp/client/codec/NettyTcpClientDecoder.java
  29. 31 0
      src/main/java/com/its/api/xnettcp/client/codec/NettyTcpClientEncoder.java
  30. 48 0
      src/main/java/com/its/api/xnettcp/client/handler/NettyTcpClientIdleHandler.java
  31. 20 0
      src/main/java/com/its/api/xnettcp/client/handler/NettyTcpClientInboundHandler.java
  32. 23 0
      src/main/java/com/its/api/xnettcp/client/listener/NettyTcpClientCloseListener.java
  33. 40 0
      src/main/java/com/its/api/xnettcp/client/listener/NettyTcpClientConnectListener.java
  34. 61 0
      src/main/java/com/its/api/xnettcp/client/service/VdsCommClientService.java
  35. 52 4
      src/main/java/com/its/api/xnetudp/CenterCommUdpServer.java
  36. 2 1
      src/main/java/com/its/api/xnetudp/protocol/CENTER_COMM_DEFINE.java
  37. 11 0
      src/main/resources/application-dev.yml
  38. 12 4
      src/main/resources/application.yml
  39. 2 2
      src/test/java/com/its/op/ItsOpServerApplicationTests.java
  40. 0 125
      src/test/java/com/its/op/TbIfscVrtxArrEntity.java
  41. 0 48
      src/test/java/com/its/op/TbIfscVrtxArrEntityPK.java
  42. 0 125
      src/test/java/com/its/op/TbRoadVrtxArrEntity.java
  43. 0 48
      src/test/java/com/its/op/TbRoadVrtxArrEntityPK.java

+ 4 - 0
src/main/java/com/its/api/ItsOpServerApplication.java

@@ -2,6 +2,7 @@ package com.its.api;
 
 import com.its.api.config.AppUtils;
 import com.its.api.config.ProcessConfig;
+import com.its.api.xnettcp.client.service.VdsCommClientService;
 import com.its.api.xnetudp.CenterCommUdpServer;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.DisposableBean;
@@ -64,6 +65,9 @@ public class ItsOpServerApplication implements CommandLineRunner, ApplicationLis
 
         CenterCommUdpServer centerCommUdpServer = (CenterCommUdpServer)AppUtils.getBean(CenterCommUdpServer.class);
         centerCommUdpServer.run();
+
+        VdsCommClientService vdsCommClientService = (VdsCommClientService)AppUtils.getBean(VdsCommClientService.class);
+        vdsCommClientService.run();
     }
 
     @Override

+ 1 - 1
src/main/java/com/its/api/bis/controller/BisController.java

@@ -43,7 +43,7 @@ public class BisController {
     @ApiOperation(value = "BIT 상태현황(Summary+List)", response = FcltSttsListDto.class, responseContainer = "ArrayList")
     @GetMapping(value = "/stts/bit/total", produces = {"application/json; charset=utf8"})
     public FcltSttsListDto findAllBitSttsTotal() {
-        return this.bitService.findAllListSttsTotal();
+        return this.bitService.findAllListSttsTotal(true);
     }
 
     @ApiOperation(value = "BIT 통신상태(장애)", response = SttsCommErrDto.class, responseContainer = "ArrayList")

+ 13 - 8
src/main/java/com/its/api/bis/service/BitService.java

@@ -187,13 +187,13 @@ public class BitService {
      * @param
      */
     @Transactional(readOnly = true)
-    public FcltSttsListDto findAllListSttsTotal() {
+    public FcltSttsListDto findAllListSttsTotal(boolean total) {
 
         String fcltType = "BIT";
         FcltSttsListDto result = new FcltSttsListDto();
         Map<String, FcltSttsDto> resultMap = new HashMap<>();
 
-        AtomicInteger error = new AtomicInteger(0);
+        //AtomicInteger error = new AtomicInteger(0);
         AtomicInteger normal = new AtomicInteger(0);
         AtomicInteger doorOpen = new AtomicInteger(0);
         AtomicInteger fanRun = new AtomicInteger(0);
@@ -255,16 +255,19 @@ public class BitService {
             }
         });
 
-        resultMap.forEach((key, obj) -> {
-            sttsDtoList.add(obj);
-        });
+        if (total) {
+            resultMap.forEach((key, obj) -> {
+                sttsDtoList.add(obj);
+            });
+        }
 
+        int error = ctlrList.size() - normal.get();
         FcltSttsSummaryDto summaryDto = FcltSttsSummaryDto.builder()
                 .fcltType(fcltType)
                 .fcltNm(fcltType)
                 .totalCnt(ctlrList.size())
                 .normalCnt(normal.get())
-                .errorCnt(error.get())
+                .errorCnt(error)
                 .colErrCnt(0)
                 .build();
 
@@ -273,7 +276,9 @@ public class BitService {
         summaryDto.setFanRun(fanRun.get());
         summaryDto.setHetrRun(hetrRun.get());
         summaryDto.setModlErr(modlErr.get());
-        summaryDto.setFcltObjs(sttsDtoList);
+        if (total) {
+            summaryDto.setFcltObjs(sttsDtoList);
+        }
 
         result.getFcltList().add(summaryDto);
 
@@ -286,7 +291,7 @@ public class BitService {
      */
     @Transactional(readOnly = true)
     public List<FcltSttsDto> findAllListCommStts() {
-        FcltSttsListDto result = findAllListSttsTotal();
+        FcltSttsListDto result = findAllListSttsTotal(true);
         return result.getFcltList().get(0).getFcltObjs();
     }
 }

+ 29 - 0
src/main/java/com/its/api/config/VdsConfig.java

@@ -0,0 +1,29 @@
+package com.its.api.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+@Configuration
+@ConfigurationProperties(prefix = "application.vds")
+public class VdsConfig {
+
+    private boolean enabled = true;
+    private String  ipAddress;
+    private int     port;
+    private int     reconnectTime = 30; // 재접속 seconds
+
+    @PostConstruct
+    private void init() {
+        log.info("{}", this);
+    }
+}

+ 28 - 0
src/main/java/com/its/api/config/VmsConfig.java

@@ -0,0 +1,28 @@
+package com.its.api.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+@Configuration
+@ConfigurationProperties(prefix = "application.vms")
+public class VmsConfig {
+
+    private boolean enabled = true;
+    private String  ipAddress;
+    private int     port;
+
+    @PostConstruct
+    private void init() {
+        log.info("{}", this);
+    }
+}

+ 3 - 17
src/main/java/com/its/api/its/controller/cctv/CctvCommonController.java

@@ -1,16 +1,15 @@
 package com.its.api.its.controller.cctv;
 
-import com.its.api.its.model.dto.cctv.CctvControlDto;
 import com.its.api.its.model.dto.cctv.TbCctvCtlrDto;
-import com.its.api.its.service.cctv.CctvControlService;
 import com.its.api.its.service.cctv.TbCctvCtlrService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
-import javax.validation.Valid;
 import java.util.List;
 
 @Api(tags = "11.CCTV-0.공통")
@@ -21,7 +20,6 @@ import java.util.List;
 public class CctvCommonController {
 
     private final TbCctvCtlrService service;
-    private final CctvControlService controlService;
 
     @ApiOperation(value = "CCTV 목록 조회-삭제되지 않은(TB_CCTV_CTLR)", response = TbCctvCtlrDto.class, responseContainer = "ArrayList")
     @GetMapping(value = "/cctv-list", produces = {"application/json; charset=utf8"})
@@ -29,16 +27,4 @@ public class CctvCommonController {
         return this.service.findAllList();
     }
 
-    @ApiOperation(value = "CCTV PTZ 제어", response = CctvControlDto.CctvControlRes.class)
-    @PostMapping(value = "/control/ptz/{id}", produces = {"application/json; charset=utf8"})
-    public CctvControlDto.CctvControlRes controlPtz(@PathVariable("id") Long id, @RequestBody @Valid final CctvControlDto.CctvControlPtzReq req) {
-        return this.controlService.controlPtz(id, req);
-    }
-
-    @ApiOperation(value = "CCTV Preset 제어", response = CctvControlDto.CctvControlRes.class)
-    @PostMapping(value = "/control/preset/{id}", produces = {"application/json; charset=utf8"})
-    public CctvControlDto.CctvControlRes controlPreset(@PathVariable("id") Long id, @RequestBody @Valid final CctvControlDto.CctvControlPresetReq req) {
-        return this.controlService.controlPreset(id, req);
-    }
-
 }

+ 43 - 0
src/main/java/com/its/api/its/controller/cctv/CctvControlController.java

@@ -0,0 +1,43 @@
+package com.its.api.its.controller.cctv;
+
+import com.its.api.its.model.dto.cctv.CctvControlDto;
+import com.its.api.its.service.cctv.CctvControlService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@Api(tags = "11.CCTV-0.제어")
+@Validated
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/cctv/control")
+public class CctvControlController {
+
+    private final CctvControlService service;
+
+    @ApiOperation(value = "CCTV PTZ 제어", response = CctvControlDto.CctvControlRes.class)
+    @PostMapping(value = "/ptz/{id}", produces = {"application/json; charset=utf8"})
+    public CctvControlDto.CctvControlRes controlPtz(
+            @ApiParam(name = "id", value = "제어기번호", example = "1", required = true)
+            @PathVariable("id") Long id,
+            @ApiParam(name = "req", value = "CCTV PTZ 제어 정보", example = "[tilt-up, start, 20, ADMIN]", required = true)
+            @RequestBody @Valid final CctvControlDto.CctvControlPtzReq req) {
+        return this.service.controlPtz(id, req);
+    }
+
+    @ApiOperation(value = "CCTV Preset 제어", response = CctvControlDto.CctvControlRes.class)
+    @PostMapping(value = "/preset/{id}", produces = {"application/json; charset=utf8"})
+    public CctvControlDto.CctvControlRes controlPreset(
+            @ApiParam(name = "id", value = "제어기번호", example = "1", required = true)
+            @PathVariable("id") Long id,
+            @ApiParam(name = "req", value = "CCTV Preset 제어 정보", example = "[preset, call, 1, 0, 0, ADMIN]", required = true)
+            @RequestBody @Valid final CctvControlDto.CctvControlPresetReq req) {
+        return this.service.controlPreset(id, req);
+    }
+
+}

+ 6 - 0
src/main/java/com/its/api/its/controller/common/CommonSttsController.java

@@ -44,6 +44,12 @@ public class CommonSttsController {
         return this.unitSystService.findAllStts();
     }
 
+    @ApiOperation(value = "시설물 상태현황(종합)", response = FcltSttsListDto.class)
+    @GetMapping(value = "/summary", produces = {"application/json; charset=utf8"})
+    public FcltSttsListDto findAllFcltSttsSummary() {
+        return this.service.findAllFcltSttsSummary();
+    }
+
     @ApiOperation(value = "시설물 상태현황(종합)", response = FcltSttsListDto.class)
     @GetMapping(value = "/total", produces = {"application/json; charset=utf8"})
     public FcltSttsListDto findAllFcltSttsTotal() {

+ 46 - 0
src/main/java/com/its/api/its/controller/vds/VdsControlController.java

@@ -0,0 +1,46 @@
+package com.its.api.its.controller.vds;
+
+import com.its.api.its.model.dto.vds.VdsControlDto;
+import com.its.api.its.service.vds.VdsControlService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@Api(tags = "13.VDS-0.제어")
+@Validated
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/vds/control")
+public class VdsControlController {
+
+    private final VdsControlService service;
+
+    @ApiOperation(value = "VDS 제어기 리셋", response = VdsControlDto.VdsControlRes.class)
+    @PostMapping(value = "/reset/{id}", produces = {"application/json; charset=utf8"})
+    public VdsControlDto.VdsControlRes controlPtz(
+            @ApiParam(name = "id", value = "제어기번호", example = "1", required = true)
+            @PathVariable("id") String id,
+            @ApiParam(name = "req", value = "제어기번호", example = "1", required = true)
+            @RequestBody @Valid final VdsControlDto.VdsControlResetReq req) {
+        return this.service.controlReset(id, req);
+    }
+
+    @ApiOperation(value = "VDS 영상 이미지 요청", response = VdsControlDto.VdsControlRes.class)
+    @PostMapping(value = "/stop-image/{id}", produces = {"application/json; charset=utf8"})
+    public VdsControlDto.VdsControlRes requestStopImage(
+            @ApiParam(name = "id", value = "제어기번호", example = "1", required = true)
+            @PathVariable("id") String id,
+            @ApiParam(name = "req", value = "VDS 영상정보 요청", example = "[1, 0, ADMIN]", required = true)
+            @RequestBody @Valid final VdsControlDto.VdsControlStopImageReq req) {
+        if (req.getFrameNo() != 0) {
+            req.setFrameNo(0);
+        }
+        return this.service.requestStopImage(id, req);
+    }
+
+}

+ 53 - 0
src/main/java/com/its/api/its/controller/vms/VmsControlController.java

@@ -0,0 +1,53 @@
+package com.its.api.its.controller.vms;
+
+import com.its.api.its.model.dto.vms.VmsControlDto;
+import com.its.api.its.service.vms.VmsControlService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@Api(tags = "12.VMS-0.제어")
+@Validated
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/vms/control")
+public class VmsControlController {
+
+    private final VmsControlService service;
+
+    @ApiOperation(value = "VMS 제어기 제어", response = VmsControlDto.VmsControlRes.class)
+    @PostMapping(value = "/reset/{id}", produces = {"application/json; charset=utf8"})
+    public VmsControlDto.VmsControlRes controlReset(
+            @ApiParam(name = "id", value = "제어기번호", example = "1", required = true)
+            @PathVariable("id") Long id,
+            @ApiParam(name = "req", value = "VMS 제어기 제어 정보", example = "[ADMIN]", required = true)
+            @RequestBody @Valid final VmsControlDto.VmsControlReq req) {
+        return this.service.controlReset(id, req);
+    }
+
+    @ApiOperation(value = "VMS 제어기 전광판 ON/OFF 제어", response = VmsControlDto.VmsControlRes.class)
+    @PostMapping(value = "/power/{id}", produces = {"application/json; charset=utf8"})
+    public VmsControlDto.VmsControlRes controlPower(
+            @ApiParam(name = "id", value = "제어기번호", example = "1", required = true)
+            @PathVariable("id") Long id,
+            @ApiParam(name = "req", value = "VMS 제어기 제어 정보", example = "[ADMIN]", required = true)
+            @RequestBody @Valid final VmsControlDto.VmsControlReq req) {
+        return this.service.controlPower(id, req);
+    }
+
+    @ApiOperation(value = "VMS 제어기 휘도 제어", response = VmsControlDto.VmsControlRes.class)
+    @PostMapping(value = "/luminance/{id}", produces = {"application/json; charset=utf8"})
+    public VmsControlDto.VmsControlRes controlLuminance(
+            @ApiParam(name = "id", value = "제어기번호", example = "1", required = true)
+            @PathVariable("id") Long id,
+            @ApiParam(name = "req", value = "VMS 제어기 제어 정보", example = "[ADMIN]", required = true)
+            @RequestBody @Valid final VmsControlDto.VmsControlReq req) {
+        return this.service.controlLuminance(id, req);
+    }
+
+}

+ 2 - 2
src/main/java/com/its/api/its/model/dto/cctv/CctvControlDto.java

@@ -10,7 +10,7 @@ import javax.validation.constraints.PositiveOrZero;
 import java.io.Serializable;
 
 /**
- * CCTV 제어기 DTO Class
+ * CCTV 제어기 제어정보 DTO Class
  */
 @Data
 @Builder
@@ -50,7 +50,7 @@ public class CctvControlDto implements Serializable {
             this.userId = user_id;
         }
     }
-    @ApiModel("CctvControlPresetReq(CCTV PTZ 제어 정보)")
+    @ApiModel("CctvControlPresetReq(CCTV Preset 제어 정보)")
     @Getter
     @Setter
     @ToString

+ 121 - 0
src/main/java/com/its/api/its/model/dto/vds/VdsControlDto.java

@@ -0,0 +1,121 @@
+package com.its.api.its.model.dto.vds;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import javax.validation.constraints.PositiveOrZero;
+import java.io.Serializable;
+
+/**
+ * VDS 제어기 제어정보 DTO Class
+ */
+@Data
+@Builder
+@ApiModel("VdsControlDto(VDS 제어 정보")
+public class VdsControlDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModel("VdsControlResetReq(VDS 제어기 리셋)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VdsControlResetReq {
+
+        @ApiModelProperty("로그인 사용자 ID")
+        @JsonProperty("user_id")
+        private String userId;
+
+        @Builder
+        public VdsControlResetReq(String user_id) {
+            this.userId = user_id;
+        }
+    }
+
+    @ApiModel("VdsControlRes(VDS 제어기 제어 응답)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VdsControlRes {
+
+        @ApiModelProperty("제어결과(0: 성공, 기타: 오류")
+        @JsonProperty("error")
+        private Integer error;
+
+        @ApiModelProperty("제어결과메시지")
+        @JsonProperty("message")
+        private String message;
+
+        public void setResult(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+        @Builder
+        public VdsControlRes(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+    }
+
+    @ApiModel("VdsControlStopImageReq(VDS 영상정보 요청)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VdsControlStopImageReq {
+
+        @ApiModelProperty("카메라번호(기본:1)")
+        @JsonProperty("camera_no")
+        @PositiveOrZero
+        private Integer cameraNo;
+
+        @ApiModelProperty("프레임번호(무조건:0)")
+        @JsonProperty("frame_no")
+        @PositiveOrZero
+        private Integer frameNo;
+
+        @ApiModelProperty("로그인 사용자 ID")
+        @JsonProperty("user_id")
+        private String userId;
+
+        @Builder
+        public VdsControlStopImageReq(Integer camera_no, String user_id) {
+            this.cameraNo = camera_no;
+            this.userId = user_id;
+        }
+    }
+
+    @ApiModel("VdsControlStopImageRes(VDS 영상정보 요청 응답)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VdsControlStopImageRes {
+
+        @ApiModelProperty("제어결과(0: 성공, 기타: 오류")
+        @JsonProperty("error")
+        private Integer error;
+
+        @ApiModelProperty("제어결과메시지")
+        @JsonProperty("message")
+        private String message;
+
+        @ApiModelProperty("영상이미지")
+        @JsonProperty("image")
+        private byte[] image;
+
+        public void setResult(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+        @Builder
+        public VdsControlStopImageRes(Integer error, String message, byte[] image) {
+            this.error = error;
+            this.message = message;
+            this.image = image;
+        }
+    }
+}

+ 126 - 0
src/main/java/com/its/api/its/model/dto/vms/VmsControlDto.java

@@ -0,0 +1,126 @@
+package com.its.api.its.model.dto.vms;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+import javax.validation.constraints.PositiveOrZero;
+import java.io.Serializable;
+
+/**
+ * Vms 제어기 제어정보 DTO Class
+ */
+@Data
+@Builder
+@ApiModel("VmsControlDto(VMS 제어 정보")
+public class VmsControlDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModel("VmsControlReq(VMS 제어기 제어 정보)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VmsControlReq {
+
+        @ApiModelProperty("로그인 사용자 ID")
+        @JsonProperty("user_id")
+        private String userId;
+
+        @ApiModelProperty("리셋(0), 전관판제어(0:On, 1:Off), 휘도제어(0:자동, 1:주간, 2:야간, 3~100:수동)")
+        @JsonProperty("value")
+        private Integer value;
+
+        @Builder
+        public VmsControlReq(String user_id, Integer value) {
+            this.userId = user_id;
+            this.value = value;
+        }
+    }
+
+    @ApiModel("VmsControlRes(VMS 제어기 제어 응답)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VmsControlRes {
+
+        @ApiModelProperty("제어결과(0: 성공, 기타: 오류")
+        @JsonProperty("error")
+        private Integer error;
+
+        @ApiModelProperty("제어결과메시지")
+        @JsonProperty("message")
+        private String message;
+
+        public void setResult(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+        @Builder
+        public VmsControlRes(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+    }
+
+    @ApiModel("VmsControlStopImageReq(VMS 영상정보 요청)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VmsControlStopImageReq {
+
+        @ApiModelProperty("카메라번호(기본:1)")
+        @JsonProperty("camera_no")
+        @PositiveOrZero
+        private Integer cameraNo;
+
+        @ApiModelProperty("프레임번호(무조건:0)")
+        @JsonProperty("frame_no")
+        @PositiveOrZero
+        private Integer frameNo;
+
+        @ApiModelProperty("로그인 사용자 ID")
+        @JsonProperty("user_id")
+        private String userId;
+
+        @Builder
+        public VmsControlStopImageReq(Integer camera_no, String user_id) {
+            this.cameraNo = camera_no;
+            this.userId = user_id;
+        }
+    }
+
+    @ApiModel("VmsControlStopImageRes(VMS 영상정보 요청 응답)")
+    @Getter
+    @Setter
+    @ToString
+    @NoArgsConstructor(access = AccessLevel.PROTECTED)
+    public static class VmsControlStopImageRes {
+
+        @ApiModelProperty("제어결과(0: 성공, 기타: 오류")
+        @JsonProperty("error")
+        private Integer error;
+
+        @ApiModelProperty("제어결과메시지")
+        @JsonProperty("message")
+        private String message;
+
+        @ApiModelProperty("영상이미지")
+        @JsonProperty("image")
+        private byte[] image;
+
+        public void setResult(Integer error, String message) {
+            this.error = error;
+            this.message = message;
+        }
+        @Builder
+        public VmsControlStopImageRes(Integer error, String message, byte[] image) {
+            this.error = error;
+            this.message = message;
+            this.image = image;
+        }
+    }
+}

+ 5 - 0
src/main/java/com/its/api/its/repository/vds/TbVdsCtlrRepository.java

@@ -4,9 +4,11 @@ import com.its.api.its.model.entity.vds.TbVdsCtlr;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
 import java.util.List;
+import java.util.Optional;
 
 @Repository
 public interface TbVdsCtlrRepository extends JpaRepository<TbVdsCtlr, String>, JpaSpecificationExecutor<TbVdsCtlr> {
@@ -14,6 +16,9 @@ public interface TbVdsCtlrRepository extends JpaRepository<TbVdsCtlr, String>, J
     @Query("select p from TbVdsCtlr p left outer join fetch p.state")
     List<TbVdsCtlr> findAll();
 
+    @Query("select p from TbVdsCtlr p left outer join fetch p.state where p.ctlrMngmNmbr = :id")
+    Optional<TbVdsCtlr> findOne(@Param("id") String id);
+
     @Query("select p from TbVdsCtlr p left outer join fetch p.state where p.delYn = 'N'")
     List<TbVdsCtlr> findAllList();
 

+ 66 - 0
src/main/java/com/its/api/its/service/cctv/CctvControlProbeService.java

@@ -0,0 +1,66 @@
+package com.its.api.its.service.cctv;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class CctvControlProbeService {
+
+    Map<String, String> startCmd = new HashMap<>();
+    Map<String, String> stopCmd = new HashMap<>();
+    Map<String, String> presetCmd = new HashMap<>();
+
+    @PostConstruct
+    void init() {
+        this.startCmd.put("tilt-up",   "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=4&PTZCTRL.speed=");
+        this.startCmd.put("tilt-down", "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=5&PTZCTRL.speed=");
+        this.startCmd.put("pan-left",  "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=2&PTZCTRL.speed=");
+        this.startCmd.put("pan-right", "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=3&PTZCTRL.speed=");
+        this.startCmd.put("zoom-in",   "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=13&PTZCTRL.speed=");
+        this.startCmd.put("zoom-out",  "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=14&PTZCTRL.speed=");
+        this.startCmd.put("focus-in",  "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=15&PTZCTRL.speed=");
+        this.startCmd.put("focus-out", "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=16&PTZCTRL.speed=");
+
+        this.stopCmd.put("tilt-up",   "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+        this.stopCmd.put("tilt-down", "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+        this.stopCmd.put("pan-left",  "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+        this.stopCmd.put("pan-right", "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+        this.stopCmd.put("zoom-in",   "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+        this.stopCmd.put("zoom-out",  "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+        this.stopCmd.put("focus-in",  "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+        this.stopCmd.put("focus-out", "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=0");
+
+        this.presetCmd.put("call",    "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=11&PTZCTRL.no=");
+        this.presetCmd.put("save",    "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=10&PTZCTRL.no=");
+        this.presetCmd.put("delete",  "/cgi-bin/control.cgi?action=update&group=PTZCTRL&channel=0&PTZCTRL.action=12&PTZCTRL.no=");
+    }
+
+    public String getPtzCmd(String control, String action, int speed) {
+        if (StringUtils.equalsIgnoreCase("start", action)) {
+            String command = this.startCmd.get(control);
+            if (command != null) {
+                return command + speed;
+            }
+        } else if (StringUtils.equalsIgnoreCase("stop", action)) {
+            return this.stopCmd.get(control);
+        }
+        return null;
+    }
+
+    public String getPresetCmd(String action, Integer psetNmbr) {
+        String command = this.presetCmd.get(action);
+        if (command != null) {
+            return command + psetNmbr;
+        }
+        return null;
+    }
+
+}

+ 91 - 5
src/main/java/com/its/api/its/service/cctv/CctvControlService.java

@@ -24,6 +24,7 @@ public class CctvControlService {
 
     private final TbCctvCtlrRepository repo;
     private final CctvControlZenoService zenoControl;
+    private final CctvControlProbeService probeControl;
 
     // 데이터 1건 조회, 없으면 exception
     private TbCctvCtlr requireOne(Long id) {
@@ -33,12 +34,97 @@ public class CctvControlService {
                 .orElseThrow(() -> new NoSuchElementException("데이터가 존재하지 않습니다: " + id));
     }
 
-    public CctvControlDto.CctvControlRes controlPresetProbeDigital(String ipAddr, String userId, String userPswd, CctvControlDto.CctvControlPresetReq req) {
+    /**
+     * PROBE Digital Preset control
+     * @param ipAddr
+     * @param userId
+     * @param userPswd
+     * @param req
+     * @return
+     */
+    public CctvControlDto.CctvControlRes controlPresetProbe(String ipAddr, String userId, String userPswd, CctvControlDto.CctvControlPresetReq req) {
         CctvControlDto.CctvControlRes result = new CctvControlDto.CctvControlRes(req.getCommand(), req.getAction(), 0, "success");
-        return result;
+        String controlUri = this.probeControl.getPresetCmd(req.getAction(), req.getNo());
+        if (controlUri == null) {
+            result.setResult(9, "unknown command");
+            return result;
+        }
+        return requestHttpPostProbe(result, controlUri, ipAddr, userId, userPswd);
     }
-    public CctvControlDto.CctvControlRes controlPtzProbeDigital(String ipAddr, String userId, String userPswd, CctvControlDto.CctvControlPtzReq req) {
+
+    /**
+     * PROBE Digital PTZ control
+     * @param ipAddr
+     * @param userId
+     * @param userPswd
+     * @param req
+     * @return
+     */
+    public CctvControlDto.CctvControlRes controlPtzProbe(String ipAddr, String userId, String userPswd, CctvControlDto.CctvControlPtzReq req) {
         CctvControlDto.CctvControlRes result = new CctvControlDto.CctvControlRes(req.getCommand(), req.getAction(), 0, "success");
+        String controlUri = this.probeControl.getPtzCmd(req.getCommand(), req.getAction(), req.getSpeed());
+        if (controlUri == null) {
+            result.setResult(9, "unknown command");
+            return result;
+        }
+        return requestHttpPostProbe(result, controlUri, ipAddr, userId, userPswd);
+    }
+    public CctvControlDto.CctvControlRes requestHttpPostProbe(CctvControlDto.CctvControlRes result, String controlUri, String ipAddr, String userId, String userPswd) {
+        String encoding = Base64.getEncoder().encodeToString((userId + ":" + userPswd).getBytes());
+        String apiUrl = "http://" + ipAddr + controlUri;
+        //log.info("{}, {}", apiUrl, SysUtils.byteArrayToHex(controlData));
+
+        HttpURLConnection connection = null;
+        try {
+            URL url = new URL(apiUrl);
+            connection = (HttpURLConnection)url.openConnection();
+            connection.setConnectTimeout(5000); //서버에 연결되는 Timeout 시간 설정
+            connection.setReadTimeout(5000); // InputStream 읽어 오는 Timeout 시간 설정
+
+            connection.setDoOutput(true); //POST 데이터를 OutputStream 으로 넘겨 주겠다는 설정
+            connection.setDoInput(true);
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty("Content-Type", "application/octet-stream");
+            connection.setRequestProperty("Accept", "text/html, */*");
+            connection.setRequestProperty("Accept-Encoding", "identity");
+            connection.setRequestProperty("Authorization", "Basic " + encoding);
+            //connection.setRequestProperty("charset", "UTF-8");
+            //connection.setRequestProperty("Content-Length", Integer.toString(controlData.length));
+            connection.setRequestProperty("User-Agent", "Mozilla/3.0");
+
+            //connection.setUseCaches(false);
+            //connection.setDefaultUseCaches(false);
+
+            DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
+            wr.flush();
+            wr.close();
+
+            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
+                String line;
+                StringBuilder sb = new StringBuilder();
+                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
+                while ((line = br.readLine()) != null) {
+                    sb.append(line).append("\n");
+                }
+                br.close();
+                log.info("HTTP_OK: CCTV, {}, {}", ipAddr, sb);
+                result.setResult(0, sb.toString());
+            } else {
+                log.error("HTTP_FAIL: {}", connection.getResponseMessage());
+                if (connection.getResponseMessage() == null) {
+                    result.setResult(2, "cctv network fail.");
+                } else {
+                    result.setResult(3, connection.getResponseMessage());
+                }
+            }
+        } catch (Exception e){
+            log.error("Exception: {}", e.getMessage());
+            result.setResult(4, e.getMessage());
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
         return result;
     }
 
@@ -169,7 +255,7 @@ public class CctvControlService {
         }
         else if (StringUtils.equals("2", cctv.getCctvType())) {
             // 프로브디지털
-            return this.controlPtzProbeDigital(cctv.getCctvCtlrIp(), "admin", "1234", req);
+            return this.controlPtzProbe(cctv.getCctvCtlrIp(), "admin", "12345", req);
         }
         return new CctvControlDto.CctvControlRes(req.getCommand(), req.getAction(), 1, "unknown cctv type");
     }
@@ -189,7 +275,7 @@ public class CctvControlService {
         }
         else if (StringUtils.equals("2", cctv.getCctvType())) {
             // 프로브디지털
-            return this.controlPresetProbeDigital(cctv.getCctvCtlrIp(), "admin", "1234", req);
+            return this.controlPresetProbe(cctv.getCctvCtlrIp(), "admin", "12345", req);
         }
         return new CctvControlDto.CctvControlRes(req.getCommand(), req.getAction(), 1, "unknown cctv type");
     }

+ 20 - 18
src/main/java/com/its/api/its/service/cctv/TbCctvCtlrService.java

@@ -139,7 +139,7 @@ public class TbCctvCtlrService {
      * @param
      */
     @Transactional(readOnly = true)
-    public FcltSttsListDto findAllSttsListTotal() {
+    public FcltSttsListDto findAllSttsListTotal(boolean total) {
 
         String fcltType = "CCTV";
         FcltSttsListDto result = new FcltSttsListDto();
@@ -151,21 +151,22 @@ public class TbCctvCtlrService {
         List<TbCctvCtlr> ctlrList = this.repo.findAllList();
         ctlrList.forEach(obj -> {
             TbCctvSttsDto dto = obj.toSttsDto();
-            FcltSttsDto stts = FcltSttsDto.builder()
-                    .fcltType(fcltType)
-                    .fcltNmbr(String.valueOf(obj.getCctvMngmNmbr()))
-                    .fcltId(obj.getCctvCtlrId())
-                    .fcltNm(obj.getIstlLctnNm())
-                    .fcltKind(obj.getCctvType())
-                    .xCrdn(obj.getXCrdn())
-                    .yCrdn(obj.getYCrdn())
-                    .strmUrl(obj.getStrmSesnNm())
-                    .sttsCd(dto.getCmncSttsCd())
-                    .sttsDesc(dto.getCmncSttsDesc())
-                    .build();
-
-            sttsDtoList.add(stts);
-
+            if (total) {
+                FcltSttsDto stts = FcltSttsDto.builder()
+                        .fcltType(fcltType)
+                        .fcltNmbr(String.valueOf(obj.getCctvMngmNmbr()))
+                        .fcltId(obj.getCctvCtlrId())
+                        .fcltNm(obj.getIstlLctnNm())
+                        .fcltKind(obj.getCctvType())
+                        .xCrdn(obj.getXCrdn())
+                        .yCrdn(obj.getYCrdn())
+                        .strmUrl(obj.getStrmSesnNm())
+                        .sttsCd(dto.getCmncSttsCd())
+                        .sttsDesc(dto.getCmncSttsDesc())
+                        .build();
+
+                sttsDtoList.add(stts);
+            }
             if (CodeManager.CMNC_STTS_NORMAL.equals(dto.getCmncSttsCd())) {
                 normal.getAndIncrement();
             }
@@ -184,8 +185,9 @@ public class TbCctvCtlrService {
                 .build();
 
         summaryDto.init();
-        summaryDto.setFcltObjs(sttsDtoList);
-
+        if (total) {
+            summaryDto.setFcltObjs(sttsDtoList);
+        }
         result.getFcltList().add(summaryDto);
 
         return result;

+ 32 - 4
src/main/java/com/its/api/its/service/common/CommonSttsService.java

@@ -1,5 +1,6 @@
 package com.its.api.its.service.common;
 
+import com.its.api.bis.service.BitService;
 import com.its.api.its.model.dto.common.FcltSttsListDto;
 import com.its.api.its.service.cctv.TbCctvCtlrService;
 import com.its.api.its.service.vds.TbVdsCtlrService;
@@ -19,6 +20,7 @@ public class CommonSttsService {
     private final TbVmsCtlrService vmsService;
     private final TbVdsCtlrService vdsService;
     private final RsemstService rseService;
+    private final BitService bitService;
 
     /**
      * 시설물 상태정보 조회(통합)
@@ -30,21 +32,47 @@ public class CommonSttsService {
         FcltSttsListDto result = new FcltSttsListDto();
 
         // CCTV
-        FcltSttsListDto cctv = this.cctvService.findAllSttsListTotal();
+        FcltSttsListDto cctv = this.cctvService.findAllSttsListTotal(true);
         result.getFcltList().add(cctv.getFcltList().get(0));
 
         // VMS
-        FcltSttsListDto vms = this.vmsService.findAllSttsListTotal();
+        FcltSttsListDto vms = this.vmsService.findAllSttsListTotal(true);
         result.getFcltList().add(vms.getFcltList().get(0));
 
         // VMS
-        FcltSttsListDto vds = this.vdsService.findAllSttsListTotal();
+        FcltSttsListDto vds = this.vdsService.findAllSttsListTotal(true);
         result.getFcltList().add(vds.getFcltList().get(0));
 
         // RSE
-        FcltSttsListDto rse = this.rseService.findAllListSttsTotal();
+        FcltSttsListDto rse = this.rseService.findAllListSttsTotal(true);
         result.getFcltList().add(rse.getFcltList().get(0));
 
         return result;
     }
+
+    public FcltSttsListDto findAllFcltSttsSummary() {
+        FcltSttsListDto result = new FcltSttsListDto();
+
+        // CCTV
+        FcltSttsListDto cctv = this.cctvService.findAllSttsListTotal(false);
+        result.getFcltList().add(cctv.getFcltList().get(0));
+
+        // VMS
+        FcltSttsListDto vms = this.vmsService.findAllSttsListTotal(false);
+        result.getFcltList().add(vms.getFcltList().get(0));
+
+        // VMS
+        FcltSttsListDto vds = this.vdsService.findAllSttsListTotal(false);
+        result.getFcltList().add(vds.getFcltList().get(0));
+
+        // RSE
+        FcltSttsListDto rse = this.rseService.findAllListSttsTotal(false);
+        result.getFcltList().add(rse.getFcltList().get(0));
+
+        // BIT
+        FcltSttsListDto bit = this.bitService.findAllListSttsTotal(false);
+        result.getFcltList().add(bit.getFcltList().get(0));
+
+        return result;
+    }
 }

+ 20 - 17
src/main/java/com/its/api/its/service/vds/TbVdsCtlrService.java

@@ -198,7 +198,7 @@ public class TbVdsCtlrService {
      * @param
      */
     @Transactional(readOnly = true)
-    public FcltSttsListDto findAllSttsListTotal() {
+    public FcltSttsListDto findAllSttsListTotal(boolean total) {
 
         String fcltType = "VDS";
         FcltSttsListDto result = new FcltSttsListDto();
@@ -227,23 +227,25 @@ public class TbVdsCtlrService {
         // 상태 설정
         ctlrList.forEach(obj -> {
             TbVdsCtlrSttsDto dto = obj.toSttsDto();
-            FcltSttsDto stts = FcltSttsDto.builder()
-                    .fcltType(fcltType)
-                    .fcltNmbr(obj.getCtlrMngmNmbr())
-                    .fcltId(obj.getVdsCtlrId())
-                    .fcltNm(obj.getLctn())
-                    .fcltKind(obj.getCtlrTypeCd())
-                    .xCrdn(obj.getXCrdn())
-                    .yCrdn(obj.getYCrdn())
-                    .sttsCd(dto.getCmncSttsCd())
-                    .sttsDesc(dto.getCmncSttsDesc())
-                    .build();
-
-            sttsDtoList.add(stts);
+            if (total) {
+                FcltSttsDto stts = FcltSttsDto.builder()
+                        .fcltType(fcltType)
+                        .fcltNmbr(obj.getCtlrMngmNmbr())
+                        .fcltId(obj.getVdsCtlrId())
+                        .fcltNm(obj.getLctn())
+                        .fcltKind(obj.getCtlrTypeCd())
+                        .xCrdn(obj.getXCrdn())
+                        .yCrdn(obj.getYCrdn())
+                        .sttsCd(dto.getCmncSttsCd())
+                        .sttsDesc(dto.getCmncSttsDesc())
+                        .build();
+
+                sttsDtoList.add(stts);
+            }
 
             if (CodeManager.CMNC_STTS_NORMAL.equals(dto.getCmncSttsCd())) {
                 normal.getAndIncrement();
-                SttsCommErrDto commErrorDto = errDtoMap.get(stts.getFcltNmbr());
+                SttsCommErrDto commErrorDto = errDtoMap.get(dto.getCtlrMngmNmbr());
                 if (commErrorDto != null) {
                     if (commErrorDto.getColCnt() == 0) {
                         // 통신상태가 정상인 경우인데 수집건수가 0건 이면 수집오류로 처리
@@ -286,8 +288,9 @@ public class TbVdsCtlrService {
         summaryDto.setHetrRun(hetrRun.get());
         summaryDto.setPwerErr(pwerErr.get());
         summaryDto.setTempErr(tempErr.get());
-        summaryDto.setFcltObjs(sttsDtoList);
-
+        if (total) {
+            summaryDto.setFcltObjs(sttsDtoList);
+        }
         result.getFcltList().add(summaryDto);
 
         return result;

+ 200 - 0
src/main/java/com/its/api/its/service/vds/VdsControlService.java

@@ -0,0 +1,200 @@
+package com.its.api.its.service.vds;
+
+import com.its.api.its.model.dto.vds.VdsControlDto;
+import com.its.api.its.model.entity.vds.TbVdsCtlr;
+import com.its.api.its.repository.vds.TbVdsCtlrRepository;
+import com.its.api.utils.SysUtils;
+import com.its.api.xnettcp.client.service.VdsCommClientService;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.NoSuchElementException;
+
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class VdsControlService {
+
+    private final VdsCommClientService vdsCommClientService;
+    private final TbVdsCtlrRepository repo;
+
+    private static final int crc16_arc[] = {
+            0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+            0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+            0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+            0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+            0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+            0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+            0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+            0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+            0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+            0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+            0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+            0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+            0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+            0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+            0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+            0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+            0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+            0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+            0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+            0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+            0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+            0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+            0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+            0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+            0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+            0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+            0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+            0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+            0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+            0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+            0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+            0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
+    };
+
+    /**
+     * VDS CRC16-ARC(https://crccalc.com/)
+     * @param data
+     * @param start
+     * @param length
+     * @return
+     */
+    public int getCRC16ARC(byte[] data, int start, int length) {
+        int crc = 0x0000;
+        for (int ii = start; ii < (start+length); ii++) {
+            int b = data[ii];
+            crc = (crc >> 8) ^ crc16_arc[(crc ^ data[ii]) & 0xff];
+        }
+        //log.error("{}", Integer.toHexString(crc));
+        return crc & 0xFFFF;
+    }
+
+
+    // 데이터 1건 조회, 없으면 exception
+    private TbVdsCtlr requireOne(String id) {
+        return this.repo.findOne(id)
+                .orElseThrow(() -> new NoSuchElementException("데이터가 존재하지 않습니다: " + id));
+    }
+
+    public byte[] getCenterPacket(byte opCode, int length) {
+
+        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+        byteBuffer.put((byte)0x24); // 송신시스템-운영단말
+        byteBuffer.put((byte)0x04); // 수신시스템-VDS 서버
+        byteBuffer.put((byte)0x01); // 전체프레임개수
+        byteBuffer.put((byte)0x01); // 현재프레임번호
+        byteBuffer.put((byte)0x00); // Reserved
+        byteBuffer.put(opCode);     // OP Code
+        byteBuffer.putInt(length);  // 데이터 길이
+
+        //log.error("HEAD: {}", SysUtils.byteArrayToHex(byteBuffer.array()));
+        return byteBuffer.array();
+    }
+
+    /**
+     * VDS Center Communication protocol buffer create
+     * @param opCode
+     * @param address
+     * @return
+     */
+    public ByteBuffer getCommand(byte opCode, Integer group, Integer address, Integer frameNo, Integer cameraNo) {
+        int length = 0;
+        if (opCode == 0x0C) {
+            length = 11;
+        } else if (opCode == 0x16) {
+            length = 14;
+        } else {
+            log.error("Unknown VDS OPCode: {}", opCode);
+            return null;
+        }
+
+        // Center packet
+        byte[] center = getCenterPacket(opCode, length);
+
+        // VDS  packet
+        ByteBuffer vdsBuffer = ByteBuffer.allocate(length);
+        vdsBuffer.order(ByteOrder.BIG_ENDIAN);
+        vdsBuffer.put((byte)0x10); // DLE
+        vdsBuffer.put((byte)0x02); // STX
+        vdsBuffer.putShort((short)group.intValue());   // Address
+        vdsBuffer.putShort((short)address.intValue()); // Address
+        vdsBuffer.put(opCode);     // OP Code
+
+        if (opCode == 0x16) {
+            // 정지영상 요청
+            vdsBuffer.putShort((short)frameNo.intValue()); // Frame NO
+            vdsBuffer.put((byte)cameraNo.intValue()); // Camera No
+        }
+        vdsBuffer.put((byte)0x10); // DLE
+        vdsBuffer.put((byte)0x03); // ETX
+        int crc = getCRC16ARC(vdsBuffer.array(), 2, length - 6);
+        byte crc1 = (byte)((crc >> 8) & 0xFF);
+        byte crc2 = (byte)((crc     ) & 0xFF);
+        vdsBuffer.put(crc1); // CRC1
+        vdsBuffer.put(crc2); // CRC2
+        // DLE Stuffing 는 하지 않는 것으로 패킷 분석결과 나타남.
+
+        ByteBuffer cmdBuffer = ByteBuffer.allocate(center.length + length);
+        cmdBuffer.order(ByteOrder.BIG_ENDIAN);
+        cmdBuffer.put(center);
+        cmdBuffer.put(vdsBuffer.array());
+        log.info("VDS Request Buffer: {}", SysUtils.byteArrayToHex(cmdBuffer.array()));
+        return cmdBuffer;
+    }
+
+    /**
+     * VDS 제어기 리셋
+     * @param id
+     * @return
+     */
+    public VdsControlDto.VdsControlRes controlReset(String id, VdsControlDto.VdsControlResetReq req) {
+        TbVdsCtlr vds = this.requireOne(id);
+        ByteBuffer cmdBuffer = getCommand((byte)0x0C, 0, Integer.valueOf(id), 0, 0);
+        return requestVdsCommand(cmdBuffer);
+    }
+
+    /**
+     * VDS 영상정보 요청
+     * @param id
+     * @param req
+     * @return
+     */
+    public VdsControlDto.VdsControlRes requestStopImage(String id, VdsControlDto.VdsControlStopImageReq req) {
+        TbVdsCtlr vds = this.requireOne(id);
+        ByteBuffer cmdBuffer = getCommand((byte)0x16, 0, Integer.valueOf(id), req.getFrameNo(), req.getCameraNo());
+        return requestVdsCommand(cmdBuffer);
+    }
+
+    /**
+     * VDS 통신서버로 요청 메시지 전송
+     * @param cmdBuffer
+     * @return
+     */
+    public VdsControlDto.VdsControlRes requestVdsCommand(ByteBuffer cmdBuffer) {
+        VdsControlDto.VdsControlRes result = new VdsControlDto.VdsControlRes(0, "success");
+        if (cmdBuffer == null) {
+            result.setResult(2, "VDS 통신 메시지 생성 중 오류가 발생하였습니다.");
+            return result;
+        }
+        Channel channel = this.vdsCommClientService.getVdsClient().getChannel();
+        if (channel == null || !channel.isActive()) {
+            result.setResult(3, "VDS 서버와 통신이 실패하였습니다.");
+            return result;
+        }
+        ChannelFuture f = channel.writeAndFlush(cmdBuffer);
+        f.awaitUninterruptibly();
+        if (f.isDone() || f.isSuccess()) {
+            result.setResult(0, "VDS 서버에 요청 메시지를 정상적으로 전송하였습니다.");
+        } else {
+            result.setResult(4, "VDS 서버에 요청 메시지 전송이 실패하였습니다.");
+        }
+        return result;
+    }
+}

+ 20 - 17
src/main/java/com/its/api/its/service/vms/TbVmsCtlrService.java

@@ -219,7 +219,7 @@ public class TbVmsCtlrService {
      * 상태 목록
      * @param
      */
-    public FcltSttsListDto findAllSttsListTotal() {
+    public FcltSttsListDto findAllSttsListTotal(boolean total) {
 
         String fcltType = "VMS";
         FcltSttsListDto result = new FcltSttsListDto();
@@ -237,21 +237,22 @@ public class TbVmsCtlrService {
         List<TbVmsCtlr> ctlrList = this.repo.findAllList();
         ctlrList.forEach(obj -> {
             TbVmsSttsDto dto = obj.toSttsDto();
-            FcltSttsDto stts = FcltSttsDto.builder()
-                    .fcltType(fcltType)
-                    .fcltNmbr(String.valueOf(obj.getVmsCtlrNmbr()))
-                    .fcltId(obj.getVmsCtlrId())
-                    .fcltNm(obj.getIstlLctnNm())
-                    .fcltKind(obj.getIstlLctnNm())
-                    .xCrdn(obj.getXCrdn())
-                    .yCrdn(obj.getYCrdn())
-                    .strmUrl(obj.getStrmSesnNm())
-                    .sttsCd(dto.getCmncSttsCd())
-                    .sttsDesc(dto.getCmncSttsDesc())
-                    .build();
-
-            sttsDtoList.add(stts);
-
+            if (total) {
+                FcltSttsDto stts = FcltSttsDto.builder()
+                        .fcltType(fcltType)
+                        .fcltNmbr(String.valueOf(obj.getVmsCtlrNmbr()))
+                        .fcltId(obj.getVmsCtlrId())
+                        .fcltNm(obj.getIstlLctnNm())
+                        .fcltKind(obj.getIstlLctnNm())
+                        .xCrdn(obj.getXCrdn())
+                        .yCrdn(obj.getYCrdn())
+                        .strmUrl(obj.getStrmSesnNm())
+                        .sttsCd(dto.getCmncSttsCd())
+                        .sttsDesc(dto.getCmncSttsDesc())
+                        .build();
+
+                sttsDtoList.add(stts);
+            }
             if (CodeManager.CMNC_STTS_NORMAL.equals(dto.getCmncSttsCd())) {
                 normal.getAndIncrement();
                 if (("CDS1").equals(dto.getCboxDoorSttsCd())) {
@@ -294,7 +295,9 @@ public class TbVmsCtlrService {
         summaryDto.setModlErr(modlErr.get());
         summaryDto.setModlPwerErr(modlPwerErr.get());
         summaryDto.setTempErr(tempErr.get());
-        summaryDto.setFcltObjs(sttsDtoList);
+        if (total) {
+            summaryDto.setFcltObjs(sttsDtoList);
+        }
         result.getFcltList().add(summaryDto);
 
         return result;

+ 60 - 0
src/main/java/com/its/api/its/service/vms/VmsControlService.java

@@ -0,0 +1,60 @@
+package com.its.api.its.service.vms;
+
+import com.its.api.its.model.dto.vms.VmsControlDto;
+import com.its.api.its.repository.vms.TbVmsCtlrRepository;
+import com.its.api.xnetudp.CenterCommUdpServer;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class VmsControlService {
+
+    private final CenterCommUdpServer centerCommUdpServer;
+    private final TbVmsCtlrRepository repo;
+
+    /**
+     * VMS 제어기 리셋
+     * @param id
+     * @param req
+     * @return
+     */
+    public VmsControlDto.VmsControlRes controlReset(Long id, VmsControlDto.VmsControlReq req) {
+        boolean isSendMsg = this.centerCommUdpServer.requestReset(id, req);
+        if (isSendMsg) {
+            return new VmsControlDto.VmsControlRes(0, "success");
+        }
+        return new VmsControlDto.VmsControlRes(9, "VMS 서버로 제어 명령 전송 중 알수 없는 오류가 발생 하였습니다.");
+    }
+
+    /**
+     * VMS 제어기 전광판 On/Off 제어
+     * @param id
+     * @param req
+     * @param isOn
+     * @return
+     */
+    public VmsControlDto.VmsControlRes controlPower(Long id, VmsControlDto.VmsControlReq req) {
+        boolean isSendMsg = this.centerCommUdpServer.requestPowerControl(id, req);
+        if (isSendMsg) {
+            return new VmsControlDto.VmsControlRes(0, "success");
+        }
+        return new VmsControlDto.VmsControlRes(9, "VMS 서버로 제어 명령 전송 중 알수 없는 오류가 발생 하였습니다.");
+    }
+
+    /**
+     * VMS 제어기 휘도 제어
+     * @param id
+     * @param req
+     * @return
+     */
+    public VmsControlDto.VmsControlRes controlLuminance(Long id, VmsControlDto.VmsControlReq req) {
+        boolean isSendMsg = this.centerCommUdpServer.controlLuminance(id, req);
+        if (isSendMsg) {
+            return new VmsControlDto.VmsControlRes(0, "success");
+        }
+        return new VmsControlDto.VmsControlRes(9, "VMS 서버로 제어 명령 전송 중 알수 없는 오류가 발생 하였습니다.");
+    }
+}

+ 1 - 1
src/main/java/com/its/api/scheduler/job/FcltSttsJobThread.java

@@ -51,7 +51,7 @@ public class FcltSttsJobThread {
         }
 
         // BIS BIT Stts
-        FcltSttsListDto bitSttsDto = this.bitService.findAllListSttsTotal();
+        FcltSttsListDto bitSttsDto = this.bitService.findAllListSttsTotal(true);
         ItsWebSocketMessage bisMessage = new ItsWebSocketMessage("bisFcltStts", bitSttsDto);
         try {
             String bitSttsJsonData = this.mapper.writeValueAsString(bisMessage);

+ 1 - 1
src/main/java/com/its/api/utis/controller/UtisController.java

@@ -39,7 +39,7 @@ public class UtisController {
     @ApiOperation(value = "RSE 상태현황(Summary+List)", response = FcltSttsListDto.class)
     @GetMapping(value = "/stts/rse/total", produces = {"application/json; charset=utf8"})
     public FcltSttsListDto findAllRseSttsTotal() {
-        return this.service.findAllListSttsTotal();
+        return this.service.findAllListSttsTotal(true);
     }
 
     @ApiOperation(value = "RSE 통신상태(장애)", response = SttsCommErrDto.class, responseContainer = "ArrayList")

+ 22 - 17
src/main/java/com/its/api/utis/service/RsemstService.java

@@ -78,7 +78,7 @@ public class RsemstService {
      */
     @Transactional(readOnly = true)
     public List<FcltSttsDto> findAllListCommStts() {
-        FcltSttsListDto result = findAllListSttsTotal();
+        FcltSttsListDto result = findAllListSttsTotal(true);
         return result.getFcltList().get(0).getFcltObjs();
     }
 
@@ -86,7 +86,7 @@ public class RsemstService {
      * 상태 목록
      * @param
      */
-    public FcltSttsListDto findAllListSttsTotal() {
+    public FcltSttsListDto findAllListSttsTotal(boolean total) {
         FcltSttsListDto result = new FcltSttsListDto();
         AtomicInteger error = new AtomicInteger();
         AtomicInteger normal = new AtomicInteger();
@@ -98,20 +98,22 @@ public class RsemstService {
         List<Rsemst> ctlrList = this.repo.findAllList();
         ctlrList.forEach(obj -> {
             UtisRseStateDto.RseCommSttsDto dto = UtisRseStateDto.toSttsDto(obj);
-            FcltSttsDto stts = FcltSttsDto.builder()
-                    .fcltType(fcltType)
-                    .fcltNmbr(obj.getRseid())
-                    .fcltId(obj.getRseid())
-                    .fcltNm(obj.getLocation())
-                    .fcltKind("1")
-                    .xCrdn(obj.getCoordx()/10000000.)
-                    .yCrdn(obj.getCoordy()/10000000.)
-                    .sttsCd(dto.getCommCd())
-                    .sttsDesc(dto.getCommDesc())
-                    .updtDt(dto.getCollDt())
-                    .build();
-
-            sttsDtoList.add(stts);
+            if (total) {
+                FcltSttsDto stts = FcltSttsDto.builder()
+                        .fcltType(fcltType)
+                        .fcltNmbr(obj.getRseid())
+                        .fcltId(obj.getRseid())
+                        .fcltNm(obj.getLocation())
+                        .fcltKind("1")
+                        .xCrdn(obj.getCoordx() / 10000000.)
+                        .yCrdn(obj.getCoordy() / 10000000.)
+                        .sttsCd(dto.getCommCd())
+                        .sttsDesc(dto.getCommDesc())
+                        .updtDt(dto.getCollDt())
+                        .build();
+
+                sttsDtoList.add(stts);
+            }
 
             if (CodeManager.CMNC_STTS_NORMAL.equals(dto.getCommCd())) {
                 normal.getAndIncrement();
@@ -129,7 +131,10 @@ public class RsemstService {
                 .errorCnt(error.get())
                 .colErrCnt(0)
                 .build();
-        cntCctv.setFcltObjs(sttsDtoList);
+
+        if (total) {
+            cntCctv.setFcltObjs(sttsDtoList);
+        }
         result.getFcltList().add(cntCctv);
 
         return result;

+ 43 - 0
src/main/java/com/its/api/xnettcp/client/NettyTcpClient.java

@@ -0,0 +1,43 @@
+package com.its.api.xnettcp.client;
+
+import com.its.api.xnettcp.client.listener.NettyTcpClientCloseListener;
+import com.its.api.xnettcp.client.listener.NettyTcpClientConnectListener;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Callable;
+
+@Slf4j
+@Getter
+@Setter
+@RequiredArgsConstructor
+public class NettyTcpClient implements Callable<Object> {
+
+    private final String ipAddress;
+    private final int    port;
+    private final int    reconnectTime;
+    private final NettyTcpClientBootstrapFactory bootstrapFactory;
+    private Channel channel;
+
+    @Override
+    public Object call() throws Exception {
+        log.info("NettyTcpClient start: {}, {}", this.ipAddress, this.port);
+        try {
+            Bootstrap clientBootstrap = this.bootstrapFactory.createBootstrap();
+            ChannelFuture connectChannelFuture = clientBootstrap.connect(new InetSocketAddress(this.ipAddress, this.port));
+            this.channel = connectChannelFuture.addListener(new NettyTcpClientConnectListener(this))
+                    .channel().closeFuture().addListener(new NettyTcpClientCloseListener(this))
+                    .channel();
+        } catch (Exception e) {
+            log.error("Exception: {}", e.getMessage());
+            throw e;
+        }
+        return null;
+    }
+}

+ 53 - 0
src/main/java/com/its/api/xnettcp/client/NettyTcpClientBootstrapFactory.java

@@ -0,0 +1,53 @@
+package com.its.api.xnettcp.client;
+
+import com.its.api.xnettcp.client.codec.NettyTcpClientDecoder;
+import com.its.api.xnettcp.client.codec.NettyTcpClientEncoder;
+import com.its.api.xnettcp.client.handler.NettyTcpClientIdleHandler;
+import com.its.api.xnettcp.client.handler.NettyTcpClientInboundHandler;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@RequiredArgsConstructor
+public class NettyTcpClientBootstrapFactory {
+
+    private final int workerThread;
+    private final int connectTimeout;
+
+    public Bootstrap createBootstrap() throws Exception {
+
+        EventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(this.workerThread);
+        Bootstrap bootstrap = new Bootstrap();
+        bootstrap.channel(NioSocketChannel.class);
+        bootstrap.group(nioEventLoopGroup);
+        bootstrap.option(ChannelOption.AUTO_READ, true);
+        bootstrap.option(ChannelOption.TCP_NODELAY, true);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
+        bootstrap.option(ChannelOption.SO_RCVBUF, 8192);
+        bootstrap.option(ChannelOption.SO_SNDBUF, 8192);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
+        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, this.connectTimeout * 1000);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
+        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
+            @Override
+            public void initChannel(SocketChannel ch) throws Exception {
+                ch.pipeline().addLast("tcpClientIdleHandler", new NettyTcpClientIdleHandler(0, 0, 0, TimeUnit.SECONDS));
+                ch.pipeline().addLast("tcpClientEncoder",        new NettyTcpClientEncoder());            // Encoding handler
+                ch.pipeline().addLast("tcpClientDecoder",        new NettyTcpClientDecoder());            // Decoding handler
+                ch.pipeline().addLast("tcpClientInboundHandler", new NettyTcpClientInboundHandler());    // Packet Inbound handler
+            }
+        });
+
+        return bootstrap;
+    }
+}

+ 38 - 0
src/main/java/com/its/api/xnettcp/client/codec/NettyTcpClientDecoder.java

@@ -0,0 +1,38 @@
+package com.its.api.xnettcp.client.codec;
+
+import com.its.api.utils.NettyUtils;
+import com.its.api.utils.SysUtils;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+@Slf4j
+public class NettyTcpClientDecoder extends ByteToMessageDecoder {
+
+    @Override
+    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> list) throws Exception {
+
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        Channel channel = ctx.channel();
+
+        int readableBytes = byteBuf.readableBytes();
+        log.info("RECV_0: [{}]. ReadableBytes: {} Bytes, ReaderIndex: {}", ipAddress, readableBytes, byteBuf.readerIndex());
+        if (readableBytes == 0) {
+            log.error("RECV: {}. byteBuf.readableBytes() == 0.", ipAddress);
+            return;
+        }
+
+        byteBuf.markReaderIndex();
+        byte[] headBuffer = new byte[readableBytes];
+        byteBuf.readBytes(headBuffer);
+        log.info("RECV: [{}], {} Bytes. {}", ipAddress, headBuffer.length, SysUtils.byteArrayToHex(headBuffer));
+        byteBuf.readerIndex(headBuffer.length);
+        byteBuf.markReaderIndex();
+        byteBuf.discardReadBytes();
+        byteBuf.resetReaderIndex();
+    }
+}

+ 31 - 0
src/main/java/com/its/api/xnettcp/client/codec/NettyTcpClientEncoder.java

@@ -0,0 +1,31 @@
+package com.its.api.xnettcp.client.codec;
+
+import com.its.api.utils.NettyUtils;
+import com.its.api.utils.SysUtils;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.ByteBuffer;
+
+@Slf4j
+public class NettyTcpClientEncoder extends MessageToByteEncoder<Object> {
+
+    @Override
+    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf outByteBuf) throws Exception {
+
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        Channel channel = ctx.channel();
+
+        ByteBuffer buffer = (ByteBuffer)msg;
+        try {
+            byte[] sendBytes = buffer.array();
+            outByteBuf.writeBytes(sendBytes);
+            log.info("SEND: [{}], {} Bytes. {}", ipAddress, sendBytes.length, SysUtils.byteArrayToHex(sendBytes));
+        } catch (Exception e) {
+            log.error("NettyTcpClientEncoder.encode: SEND: {}. Exception Error: will be closed: {}.", ipAddress, e.toString());
+        }
+    }
+}

+ 48 - 0
src/main/java/com/its/api/xnettcp/client/handler/NettyTcpClientIdleHandler.java

@@ -0,0 +1,48 @@
+package com.its.api.xnettcp.client.handler;
+
+import com.its.api.utils.NettyUtils;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.handler.timeout.IdleStateHandler;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class NettyTcpClientIdleHandler extends IdleStateHandler {
+
+    public NettyTcpClientIdleHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {
+        super(readerIdleTime, writerIdleTime, allIdleTime, unit);
+    }
+
+    @Override
+    protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        log.info("channelIdle: {}", ipAddress);
+        // disconnect here
+    }
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        log.info("channelActive: {}", ipAddress);
+
+        super.channelActive(ctx);
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        log.info("channelInactive: {}", ipAddress);
+
+        super.channelInactive(ctx);
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        log.info("exceptionCaught: {}, {}", ipAddress, cause.getMessage());
+
+        ctx.channel().close();
+    }
+}

+ 20 - 0
src/main/java/com/its/api/xnettcp/client/handler/NettyTcpClientInboundHandler.java

@@ -0,0 +1,20 @@
+package com.its.api.xnettcp.client.handler;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class NettyTcpClientInboundHandler extends SimpleChannelInboundHandler<Object> {
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) throws Exception {
+
+    }
+
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
+    {
+        log.error("exceptionCaught:  {}", ctx.toString());
+        super.exceptionCaught(ctx, cause);
+    }
+}

+ 23 - 0
src/main/java/com/its/api/xnettcp/client/listener/NettyTcpClientCloseListener.java

@@ -0,0 +1,23 @@
+package com.its.api.xnettcp.client.listener;
+
+import com.its.api.xnettcp.client.NettyTcpClient;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@RequiredArgsConstructor
+public class NettyTcpClientCloseListener implements ChannelFutureListener {
+
+    private final NettyTcpClient client;
+
+    @Override
+    public void operationComplete(ChannelFuture channelFuture) throws Exception {
+        log.error("NettyTcpClientCloseListener: {}", channelFuture.channel().toString());
+        channelFuture.channel().close();
+        channelFuture.channel().eventLoop().schedule(this.client, this.client.getReconnectTime(), TimeUnit.SECONDS);
+    }
+}

+ 40 - 0
src/main/java/com/its/api/xnettcp/client/listener/NettyTcpClientConnectListener.java

@@ -0,0 +1,40 @@
+package com.its.api.xnettcp.client.listener;
+
+import com.its.api.xnettcp.client.NettyTcpClient;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class NettyTcpClientConnectListener implements ChannelFutureListener {
+
+    private final NettyTcpClient client;
+
+    @Override
+    public void operationComplete(ChannelFuture channelFuture) throws Exception {
+        if (!channelFuture.isSuccess()) {
+            log.error("NettyTcpClientConnectListener:  !SUCCESS, {}, cause,{}", channelFuture.channel().toString(), channelFuture.cause().toString());
+            channelFuture.channel().close();
+            //channelFuture.channel().eventLoop().schedule(this.client, this.client.getReconnectTime(), TimeUnit.SECONDS);
+        } else {
+            log.error("NettyTcpClientConnectListener: SUCCESS, {}", channelFuture.channel().toString());
+        }
+/*
+        if (channelFuture.isCancelled()) {
+            log.error("NettyTcpClientConnectListener:  Canceled, {}, cause,{}", channelFuture.channel().toString(), channelFuture.cause().toString());
+            channelFuture.channel().close();
+            channelFuture.channel().eventLoop().schedule(this.client, this.client.getReconnectTime(), TimeUnit.SECONDS);
+        } else if (!channelFuture.isSuccess()) {
+            log.error("NettyTcpClientConnectListener:  !Success, {}, cause,{}", channelFuture.channel().toString(), channelFuture.cause().toString());
+            channelFuture.channel().close();
+            channelFuture.channel().eventLoop().schedule(this.client, this.client.getReconnectTime(), TimeUnit.SECONDS);
+        } else if (!channelFuture.channel().isActive()) {
+            log.error("NettyTcpClientConnectListener:  !Active, {}, cause,{}", channelFuture.channel().toString(), channelFuture.cause().toString());
+            channelFuture.channel().close();
+            channelFuture.channel().eventLoop().schedule(this.client, this.client.getReconnectTime(), TimeUnit.SECONDS);
+        }
+*/
+    }
+}

+ 61 - 0
src/main/java/com/its/api/xnettcp/client/service/VdsCommClientService.java

@@ -0,0 +1,61 @@
+package com.its.api.xnettcp.client.service;
+
+import com.its.api.config.VdsConfig;
+import com.its.api.xnettcp.client.NettyTcpClient;
+import com.its.api.xnettcp.client.NettyTcpClientBootstrapFactory;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+@Slf4j
+@Getter
+@RequiredArgsConstructor
+@Service
+public class VdsCommClientService {
+
+    private final VdsConfig vdsConfig;
+    private NettyTcpClient vdsClient;
+    private ExecutorService executorService= Executors.newFixedThreadPool(1);
+    private List clientTasks = Collections.synchronizedList(new ArrayList());
+
+    @PostConstruct
+    void init() {
+
+    }
+
+    public void run() {
+        log.info("VdsCommClientService.run: Start.");
+
+        this.vdsClient = new NettyTcpClient(vdsConfig.getIpAddress(), vdsConfig.getPort(), vdsConfig.getReconnectTime(), new NettyTcpClientBootstrapFactory(1, 5));
+        this.clientTasks.add(this.vdsClient);
+        try {
+            List<Future> futures = this.executorService.invokeAll(this.clientTasks);
+            log.info("VdsCommClientService.run: {}", futures);
+        } catch(InterruptedException e) {
+            log.error("Exception: {}", e.getMessage());
+        }
+
+        log.info("===============================================================");
+        log.info("=  VDS Communication Client Start.......................");
+        log.info("=  ipAddress: {}", vdsConfig.getIpAddress());
+        log.info("=       port: {}", vdsConfig.getPort());
+        log.info("===============================================================");
+
+        log.info("VdsCommClientService.run: ..End. {}", toString());
+    }
+
+    public boolean isConnected() {
+        return (this.vdsClient.getChannel() != null) && (this.vdsClient.getChannel().isActive());
+    }
+
+
+}

+ 52 - 4
src/main/java/com/its/api/xnetudp/CenterCommUdpServer.java

@@ -1,8 +1,12 @@
 package com.its.api.xnetudp;
 
 import com.its.api.config.CenterCommConfig;
+import com.its.api.config.VmsConfig;
+import com.its.api.its.model.dto.vms.VmsControlDto;
 import com.its.api.xnetudp.codec.CenterCommServerDecoder;
 import com.its.api.xnetudp.handler.CenterCommServerPacketHandler;
+import com.its.api.xnetudp.protocol.CENTER_COMM_DEFINE;
+import com.its.api.xnetudp.protocol.CENTER_COMM_MESSAGE;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.*;
 import io.netty.channel.nio.NioEventLoopGroup;
@@ -18,6 +22,7 @@ import org.springframework.stereotype.Component;
 @Component
 public class CenterCommUdpServer {
 
+    private final VmsConfig vmsConfig;
     private final CenterCommConfig serverConfig;
 
     private EventLoopGroup nioEventLoopGroup;
@@ -25,7 +30,7 @@ public class CenterCommUdpServer {
     private boolean isThreadRunning = false;
 
     public void run() {
-        log.info("UdpServerCenterComm.init: Start.");
+        log.info("UdpServerCenterComm.run: Start.");
 
         try {
             this.nioEventLoopGroup = new NioEventLoopGroup();
@@ -47,7 +52,7 @@ public class CenterCommUdpServer {
             });
         }
         catch (Exception e) {
-            this.log.error("UdpServerCenterComm.init: Exception: {}", e.toString());
+            this.log.error("UdpServerCenterComm.run: Exception: {}", e.toString());
         }
 
         log.info("===============================================================");
@@ -76,7 +81,7 @@ public class CenterCommUdpServer {
         }
         catch (Exception e) {
             e.printStackTrace();
-            log.error("UdpServerCenterComm.init: Bind Exception: {}", e.toString());
+            log.error("UdpServerCenterComm.run: Bind Exception: {}", e.toString());
             if (!isThreadRunning) {
                 this.nioEventLoopGroup.shutdownGracefully();
             }
@@ -86,7 +91,50 @@ public class CenterCommUdpServer {
                 this.nioEventLoopGroup.shutdownGracefully();
             }
         }
-        log.info("UdpServerCenterComm.init: ..End. {}", toString());
+        log.info("UdpServerCenterComm.run: ..End. {}", toString());
     }
 
+    /**
+     * VMS 서버로 리셋 명령 전송
+     * @param id
+     * @param req
+     * @return
+     */
+    public boolean requestReset(Long id, VmsControlDto.VmsControlReq req) {
+        byte msgSeq = (byte)0x20;
+        int reqSize = CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME + CENTER_COMM_DEFINE.INT_VMS_MAX_ID + CENTER_COMM_DEFINE.INT_VMS_MAX_OPER_ID;
+        int length = reqSize + 1;
+        CENTER_COMM_MESSAGE commMsg = new CENTER_COMM_MESSAGE(CENTER_COMM_DEFINE.INT_ID_VMS_SERVER, CENTER_COMM_DEFINE.INT_OP_VMS_RESET, length, msgSeq);
+        return true;
+    }
+
+    /**
+     * VMS 서버로 전광판 On/Off 명령 전송
+     * @param id
+     * @param req
+     * @return
+     */
+    public boolean requestPowerControl(Long id, VmsControlDto.VmsControlReq req) {
+        byte msgSeq = (byte)0x20;
+        int reqSize = CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME + CENTER_COMM_DEFINE.INT_VMS_MAX_ID + CENTER_COMM_DEFINE.INT_VMS_MAX_OPER_ID;
+        int length = reqSize + 1;
+        byte command = req.getValue() == 0 ? (byte)0x00 : (byte)0x01;
+        CENTER_COMM_MESSAGE commMsg = new CENTER_COMM_MESSAGE(CENTER_COMM_DEFINE.INT_ID_VMS_SERVER, CENTER_COMM_DEFINE.INT_OP_VMS_POWER_CTL, length, msgSeq);
+        return true;
+    }
+
+    /**
+     * VMS 서버로 휘도제어 명령 전송
+     * @param id
+     * @param req
+     * @return
+     */
+    public boolean controlLuminance(Long id, VmsControlDto.VmsControlReq req) {
+        byte msgSeq = (byte)0x20;
+        int reqSize = CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME + CENTER_COMM_DEFINE.INT_VMS_MAX_ID + CENTER_COMM_DEFINE.INT_VMS_MAX_OPER_ID;
+        int length = reqSize + 1;
+        byte luminance = (byte)req.getValue().intValue();
+        CENTER_COMM_MESSAGE commMsg = new CENTER_COMM_MESSAGE(CENTER_COMM_DEFINE.INT_ID_VMS_SERVER, CENTER_COMM_DEFINE.INT_OP_VMS_LUMINANCE_CTL, length, msgSeq);
+        return true;
+    }
 }

+ 2 - 1
src/main/java/com/its/api/xnetudp/protocol/CENTER_COMM_DEFINE.java

@@ -68,7 +68,8 @@ public class CENTER_COMM_DEFINE {
 
 	public static final int INT_OP_VMS_PARA_SET             = 0x25;        /* VMS 통신 서버, VMS 환경설정정보 전송 */
 	public static final int INT_OP_VMS_PARA_SET2            = 0x26;        /* VMS 통신 서버, VMS 환경설정정보 전송(For Pasig) */
-	public static final int INT_OP_VMS_RESET                = 0x27;        /* VMS 통신 서버, VMS 제어기 리셋 전송 */
+	//public static final int INT_OP_VMS_RESET                = 0x27;        /* VMS 통신 서버, VMS 제어기 리셋 전송 */
+	public static final int INT_OP_VMS_RESET                = 0x09;        /* VMS 통신 서버, VMS 제어기 리셋 전송 */
 	public static final int INT_OP_VMS_MODE                 = 0x28;        /* VMS 통신 서버, VMS 운영모드 변경 */
 	public static final int INT_OP_VMS_FORM_SAVE            = 0x0B;        /* VMS 통신 서버, 실시간 VMS 제공정보 저장 */
 	public static final int INT_OP_VMS_FORM_DOWNLOAD        = 0x0C;        /* VMS 통신 서버, 실시간 VMS 제공정보 다운로드 결과 저장 */

+ 11 - 0
src/main/resources/application-dev.yml

@@ -1,3 +1,14 @@
+application:
+  vds:
+    #ip-address: 172.16.12.32
+    ip-address: 192.168.20.93
+    port: 9901
+    reconnect-time: 30
+  vms:
+    #ip-address: 172.16.12.26
+    ip-address: 192.168.20.99
+    port: 3001
+
 spring:
   resources:
     static-locations: file:src/main/resources/static/

+ 12 - 4
src/main/resources/application.yml

@@ -10,6 +10,14 @@ application:
   job:
     cctv-preset: false
 
+  vds:
+    ip-address: 172.16.12.32
+    port: 9901
+    reconnect-time: 30
+  vms:
+    ip-address: 172.16.12.26
+    port: 3001
+
 server:
   port: 8999
   shutdown: graceful
@@ -41,13 +49,13 @@ spring:
   jpa:
     #database: Oracle
     open-in-view: false
-    show-sql: true
+    show-sql: false
     hibernate:
       ddl-auto: none
     properties:
       hibernate:
-        format_sql: true
-        use_sql_columns: true
+        format_sql: false
+        use_sql_columns: false
         hbm2ddl.auto: validate
         implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
         physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
@@ -68,4 +76,4 @@ logging:
         type:
           descriptor:
             sql:
-              BasicBinder: TRACE
+              BasicBinder: OFF

+ 2 - 2
src/test/java/com/its/op/ItsOpServerApplicationTests.java

@@ -1,14 +1,13 @@
 package com.its.op;
 
 import lombok.extern.slf4j.Slf4j;
-import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 
 @Slf4j
 @SpringBootTest
 public class ItsOpServerApplicationTests {
 
-    @Test
+    //@Test
     void test1() {
         for (int ii = 0; ii < 24; ii++) {
             for (int jj = 0; jj < 12; jj++) {
@@ -26,4 +25,5 @@ public class ItsOpServerApplicationTests {
         log.error("compareTo: {}", svcDt.compareTo(prcsDt));
     }
 
+
 }

+ 0 - 125
src/test/java/com/its/op/TbIfscVrtxArrEntity.java

@@ -1,125 +0,0 @@
-package com.its.op;
-
-import javax.persistence.*;
-import java.math.BigDecimal;
-import java.util.Objects;
-
-@Entity
-@Table(name = "TB_IFSC_VRTX_ARR", schema = "YIITS", catalog = "")
-@IdClass(TbIfscVrtxArrEntityPK.class)
-public class TbIfscVrtxArrEntity {
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Id
-    @Column(name = "IFSC_ID", nullable = false, precision = 0)
-    private int ifscId;
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Id
-    @Column(name = "LEVL", nullable = false, precision = 0)
-    private int levl;
-    @Basic
-    @Column(name = "CRDN_CNT", nullable = true, precision = 0)
-    private Integer crdnCnt;
-    @Basic
-    @Column(name = "X_CRDN_ARR", nullable = true, length = 4000)
-    private String xCrdnArr;
-    @Basic
-    @Column(name = "Y_CRDN_ARR", nullable = true, length = 4000)
-    private String yCrdnArr;
-    @Basic
-    @Column(name = "X_CRDN_MIN", nullable = true, precision = 8)
-    private BigDecimal xCrdnMin;
-    @Basic
-    @Column(name = "X_CRDN_MAX", nullable = true, precision = 8)
-    private BigDecimal xCrdnMax;
-    @Basic
-    @Column(name = "Y_CRDN_MIN", nullable = true, precision = 8)
-    private BigDecimal yCrdnMin;
-    @Basic
-    @Column(name = "Y_CRDN_MAX", nullable = true, precision = 8)
-    private BigDecimal yCrdnMax;
-
-    public int getIfscId() {
-        return ifscId;
-    }
-
-    public void setIfscId(int ifscId) {
-        this.ifscId = ifscId;
-    }
-
-    public int getLevl() {
-        return levl;
-    }
-
-    public void setLevl(int levl) {
-        this.levl = levl;
-    }
-
-    public Integer getCrdnCnt() {
-        return crdnCnt;
-    }
-
-    public void setCrdnCnt(Integer crdnCnt) {
-        this.crdnCnt = crdnCnt;
-    }
-
-    public String getxCrdnArr() {
-        return xCrdnArr;
-    }
-
-    public void setxCrdnArr(String xCrdnArr) {
-        this.xCrdnArr = xCrdnArr;
-    }
-
-    public String getyCrdnArr() {
-        return yCrdnArr;
-    }
-
-    public void setyCrdnArr(String yCrdnArr) {
-        this.yCrdnArr = yCrdnArr;
-    }
-
-    public BigDecimal getxCrdnMin() {
-        return xCrdnMin;
-    }
-
-    public void setxCrdnMin(BigDecimal xCrdnMin) {
-        this.xCrdnMin = xCrdnMin;
-    }
-
-    public BigDecimal getxCrdnMax() {
-        return xCrdnMax;
-    }
-
-    public void setxCrdnMax(BigDecimal xCrdnMax) {
-        this.xCrdnMax = xCrdnMax;
-    }
-
-    public BigDecimal getyCrdnMin() {
-        return yCrdnMin;
-    }
-
-    public void setyCrdnMin(BigDecimal yCrdnMin) {
-        this.yCrdnMin = yCrdnMin;
-    }
-
-    public BigDecimal getyCrdnMax() {
-        return yCrdnMax;
-    }
-
-    public void setyCrdnMax(BigDecimal yCrdnMax) {
-        this.yCrdnMax = yCrdnMax;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        TbIfscVrtxArrEntity that = (TbIfscVrtxArrEntity) o;
-        return ifscId == that.ifscId && levl == that.levl && Objects.equals(crdnCnt, that.crdnCnt) && Objects.equals(xCrdnArr, that.xCrdnArr) && Objects.equals(yCrdnArr, that.yCrdnArr) && Objects.equals(xCrdnMin, that.xCrdnMin) && Objects.equals(xCrdnMax, that.xCrdnMax) && Objects.equals(yCrdnMin, that.yCrdnMin) && Objects.equals(yCrdnMax, that.yCrdnMax);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(ifscId, levl, crdnCnt, xCrdnArr, yCrdnArr, xCrdnMin, xCrdnMax, yCrdnMin, yCrdnMax);
-    }
-}

+ 0 - 48
src/test/java/com/its/op/TbIfscVrtxArrEntityPK.java

@@ -1,48 +0,0 @@
-package com.its.op;
-
-import javax.persistence.Column;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import java.io.Serializable;
-import java.util.Objects;
-
-public class TbIfscVrtxArrEntityPK implements Serializable {
-    @Column(name = "IFSC_ID", nullable = false, precision = 0)
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private int ifscId;
-    @Column(name = "LEVL", nullable = false, precision = 0)
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private int levl;
-
-    public int getIfscId() {
-        return ifscId;
-    }
-
-    public void setIfscId(int ifscId) {
-        this.ifscId = ifscId;
-    }
-
-    public int getLevl() {
-        return levl;
-    }
-
-    public void setLevl(int levl) {
-        this.levl = levl;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        TbIfscVrtxArrEntityPK that = (TbIfscVrtxArrEntityPK) o;
-        return ifscId == that.ifscId && levl == that.levl;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(ifscId, levl);
-    }
-}

+ 0 - 125
src/test/java/com/its/op/TbRoadVrtxArrEntity.java

@@ -1,125 +0,0 @@
-package com.its.op;
-
-import javax.persistence.*;
-import java.math.BigDecimal;
-import java.util.Objects;
-
-@Entity
-@Table(name = "TB_ROAD_VRTX_ARR", schema = "YIITS", catalog = "")
-@IdClass(TbRoadVrtxArrEntityPK.class)
-public class TbRoadVrtxArrEntity {
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Id
-    @Column(name = "ROAD_ID", nullable = false, precision = 0)
-    private Long roadId;
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Id
-    @Column(name = "LEVL", nullable = false, precision = 0)
-    private int levl;
-    @Basic
-    @Column(name = "CRDN_CNT", nullable = true, precision = 0)
-    private Integer crdnCnt;
-    @Basic
-    @Column(name = "X_CRDN_ARR", nullable = true, length = 4000)
-    private String xCrdnArr;
-    @Basic
-    @Column(name = "Y_CRDN_ARR", nullable = true, length = 4000)
-    private String yCrdnArr;
-    @Basic
-    @Column(name = "X_CRDN_MIN", nullable = true, precision = 8)
-    private BigDecimal xCrdnMin;
-    @Basic
-    @Column(name = "X_CRDN_MAX", nullable = true, precision = 8)
-    private BigDecimal xCrdnMax;
-    @Basic
-    @Column(name = "Y_CRDN_MIN", nullable = true, precision = 8)
-    private BigDecimal yCrdnMin;
-    @Basic
-    @Column(name = "Y_CRDN_MAX", nullable = true, precision = 8)
-    private BigDecimal yCrdnMax;
-
-    public Long getRoadId() {
-        return roadId;
-    }
-
-    public void setRoadId(Long roadId) {
-        this.roadId = roadId;
-    }
-
-    public int getLevl() {
-        return levl;
-    }
-
-    public void setLevl(int levl) {
-        this.levl = levl;
-    }
-
-    public Integer getCrdnCnt() {
-        return crdnCnt;
-    }
-
-    public void setCrdnCnt(Integer crdnCnt) {
-        this.crdnCnt = crdnCnt;
-    }
-
-    public String getxCrdnArr() {
-        return xCrdnArr;
-    }
-
-    public void setxCrdnArr(String xCrdnArr) {
-        this.xCrdnArr = xCrdnArr;
-    }
-
-    public String getyCrdnArr() {
-        return yCrdnArr;
-    }
-
-    public void setyCrdnArr(String yCrdnArr) {
-        this.yCrdnArr = yCrdnArr;
-    }
-
-    public BigDecimal getxCrdnMin() {
-        return xCrdnMin;
-    }
-
-    public void setxCrdnMin(BigDecimal xCrdnMin) {
-        this.xCrdnMin = xCrdnMin;
-    }
-
-    public BigDecimal getxCrdnMax() {
-        return xCrdnMax;
-    }
-
-    public void setxCrdnMax(BigDecimal xCrdnMax) {
-        this.xCrdnMax = xCrdnMax;
-    }
-
-    public BigDecimal getyCrdnMin() {
-        return yCrdnMin;
-    }
-
-    public void setyCrdnMin(BigDecimal yCrdnMin) {
-        this.yCrdnMin = yCrdnMin;
-    }
-
-    public BigDecimal getyCrdnMax() {
-        return yCrdnMax;
-    }
-
-    public void setyCrdnMax(BigDecimal yCrdnMax) {
-        this.yCrdnMax = yCrdnMax;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        TbRoadVrtxArrEntity that = (TbRoadVrtxArrEntity) o;
-        return levl == that.levl && Objects.equals(roadId, that.roadId) && Objects.equals(crdnCnt, that.crdnCnt) && Objects.equals(xCrdnArr, that.xCrdnArr) && Objects.equals(yCrdnArr, that.yCrdnArr) && Objects.equals(xCrdnMin, that.xCrdnMin) && Objects.equals(xCrdnMax, that.xCrdnMax) && Objects.equals(yCrdnMin, that.yCrdnMin) && Objects.equals(yCrdnMax, that.yCrdnMax);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(roadId, levl, crdnCnt, xCrdnArr, yCrdnArr, xCrdnMin, xCrdnMax, yCrdnMin, yCrdnMax);
-    }
-}

+ 0 - 48
src/test/java/com/its/op/TbRoadVrtxArrEntityPK.java

@@ -1,48 +0,0 @@
-package com.its.op;
-
-import javax.persistence.Column;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import java.io.Serializable;
-import java.util.Objects;
-
-public class TbRoadVrtxArrEntityPK implements Serializable {
-    @Column(name = "ROAD_ID", nullable = false, precision = 0)
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long roadId;
-    @Column(name = "LEVL", nullable = false, precision = 0)
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private int levl;
-
-    public Long getRoadId() {
-        return roadId;
-    }
-
-    public void setRoadId(Long roadId) {
-        this.roadId = roadId;
-    }
-
-    public int getLevl() {
-        return levl;
-    }
-
-    public void setLevl(int levl) {
-        this.levl = levl;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        TbRoadVrtxArrEntityPK that = (TbRoadVrtxArrEntityPK) o;
-        return levl == that.levl && Objects.equals(roadId, that.roadId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(roadId, levl);
-    }
-}