diff --git a/lib/tibero-jdbc-7.0.0.jar b/lib/tibero-jdbc-7.0.0.jar new file mode 100644 index 0000000..69b9029 Binary files /dev/null and b/lib/tibero-jdbc-7.0.0.jar differ diff --git a/pom.xml b/pom.xml index cb60256..b8157a6 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,12 @@ spring-boot-starter-data-elasticsearch + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 3.0.0 + + org.projectlombok lombok @@ -58,10 +64,24 @@ + org.locationtech.jts + jts-core + 1.19.0 + + + + com.tmax.tibero + tibero-jdbc + 7 + system + ${basedir}/lib/tibero-jdbc-7.0.0.jar + + + + + diff --git a/src/main/java/kr/gmtc/gw/elastic/ESApplication.java b/src/main/java/kr/gmtc/gw/elastic/ESApplication.java index 03ff435..71d8f63 100644 --- a/src/main/java/kr/gmtc/gw/elastic/ESApplication.java +++ b/src/main/java/kr/gmtc/gw/elastic/ESApplication.java @@ -1,13 +1,17 @@ package kr.gmtc.gw.elastic; import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.context.ApplicationPidFileWriter; import org.springframework.boot.system.ApplicationHome; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @SpringBootApplication +@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class}) public class ESApplication { public static void main(String[] args) { diff --git a/src/main/java/kr/gmtc/gw/elastic/config/AppConfig.java b/src/main/java/kr/gmtc/gw/elastic/config/AppConfig.java new file mode 100644 index 0000000..a65ab78 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/config/AppConfig.java @@ -0,0 +1,11 @@ +package kr.gmtc.gw.elastic.config; + +import java.util.Map; +import java.util.Queue; + +public class AppConfig { + + + + +} diff --git a/src/main/java/kr/gmtc/gw/elastic/config/DataSourceConfigDB1.java b/src/main/java/kr/gmtc/gw/elastic/config/DataSourceConfigDB1.java new file mode 100644 index 0000000..1076a16 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/config/DataSourceConfigDB1.java @@ -0,0 +1,54 @@ +package kr.gmtc.gw.elastic.config; + +import javax.sql.DataSource; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +@Configuration +@MapperScan(value = "kr.gmtc.gw.elastic.mapper", sqlSessionFactoryRef = "factory") +public class DataSourceConfigDB1 { + + @Primary + @Bean(name = "datasource") + @ConfigurationProperties(prefix = "database.db1.datasource") + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Primary + @Bean(name = "factory") + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { + SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); + sqlSessionFactory.setDataSource(dataSource); + + Resource[] res = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/DB1.xml"); + sqlSessionFactory.setMapperLocations(res); + + return sqlSessionFactory.getObject(); + } + + @Primary + @Bean(name="SqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception{ + return new SqlSessionTemplate(sqlSessionFactory); + } + + @Primary + @Bean + public DataSourceTransactionManager ATransactionManager(DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + +} + diff --git a/src/main/java/kr/gmtc/gw/elastic/config/ElasticsearchClientConfig.java b/src/main/java/kr/gmtc/gw/elastic/config/ElasticsearchClientConfig.java index 4e5010a..ed4f015 100644 --- a/src/main/java/kr/gmtc/gw/elastic/config/ElasticsearchClientConfig.java +++ b/src/main/java/kr/gmtc/gw/elastic/config/ElasticsearchClientConfig.java @@ -1,13 +1,17 @@ package kr.gmtc.gw.elastic.config; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.data.elasticsearch.client.ClientConfiguration; -import org.springframework.data.elasticsearch.client.RestClients; import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; @Configuration //@EnableElasticsearchRepositories(basePackages = "kr.gmtc.gw.elk.repositories") @@ -18,19 +22,44 @@ public class ElasticsearchClientConfig extends AbstractElasticsearchConfiguratio private String gsEsHost; @Value("${app.config.elastic.port}") - private String gsEsPort; + private int gsEsPort; + + // @Override + // @Bean(destroyMethod = "close") + // public RestHighLevelClient elasticsearchClient() { + // final ClientConfiguration clientConfiguration = + // ClientConfiguration + // .builder() + // .connectedTo(gsEsHost + ":" + gsEsPort) + // //.connectedTo( "10.200.31.129:9200") + // .build(); + + // return RestClients.create(clientConfiguration).rest(); + // } @Override @Bean(destroyMethod = "close") public RestHighLevelClient elasticsearchClient() { - final ClientConfiguration clientConfiguration = - ClientConfiguration - .builder() - .connectedTo(gsEsHost + ":" + gsEsPort) - //.connectedTo( "10.200.31.129:9200") - .build(); - return RestClients.create(clientConfiguration).rest(); + RestClientBuilder builder = RestClient.builder( + new HttpHost(gsEsHost, gsEsPort)) + .setRequestConfigCallback( + new RestClientBuilder.RequestConfigCallback() { + @Override + public RequestConfig.Builder customizeRequestConfig( + RequestConfig.Builder requestConfigBuilder) { + return requestConfigBuilder + .setConnectTimeout(5000) + .setSocketTimeout(60000); + } + }); + + return new RestHighLevelClient(builder); + } + + @Bean + public ElasticsearchOperations esTemplate() { + return new ElasticsearchRestTemplate(elasticsearchClient()); } } diff --git a/src/main/java/kr/gmtc/gw/elastic/config/QueueManageBean.java b/src/main/java/kr/gmtc/gw/elastic/config/QueueManageBean.java new file mode 100644 index 0000000..2c1c1c7 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/config/QueueManageBean.java @@ -0,0 +1,23 @@ +package kr.gmtc.gw.elastic.config; + +import java.util.Map; +import java.util.Queue; + +public class QueueManageBean { + + private Map> replayLogQ; + + public void setQue(String qid, Queue que){ + replayLogQ.put(qid, que) ; + } + + public Queue getQue(String qid){ + + return replayLogQ.get(qid); + } + + + + + +} diff --git a/src/main/java/kr/gmtc/gw/elastic/controller/AeraSchduler.java b/src/main/java/kr/gmtc/gw/elastic/controller/AeraSchduler.java new file mode 100644 index 0000000..0acf756 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/controller/AeraSchduler.java @@ -0,0 +1,238 @@ +package kr.gmtc.gw.elastic.controller; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.Point; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import co.elastic.clients.elasticsearch.ml.get_calendars.Calendar; +import kr.gmtc.gw.comp.thread.CustomThread; +import kr.gmtc.gw.elastic.services.AeraService; +import kr.gmtc.gw.elastic.services.ElkSearchService; +import kr.gmtc.gw.elastic.vo.AnalyzeArea.Area; +import kr.gmtc.gw.elastic.vo.ReplayLog.FusionVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; + +@Component("aeraSchduler") +public class AeraSchduler implements ApplicationListener { + + @Autowired + private ElkSearchService elkSearchService; + + private AeraService aeraService; + + private List getDBdataThreads; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private int areaSelectInterval = 10 * (60 * 1000); + private int analyzeOnAreaInterval = 1 * (60 * 1000); + + private final GeometryFactory gf = new GeometryFactory(); + + private Map mapTaxiway = new ConcurrentHashMap(); + + private Queue parserFusionQ = new LinkedBlockingQueue(); + + private LocalDateTime procBeforeDT; + + public AeraSchduler(AeraService aeraService){ + this.aeraService = aeraService; + } + + @Order(0) + @EventListener(ApplicationReadyEvent.class) + public void initialize() { + try { + + // 업무 스래드(프로시저 호출) + getDBdataThreads = new ArrayList(); + + getDBdataThreads.add(new CustomThread("selectAeraList", this, areaSelectInterval, this::selectAeraList, null, false)); + getDBdataThreads.add(new CustomThread("analyzeOnArea", this, analyzeOnAreaInterval, this::analyzeOnArea, null, false)); + + } catch (Exception e) { + logger.error("MainContoller-Thread create fail"); + System.exit(1); + } + } + + /** + * 실행 (2순위)
+ * 프로그램 실행 + */ + @Order(1) + @EventListener(ApplicationReadyEvent.class) + public void start() { + try { + + logger.info("MainContoller-Thread start"); + + for(CustomThread ct : getDBdataThreads ){ + ct.start(); + } + + } catch (Exception e) { + logger.error("MainContoller-Thread start fail"); + System.exit(1); + } + } + + /** 종료 처리 */ + public void stop() { + + for(CustomThread ct : getDBdataThreads ){ + ct.gracefulStop(); + } + + } + + private void analyzeOnArea(){ + + if(mapTaxiway.size() == 0) selectAeraList(); + + if(searchElastic().equals("OK")) { + + checkArea(); + + } + + } + + + private void selectAeraList(){ + + // List> getAeraList = aeraService.getAeraListMap(); + + // Map>> groupedAreas = aeraService.groupAreasByID(getAeraList); + + List areaList = aeraService.getAeraList(); + + mapTaxiway.clear(); + areaList.forEach(area -> mapTaxiway.put(area.getId(), area)); + mapTaxiway.forEach((id, area) -> area.generateLineToBufferedPolygon(10)); + + String asdfa = "asdfadf"; + } + + private String searchElastic(){ + + String sIndex = "3"; + String sStartDt, sEndDt; + + // TODO : DB table 시각 가져오기, file저장 + if(procBeforeDT == null ){ + procBeforeDT = LocalDateTime.now().minusMinutes(10); + } + + LocalDateTime currentDT = LocalDateTime.now(); + + sStartDt = procBeforeDT.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS")); + sEndDt = currentDT.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS")); + + procBeforeDT = currentDT; + + String searchRes = elkSearchService.searchFusion(parserFusionQ, sIndex, sStartDt, sEndDt); + + if(searchRes.equals("OK")){ + logger.info("Elastic 데이터 조회 완료"); + } + + return searchRes; + + } + + public void checkArea(){ + + + for(LogMsgParserVO logVO : parserFusionQ ){ + + for(int idx = 0; idx < logVO.getData().size(); idx ++ ){ + + List fList = (List) logVO.getData(); + + for(FusionVO fVO : fList){ + + double dLon = Double.parseDouble(fVO.getLon()); + double dLat = Double.parseDouble(fVO.getLat()); + // AeraSchduler as = new AeraSchduler( new AeraService() ); + List areaList = checkPositionInTaxiway(dLon, dLat); + + if (!areaList.isEmpty()){ + + + + } + + } + + } + + } + + } + + + public List checkPositionInTaxiway(double lon, double lat) { + + List useTwyList = new ArrayList<>(); + + Point point = gf.createPoint(new Coordinate(lon, lat)); + + try { + + if (point == null) { + throw new NullPointerException("Point param is null"); + } + + for (Area area : mapTaxiway.values()) { + // result = result || area.isContains(point); + + if(area.isContains(point)){ + useTwyList.add(area.getId()); + } + + } + + } catch (RuntimeException e) { + logger.error("[checkPositionInTaxiway] is generate runtime error ", e); + return useTwyList; + } catch(Exception e) { + logger.error("[checkPositionInTaxiway] is fatal error ", e); + return useTwyList; + } + + return useTwyList; + } + + @Override + public void onApplicationEvent(ContextClosedEvent event) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'onApplicationEvent'"); + } + + + + + + + +} diff --git a/src/main/java/kr/gmtc/gw/elastic/mapper/AeraMapper.java b/src/main/java/kr/gmtc/gw/elastic/mapper/AeraMapper.java new file mode 100644 index 0000000..146274d --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/mapper/AeraMapper.java @@ -0,0 +1,17 @@ +package kr.gmtc.gw.elastic.mapper; + +import java.util.HashMap; +import java.util.List; + +import org.apache.ibatis.annotations.Mapper; + +import kr.gmtc.gw.elastic.vo.AnalyzeArea.Area; + +@Mapper +public interface AeraMapper { + + List> selectAeraListMap(); + + List selectAeraList(); + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserAade.java b/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserAade.java index 09d6313..2bb9dee 100644 --- a/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserAade.java +++ b/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserAade.java @@ -6,10 +6,10 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import kr.gmtc.gw.elastic.utils.LogMsgParserUtile; -import kr.gmtc.gw.elastic.vo.ElasticMsgHeader; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; -import kr.gmtc.gw.elastic.vo.LogMsgParserVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; import kr.gmtc.gw.elastic.vo.ReplayLog.AsdeVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandardRouteVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandardRouteVO.RoutePoints; diff --git a/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserRadar.java b/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserRadar.java index 794765b..42c8c9c 100644 --- a/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserRadar.java +++ b/src/main/java/kr/gmtc/gw/elastic/parser/logingIndex/ParserRadar.java @@ -6,9 +6,9 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import kr.gmtc.gw.elastic.utils.LogMsgParserUtile; -import kr.gmtc.gw.elastic.vo.ElasticMsgHeader; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; -import kr.gmtc.gw.elastic.vo.LogMsgParserVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; import kr.gmtc.gw.elastic.vo.ReplayLog.RadarVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandardRouteVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandardRouteVO.RoutePoints; diff --git a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAILocation.java b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAILocation.java index 704c609..373be21 100644 --- a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAILocation.java +++ b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAILocation.java @@ -6,10 +6,10 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import kr.gmtc.gw.elastic.utils.LogMsgParserUtile; -import kr.gmtc.gw.elastic.vo.ElasticMsgHeader; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; -import kr.gmtc.gw.elastic.vo.LogMsgParserVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; import kr.gmtc.gw.elastic.vo.ReplayLog.AiLocationVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; public class ParserAILocation { diff --git a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAna.java b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAna.java index 9c1822b..2271557 100644 --- a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAna.java +++ b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserAna.java @@ -6,10 +6,10 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import kr.gmtc.gw.elastic.utils.LogMsgParserUtile; -import kr.gmtc.gw.elastic.vo.ElasticMsgHeader; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; -import kr.gmtc.gw.elastic.vo.LogMsgParserVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; import kr.gmtc.gw.elastic.vo.ReplayLog.AnaVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; import kr.gmtc.gw.elastic.vo.ReplayLog.AnaVO.Area; import kr.gmtc.gw.elastic.vo.ReplayLog.AnaVO.Target; diff --git a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserFusion.java b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserFusion.java index 45ee5ae..f24c3b0 100644 --- a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserFusion.java +++ b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserFusion.java @@ -5,11 +5,12 @@ import java.util.List; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; +import kr.gmtc.gw.elastic.controller.AeraSchduler; import kr.gmtc.gw.elastic.utils.LogMsgParserUtile; -import kr.gmtc.gw.elastic.vo.ElasticMsgHeader; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; -import kr.gmtc.gw.elastic.vo.LogMsgParserVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; import kr.gmtc.gw.elastic.vo.ReplayLog.FusionVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; import kr.gmtc.gw.elastic.vo.ReplayLog.FusionVO.BoundingBox; @@ -17,12 +18,14 @@ public class ParserFusion { private List logMsgs; - Queue parserAiLocQ = new LinkedBlockingQueue(); + Queue parserFusionQ = new LinkedBlockingQueue(); LogMsgParserUtile pUtile; - - public ParserFusion(){ + AeraSchduler areaSc; + + public ParserFusion(Queue parserFusionQ){ + this.parserFusionQ = parserFusionQ; pUtile = new LogMsgParserUtile(); } @@ -31,7 +34,7 @@ public class ParserFusion { this.logMsgs = recvMsgs; - List parserList = new ArrayList(); + List parserList; FusionVO parserVO; BoundingBox bBox; @@ -43,6 +46,8 @@ public class ParserFusion { String sMsg = mv.getMessage(); + parserList = new ArrayList(); + logVO = new LogMsgParserVO(); /*** 메시지 Pipe(|) 구분 ***/ @@ -90,39 +95,44 @@ public class ParserFusion { parserVO.setLon(split_Field[3]); parserVO.setSpd(split_Field[4]); parserVO.setCos(split_Field[5]); - parserVO.setAlt(split_Field[6]); - parserVO.setTrgt_ty(split_Field[7]); - parserVO.setSchdul_id(split_Field[8]); + parserVO.setTrgt_ty(split_Field[6]); + parserVO.setCrrct_lat(split_Field[7]); + parserVO.setCrrct_lon(split_Field[8]); parserVO.setMode_s_cd(split_Field[9]); parserVO.setSsr_cd(split_Field[10]); parserVO.setClsgn(split_Field[11]); parserVO.setTail_no(split_Field[12]); - parserVO.setCrrct_lat(split_Field[13]); - parserVO.setCrrct_lon(split_Field[14]); - parserVO.setIs_cntrlzone(split_Field[15]); parserVO.setBbox(new ArrayList()); // bbox 담기 - String[] split_List = pUtile.splitString(split_Field[17], pUtile.DIV_DOLLAR); + String[] split_List = pUtile.splitString(split_Field[13], pUtile.DIV_DOLLAR); - for(String loopList : split_List){ + if(!split_List[0].equals("")) { - bBox = new BoundingBox(); + for(String loopList : split_List){ - String[] split_Array = pUtile.splitString(loopList, pUtile.DIV_AT); - - bBox.setLt_x(split_Array[0]); - bBox.setLt_y(split_Array[1]); - bBox.setRb_x(split_Array[2]); - bBox.setRb_y(split_Array[3]); - bBox.setPx(split_Array[4]); - bBox.setPy(split_Array[5]); - - parserVO.getBbox().add(bBox); + bBox = new BoundingBox(); + + String[] split_Array = pUtile.splitString(loopList, pUtile.DIV_AT); + + bBox.setLt_x(split_Array[0]); + bBox.setLt_y(split_Array[1]); + bBox.setRb_x(split_Array[2]); + bBox.setRb_y(split_Array[3]); + bBox.setPx(split_Array[4]); + bBox.setPy(split_Array[5]); + + parserVO.getBbox().add(bBox); + + } } + parserVO.setAlt(split_Field[14]); + parserVO.setSchdul_id(split_Field[15]); + parserVO.setIs_cntrlzone(split_Field[16]); + parserList.add(parserVO); } /**** Data부 한줄씩 처리 END ****/ @@ -131,15 +141,10 @@ public class ParserFusion { /*** 메시지 data(body) 변환 END ***/ // Que에 파싱 데이터 담기 - parserAiLocQ.offer(logVO) ; + parserFusionQ.offer(logVO) ; } // for( ElasticResultMsgVO mv : logMsgs){... END - - } - - - } diff --git a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserRoute.java b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserRoute.java index e092f59..51373ea 100644 --- a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserRoute.java +++ b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserRoute.java @@ -6,9 +6,9 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import kr.gmtc.gw.elastic.utils.LogMsgParserUtile; -import kr.gmtc.gw.elastic.vo.ElasticMsgHeader; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; -import kr.gmtc.gw.elastic.vo.LogMsgParserVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandardRouteVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandardRouteVO.RoutePoints; diff --git a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserStandStatus.java b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserStandStatus.java index f8b75f2..a3a2df5 100644 --- a/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserStandStatus.java +++ b/src/main/java/kr/gmtc/gw/elastic/parser/replayLog/ParserStandStatus.java @@ -6,9 +6,9 @@ import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import kr.gmtc.gw.elastic.utils.LogMsgParserUtile; -import kr.gmtc.gw.elastic.vo.ElasticMsgHeader; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; -import kr.gmtc.gw.elastic.vo.LogMsgParserVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandStatusVO; import kr.gmtc.gw.elastic.vo.ReplayLog.StandStatusVO.StandSttusTy; import kr.gmtc.gw.elastic.vo.ReplayLog.StandardRouteVO.RoutePoints; diff --git a/src/main/java/kr/gmtc/gw/elastic/services/AeraService.java b/src/main/java/kr/gmtc/gw/elastic/services/AeraService.java new file mode 100644 index 0000000..d6de0c8 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/services/AeraService.java @@ -0,0 +1,47 @@ +package kr.gmtc.gw.elastic.services; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import kr.gmtc.gw.elastic.mapper.AeraMapper; +import kr.gmtc.gw.elastic.vo.AnalyzeArea.Area; + +@Service +public class AeraService { + + @Autowired + private AeraMapper aeraMapper; + + public List> getAeraListMap() { + return aeraMapper.selectAeraListMap(); + } + + public List getAeraList() { + return aeraMapper.selectAeraList(); + } + + + public Map>> groupAreasByID(List> areaList) { + Map>> groupedAreas = new HashMap<>(); + + for (HashMap area : areaList) { + String areaId = (String) area.get("AREA_ID"); + + // 해당 지역 이름에 대한 맵 엔트리가 이미 있는지 확인하고, 없으면 새로운 리스트를 생성하여 추가합니다. + if (!groupedAreas.containsKey(areaId)) { + groupedAreas.put(areaId, new ArrayList<>()); + } + + // 해당 지역 이름에 해당하는 리스트를 가져와서 현재 지역 정보를 추가합니다. + groupedAreas.get(areaId).add(area); + } + + return groupedAreas; + } + +} diff --git a/src/main/java/kr/gmtc/gw/elastic/services/ElkSearchService.java b/src/main/java/kr/gmtc/gw/elastic/services/ElkSearchService.java index 4569cdf..0c433ec 100644 --- a/src/main/java/kr/gmtc/gw/elastic/services/ElkSearchService.java +++ b/src/main/java/kr/gmtc/gw/elastic/services/ElkSearchService.java @@ -4,9 +4,11 @@ import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Queue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHits; @@ -16,12 +18,10 @@ import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.stereotype.Service; -import kr.gmtc.gw.elastic.parser.logingIndex.ParserAade; -import kr.gmtc.gw.elastic.parser.replayLog.ParserAILocation; -import kr.gmtc.gw.elastic.parser.replayLog.ParserAna; +import kr.gmtc.gw.elastic.controller.AeraSchduler; import kr.gmtc.gw.elastic.parser.replayLog.ParserFusion; -import kr.gmtc.gw.elastic.parser.replayLog.ParserRoute; -import kr.gmtc.gw.elastic.vo.ElasticResultMsgVO; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticResultMsgVO; +import kr.gmtc.gw.elastic.vo.ReplayLog.LogMsgParserVO; @Service public class ElkSearchService { @@ -41,7 +41,7 @@ public class ElkSearchService { logMsgMatches = new ArrayList(); //logParser = new ReplayLogParser_Route(); - logParser = new ParserFusion(); + //logParser = new ParserFusion(areaSc); } public String elkSearch_replay_log(String sLogType, String sStartDt, String sEndDt) { @@ -109,6 +109,73 @@ public class ElkSearchService { return "OK"; } + + + + public String searchFusion(Queue parserFusionQ, String sLogType, String sStartDt, String sEndDt) { + + ParserFusion psFusion = new ParserFusion(parserFusionQ); + + List sAfter = null; // 일시(to) + + //logMsgMatches = new ArrayList(); + + String esQuery = "{ " + // + " \"bool\" : { " + // + " \"filter\" : [ " + // + " { \"terms\" : { " + // + " \"header.msg_type.keyword\" : [ " + // + " "+ sLogType +" ] } }, " + // + " { \"range\" : { " + // + " \"header.recv_time\" : { " + // + " \"from\" : \""+ sStartDt +"\", " + // + " \"to\" : \""+ sEndDt +"\" } } } ] } " + // + "}"; + + Query searchQuery = new StringQuery(esQuery); + + // 한번에 가져올 row수 설정 + ((BaseQuery) searchQuery).setMaxResults(1000); + + // 데이터 정렬할 필드 설정 + searchQuery.addSort(Sort.by(new Sort.Order(Sort.Direction.ASC, "header.recv_time.keyword"))); + + LocalDateTime dt_before = LocalDateTime.now(); + + while (true) { + + searchQuery.setSearchAfter(sAfter); + + // 검색 요청하여 검색 결과 가져오기 + SearchHits searchHits = elasticsearchOperations.search(searchQuery, ElasticResultMsgVO.class, IndexCoordinates.of(INDEX_NAME)); + + if (searchHits.getTotalHits() <= 0) break; + + Duration diff = Duration.between(dt_before, LocalDateTime.now()); + + logger.info("elastic Call " + searchHits.getTotalHits() + "건 " + diff.toMillis() + "msec"); + + sAfter = searchHits.toList().get(searchHits.toList().size() -1).getSortValues(); + + // IndexFusion Object에 데이터 담기 + searchHits.forEach(srcHit -> { + logMsgMatches.add(srcHit.getContent()); + }); + + + logger.info("map cnt " + logMsgMatches.size() + "건 " ); + + if (searchHits.toList().size() != 1000) { + psFusion.logParser(logMsgMatches); + break; + } + + } + + + return "OK"; + } + } diff --git a/src/main/java/kr/gmtc/gw/elastic/test/SearchController.java b/src/main/java/kr/gmtc/gw/elastic/test/SearchController.java index 07b584a..4cf265f 100644 --- a/src/main/java/kr/gmtc/gw/elastic/test/SearchController.java +++ b/src/main/java/kr/gmtc/gw/elastic/test/SearchController.java @@ -12,7 +12,7 @@ import kr.gmtc.gw.elastic.services.ElkSearchService; @RestController -@RequestMapping("/") +// @RequestMapping("/") public class SearchController { private ElkSearchService elkSearchService; @@ -23,9 +23,9 @@ public class SearchController { this.elkSearchService = elkSearchService; } - // http://localhost:8080/replay?idx=2&s=20240429145000.000&e=20240429145500.999 - @GetMapping("/replay") - @ResponseBody + // http://localhost:8080/replay?idx=3&s=20240507145000.000&e=20240507145500.999 + @GetMapping(value = "/replay") + // @ResponseBody public String processSearch_replay_loop(@RequestParam(value = "idx", required = false) String sIndex, @RequestParam(value = "s", required = false) String sStartDt, @RequestParam(value = "e", required = false) String sEndDt) { diff --git a/src/main/java/kr/gmtc/gw/elastic/utils/CommonUtils.java b/src/main/java/kr/gmtc/gw/elastic/utils/CommonUtils.java new file mode 100644 index 0000000..8bd7556 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/utils/CommonUtils.java @@ -0,0 +1,52 @@ +package kr.gmtc.gw.elastic.utils; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.util.AffineTransformation; + +public class CommonUtils { + + private static int ID_SEQ = 0; + + + public static String generateAnalysisID() { + + ID_SEQ = (ID_SEQ >= 999) ? 0 : ID_SEQ+1; + + String id = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")) + String.format("%03d", ID_SEQ); + return id; + } + + + public static String getNow() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss")); + } + + public static String getNowWithMillsecond() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss.SSS")); + } + + public static double meterOnWGS84(double meter) { + return (1 * meter) / 111000; + } + + public static Point rotatePoint(Point pointToRotate, Point rotationCenter, double angleInDegrees) { + AffineTransformation rotation = AffineTransformation.rotationInstance( + Math.toRadians(angleInDegrees), rotationCenter.getX(), rotationCenter.getY() + ); + return (Point) rotation.transform(pointToRotate); + } + + public static Coordinate rotatePoint(Coordinate pointToRotate, Coordinate rotationCenter, double angleInDegrees) { + //중심점을 기준으로 각도만큼 회전하는 변환을 생성. 양의 각도는 반시계 방향으로의 회전을 나타냄 + AffineTransformation rotation = AffineTransformation.rotationInstance( + Math.toRadians( -1 * angleInDegrees), rotationCenter.x, rotationCenter.y + ); + Coordinate dest = new Coordinate(); + return rotation.transform(pointToRotate, dest); + } + +} diff --git a/src/main/java/kr/gmtc/gw/elastic/vo/AnalyzeArea/Area.java b/src/main/java/kr/gmtc/gw/elastic/vo/AnalyzeArea/Area.java new file mode 100644 index 0000000..4e03383 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/vo/AnalyzeArea/Area.java @@ -0,0 +1,129 @@ +package kr.gmtc.gw.elastic.vo.AnalyzeArea; + +import java.util.List; + +import org.locationtech.jts.algorithm.ConvexHull; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.operation.buffer.BufferOp; +import org.locationtech.jts.operation.buffer.BufferParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.gw.elastic.utils.CommonUtils; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Area { + +// private static final GeometryFactory gf = new GeometryFactory( +// new PrecisionModel(PrecisionModel.FLOATING), +// 4326, +// CoordinateArraySequenceFactory.instance()); + private static final GeometryFactory gf = new GeometryFactory(); + private static final Logger logger = LoggerFactory.getLogger(Area.class); + + private boolean isValid = false; + private String id; + private String name; + private String areatype; + private Polygon polygon; + private List points; + + private LineString line; + + public int addPoint(AreaPoint ponit) { + try { + this.points.add(ponit); + return this.points.size(); + } catch (NullPointerException ne) { + return -1; + } catch (RuntimeException re) { + return this.points.size(); + } + } + + public void generatePolygon() { + try { + this.isValid = false; + + if (points.size() > 1) { + + AreaPoint point = null; + Coordinate[] coords = new Coordinate[points.size()+1]; + + for (int i = 0; i < points.size(); i++) { + point = points.get(i); + if (point == null) { + return; + } + coords[i] = new Coordinate(point.getLon(), point.getLat()); + } + coords[points.size()] = new Coordinate(coords[0].x, coords[0].y); + + ConvexHull convexHull = new ConvexHull(coords, gf); + Geometry convexHullGeometry = convexHull.getConvexHull(); + Coordinate[] sortedCoordinates = convexHullGeometry.getCoordinates(); + this.polygon = gf.createPolygon(sortedCoordinates); + +// LinearRing ring = gf.createLinearRing(coords); +// this.polygon = gf.createPolygon(ring); + this.isValid = true; + +// logger.info("Generated Polygon ["+ this.name +"] : " + this.polygon); + } + + } catch (RuntimeException e) { + logger.error("Polygon generated fail : ["+ this.id +"] "+ name, e); + } + } + + public void generateLineToBufferedPolygon(double bufferMeter) { + try { + this.isValid = false; + Coordinate[] coords = this.points.stream() + .map(point -> new Coordinate(point.getLon(), point.getLat())) + .toArray(i -> new Coordinate[i]); + + LineString line = gf.createLineString(coords); + this.line = gf.createLineString(coords); + + Geometry buffer = BufferOp.bufferOp(line, CommonUtils.meterOnWGS84(bufferMeter), BufferParameters.CAP_SQUARE); + this.polygon = gf.createPolygon(buffer.getCoordinates()); + this.isValid = true; + +// logger.info("Taxiway buffered polygon info : "+ this.polygon); + + } catch (RuntimeException e) { + logger.error("Line to Buffered Polygon generated fail : ["+ this.id +"] "+ name, e); + } + } + + public boolean isContains(Point point) throws RuntimeException { + if (this.isValid == false) { + return false; + } + return this.polygon.contains(point); + } + + public void generateBufferedPolygon(double bufferMeter) { + try { + generatePolygon(); + + this.isValid = false; + + Geometry buffer = BufferOp.bufferOp(this.polygon, CommonUtils.meterOnWGS84(bufferMeter), BufferParameters.CAP_SQUARE); + this.polygon = gf.createPolygon(buffer.getCoordinates()); + this.isValid = true; + + } catch (RuntimeException e) { + logger.error("Buffered Polygon generated fail : ["+ this.id +"] "+ name, e); + } + } +} diff --git a/src/main/java/kr/gmtc/gw/elastic/vo/AnalyzeArea/AreaPoint.java b/src/main/java/kr/gmtc/gw/elastic/vo/AnalyzeArea/AreaPoint.java new file mode 100644 index 0000000..2797c55 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/elastic/vo/AnalyzeArea/AreaPoint.java @@ -0,0 +1,17 @@ +package kr.gmtc.gw.elastic.vo.AnalyzeArea; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class AreaPoint { + + private String areaID; + private int sn; + private double lon; + private double lat; + +} diff --git a/src/main/java/kr/gmtc/gw/elastic/vo/ElasticMsgHeader.java b/src/main/java/kr/gmtc/gw/elastic/vo/ElasticRecv/ElasticMsgHeader.java similarity index 83% rename from src/main/java/kr/gmtc/gw/elastic/vo/ElasticMsgHeader.java rename to src/main/java/kr/gmtc/gw/elastic/vo/ElasticRecv/ElasticMsgHeader.java index 1f71ed0..31bd6e6 100644 --- a/src/main/java/kr/gmtc/gw/elastic/vo/ElasticMsgHeader.java +++ b/src/main/java/kr/gmtc/gw/elastic/vo/ElasticRecv/ElasticMsgHeader.java @@ -1,4 +1,4 @@ -package kr.gmtc.gw.elastic.vo; +package kr.gmtc.gw.elastic.vo.ElasticRecv; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/kr/gmtc/gw/elastic/vo/ElasticResultMsgVO.java b/src/main/java/kr/gmtc/gw/elastic/vo/ElasticRecv/ElasticResultMsgVO.java similarity index 90% rename from src/main/java/kr/gmtc/gw/elastic/vo/ElasticResultMsgVO.java rename to src/main/java/kr/gmtc/gw/elastic/vo/ElasticRecv/ElasticResultMsgVO.java index c5b997c..1194542 100644 --- a/src/main/java/kr/gmtc/gw/elastic/vo/ElasticResultMsgVO.java +++ b/src/main/java/kr/gmtc/gw/elastic/vo/ElasticRecv/ElasticResultMsgVO.java @@ -1,4 +1,4 @@ -package kr.gmtc.gw.elastic.vo; +package kr.gmtc.gw.elastic.vo.ElasticRecv; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; diff --git a/src/main/java/kr/gmtc/gw/elastic/vo/LogMsgParserVO.java b/src/main/java/kr/gmtc/gw/elastic/vo/ReplayLog/LogMsgParserVO.java similarity index 65% rename from src/main/java/kr/gmtc/gw/elastic/vo/LogMsgParserVO.java rename to src/main/java/kr/gmtc/gw/elastic/vo/ReplayLog/LogMsgParserVO.java index de7b18b..894e410 100644 --- a/src/main/java/kr/gmtc/gw/elastic/vo/LogMsgParserVO.java +++ b/src/main/java/kr/gmtc/gw/elastic/vo/ReplayLog/LogMsgParserVO.java @@ -1,7 +1,8 @@ -package kr.gmtc.gw.elastic.vo; +package kr.gmtc.gw.elastic.vo.ReplayLog; import java.util.List; +import kr.gmtc.gw.elastic.vo.ElasticRecv.ElasticMsgHeader; import lombok.Getter; import lombok.Setter; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5d43c7b..80ab15c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -11,6 +11,14 @@ spring: activate: on-profile: default +database: + db1: + datasource: + driver-class-name: com.tmax.tibero.jdbc.TbDriver + jdbcUrl: jdbc:tibero:thin:@10.200.31.1:8629:sacp + username: ucm + password: ucm + server: port: 8080 diff --git a/src/main/resources/mapper/DB1.xml b/src/main/resources/mapper/DB1.xml new file mode 100644 index 0000000..eeeca3f --- /dev/null +++ b/src/main/resources/mapper/DB1.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file