shjung 1 year ago
parent
commit
f45614577d
35 changed files with 733 additions and 619 deletions
  1. 0 2
      conf/apiKey.properties
  2. 46 0
      conf/application.yml
  3. 0 47
      conf/wthr-comm-server--tibero.properties
  4. 0 175
      conf/wthr-comm-server-logback - 복사본.xml
  5. 0 178
      conf/wthr-comm-server-logback.xml
  6. 0 52
      conf/wthr-comm-server.properties
  7. 6 0
      pom.xml
  8. 0 1
      src/main/java/com/its/wthr/WthrCommServerApplication.java
  9. 4 7
      src/main/java/com/its/wthr/config/AtmpConfig.java
  10. 4 7
      src/main/java/com/its/wthr/config/FrcsConfig.java
  11. 63 0
      src/main/java/com/its/wthr/config/JasyptConfig.java
  12. 7 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/FcstVersionData.java
  13. 7 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/UltraSrtFcstData.java
  14. 26 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/UltraSrtNcstData.java
  15. 7 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/VilageFcstData.java
  16. 225 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/VilageFcstInfo.java
  17. 16 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/SrtFcstItem.java
  18. 16 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/SrtNcstItem.java
  19. 12 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageBody.java
  20. 9 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageHeader.java
  21. 22 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageItem.java
  22. 10 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageItems.java
  23. 9 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageResponse.java
  24. 8 0
      src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageRoot.java
  25. 0 1
      src/main/java/com/its/wthr/scheduler/SchedulerTask.java
  26. 1 3
      src/main/java/com/its/wthr/service/AbstractXmlService.java
  27. 25 60
      src/main/resources/application.yml
  28. 9 0
      src/main/resources/console-appender.xml
  29. 19 0
      src/main/resources/file-error-appender.xml
  30. 14 0
      src/main/resources/file-log-appender.xml
  31. 23 0
      src/main/resources/file-packet-appender.xml
  32. 14 0
      src/main/resources/file-schedule-appender.xml
  33. 14 0
      src/main/resources/file-sql-appender.xml
  34. 8 86
      src/main/resources/logback-spring.xml
  35. 109 0
      src/test/java/com/its/wthr/WthrCommServerApplicationTests.java

+ 0 - 2
conf/apiKey.properties

@@ -1,2 +0,0 @@
-atmp-key=GKhEEB6LS9UEgLea0CorQiKzY0xxP86eJfhj8a2wmx4jNJ%2FBhL8f7rBviPWQY92ugK8zPjLYGQ8QQ5TRShtYFQ%3D%3D
-frcs-key=GKhEEB6LS9UEgLea0CorQiKzY0xxP86eJfhj8a2wmx4jNJ%2FBhL8f7rBviPWQY92ugK8zPjLYGQ8QQ5TRShtYFQ%3D%3D

+ 46 - 0
conf/application.yml

@@ -0,0 +1,46 @@
+application:
+  atmp:
+    enabled: true
+    crontab: 40 0/30 * * * *
+    api-key: GKhEEB6LS9UEgLea0CorQiKzY0xxP86eJfhj8a2wmx4jNJ%2FBhL8f7rBviPWQY92ugK8zPjLYGQ8QQ5TRShtYFQ%3D%3D
+    api-ver: 1.3
+    start-hour: 0
+    end-hour: 23
+
+  frcs:
+    enabled: true
+    crontab: 50 0/30 * * * *
+    api-key: 2y3qwo%2BwhlG6E%2BZfcyDKLMCr5Lp4gy%2BNgGuvWmgAdq7O%2Bf%2Fs4DPQz2ZD1rzDLowBq%2F6pfSi5F6UWlyM5meRiaw%3D%3D
+    start-hour: 0
+    end-hour: 23
+
+server:
+  port: 8873
+
+spring:
+  profiles:
+    active: dev
+
+---
+spring:
+  config:
+    activate:
+      on-profile: dev
+  datasource:
+    hikari:
+      driver-class-name: com.tmax.tibero.jdbc.TbDriver
+      jdbc-url: jdbc:tibero:thin:@115.91.94.42:8629:tibero
+      username: ENC(D/mtjX68HkE=)
+      password: ENC(D/mtjX68HkE=)
+
+---
+spring:
+  config:
+    activate:
+      on-profile: prod
+  datasource:
+    hikari:
+      driver-class-name: com.tmax.tibero.jdbc.TbDriver
+      jdbc-url: jdbc:tibero:thin:@115.91.94.42:8629:tibero
+      username: ENC(D/mtjX68HkE=)
+      password: ENC(D/mtjX68HkE=)

+ 0 - 47
conf/wthr-comm-server--tibero.properties

@@ -1,47 +0,0 @@
-#[logging]
-logging.config=conf//wthr-comm-server-logback.xml
-
-#[Application properties]
-process.id=EXT03
-process.name=Weather External Communication Server
-
-#[server config]
-
-#[server <---> operator]
-server.center.bind.port=6010
-server.center.dump=false
-
-#[ATMP]
-atmp.crontab = 0 15 * * * *
-atmp.apikey = 2y3qwo%2BwhlG6E%2BZfcyDKLMCr5Lp4gy%2BNgGuvWmgAdq7O%2Bf%2Fs4DPQz2ZD1rzDLowBq%2F6pfSi5F6UWlyM5meRiaw%3D%3D
-atmp.apiver = 1.3
-atmp.strhour = 0
-atmp.endhour = 23
-
-#[FRCS]
-frcs.crontab = 0 10 * * * *
-
-
-#[Database properties]
-#spring.datasource.hikari.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
-spring.datasource.hikari.driver-class-name=com.tmax.tibero.jdbc.TbDriver
-spring.datasource.hikari.jdbc-url=jdbc:tibero:thin:@100.100.10.10:8629:UTIS
-spring.datasource.hikari.username=itsdev
-spring.datasource.hikari.password=itsdev
-
-
-spring.datasource.hikari.jpool-name=hikari-cp
-spring.datasource.hikari.jmaximum-pool-size=30
-spring.datasource.hikari.jminimum-idle=2
-
-# FOR WEB UI: START
-server.shutdown=graceful
-server.port=8080
-server.error.whitelabel.enabled=true
-server.error.include-exception=false
-server.error.include-stacktrace=never
-
-spring.mvc.view.prefix=/WEB-INF/jsp/
-spring.mvc.view.suffix=.jsp
-server.servlet.session.timeout=300
-# FOR WEB UI: END

+ 0 - 175
conf/wthr-comm-server-logback - 복사본.xml

@@ -1,175 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration scan="true" scanPeriod="60 seconds">
-    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
-
-    <property name="PROJECT_NAME"    value="wthr-comm-server"/>
-    <property name="ROOT_LOG_LEVEL"  value="INFO"/>
-    <property name="LOG_CHARSET"     value="UTF-8" />
-    <property name="LOG_PATH"        value="${user.dir}/logs/"/>
-    <property name="LOG_BACKUP_PATH" value="${user.dir}/logs/backup/"/>
-
-    <property name="LOG_FILE_NAME"             value="${PROJECT_NAME}.log"/>
-    <property name="LOG_FILE_NAME_ERROR"       value="${PROJECT_NAME}.err.log"/>
-    <property name="LOG_FILE_NAME_PATTERN"     value="%d{yyyyMMdd}_%i.log.gz"/>
-    <property name="LOG_FILE_NAME_PACKET"      value="normal"/>
-    <property name="LOG_FILE_NAME_SESSION"     value="wthr-session.log"/>
-    <property name="LOG_FILE_NAME_CENTER_COMM" value="wthr-center-comm.log"/>
-    <property name="LOG_FILE_NAME_SQL"         value="wthr-sql.log"/>
-    <property name="LOG_FILE_NAME_SCHEDULE"    value="wthr-schedule.log"/>
-    <property name="LOG_FILE_NAME_STATISTICS"  value="wthr-statistics.log"/>
-
-    <property name="MAX_FILESIZE" value="10MB"/>
-    <property name="MAX_HISTORY"  value="30"/>
-    <property name="LOG_PATTERN_FILE"        value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_ERROR"       value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%30t] [%5level] %42logger{35}.%-20M ${PID:-} %n%msg%n"/>
-    <property name="LOG_PATTERN_PACKET"      value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_SESSION"     value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_CENTER_COMM" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_SQL"         value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_SCHEDULE"    value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_STATISTICS"  value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_CONSOLE" value="[%d{HH:mm:ss.SSS}] %highlight([%5level]) %highlight(${PID:-}): %cyan(%msg) %n"/>
-
-    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
-        <withJansi>true</withJansi>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <pattern>${LOG_PATTERN_CONSOLE}</pattern>
-        </encoder>
-    </appender>
-
-    <appender name="PACKET" class="ch.qos.logback.classic.sift.SiftingAppender">
-        <discriminator>
-            <key>id</key>
-            <defaultValue>${LOG_FILE_NAME_PACKET}</defaultValue>
-        </discriminator>
-        <sift>
-            <appender name="FILE-${id}" class="ch.qos.logback.core.rolling.RollingFileAppender">
-                <file>${LOG_PATH}wthr-${id}.log</file>
-                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-                    <charset>${LOG_CHARSET}</charset>
-                    <Pattern>${LOG_PATTERN_PACKET}</Pattern>
-                </encoder>
-
-                <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-                    <FileNamePattern>${LOG_BACKUP_PATH}${id}.${LOG_FILE_NAME_PATTERN}</FileNamePattern>
-                    <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-                    <maxHistory>${MAX_HISTORY}</maxHistory>
-                </rollingPolicy>
-            </appender>
-        </sift>
-    </appender>
-
-    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_FILE}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>error</level>
-            <onMatch>ACCEPT</onMatch>
-            <onMismatch>DENY</onMismatch>
-        </filter>
-        <file>${LOG_PATH}${LOG_FILE_NAME_ERROR}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_ERROR}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_ERROR}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="CENTER_COMM" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_CENTER_COMM}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_CENTER_COMM}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}CenterComm/${LOG_FILE_NAME_CENTER_COMM}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="FILE_SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_SQL}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_SQL}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}SQL/${LOG_FILE_NAME_SQL}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="FILE_SCHEDULE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_SCHEDULE}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_SCHEDULE}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}Schedule/${LOG_FILE_NAME_SCHEDULE}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <root level="${ROOT_LOG_LEVEL}">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="FILE"/>
-        <appender-ref ref="ERROR"/>
-    </root>
-
-    <logger name="com.its.app.thread" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="PACKET"/>
-    </logger>
-    <logger name="com.its.app.service" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="PACKET"/>
-    </logger>
-
-    <logger name="com.its.app.scheduler" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="FILE_SCHEDULE"/>
-        <appender-ref ref="ERROR"/>
-    </logger>
-
-    <logger name="com.its.app.xnetwork.udp" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="FILE"/>
-        <appender-ref ref="CENTER_COMM"/>
-    </logger>
-
-    <!--
-        <logger name="org.apache.ibatis" level="DEBUG" additivity="false">
-            <appender-ref ref="CONSOLE"/>
-            <appender-ref ref="FILE"/>
-            <appender-ref ref="ERROR"/>
-        </logger>
-    -->
-
-    <logger name="jdbc"                level="OFF"   additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.sqlonly"        level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.sqltiming"      level="DEBUG" additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.audit"          level="OFF"   additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.resultset"      level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.resultsettable" level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.connection"     level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-
-</configuration>

+ 0 - 178
conf/wthr-comm-server-logback.xml

@@ -1,178 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration scan="true" scanPeriod="60 seconds">
-    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
-
-    <property name="PROJECT_NAME"    value="wthr-comm-server"/>
-    <property name="ROOT_LOG_LEVEL"  value="INFO"/>
-    <property name="LOG_CHARSET"     value="UTF-8" />
-    <property name="LOG_PATH"        value="${user.dir}/logs/"/>
-    <property name="LOG_BACKUP_PATH" value="${user.dir}/logs/backup/"/>
-
-    <property name="LOG_FILE_NAME"             value="${PROJECT_NAME}.log"/>
-    <property name="LOG_FILE_NAME_ERROR"       value="${PROJECT_NAME}.err.log"/>
-    <property name="LOG_FILE_NAME_PATTERN"     value="%d{yyyyMMdd}_%i.log.gz"/>
-    <property name="LOG_FILE_NAME_PACKET"      value="normal"/>
-    <property name="LOG_FILE_NAME_SESSION"     value="wthr-session.log"/>
-    <property name="LOG_FILE_NAME_CENTER_COMM" value="wthr-center-comm.log"/>
-    <property name="LOG_FILE_NAME_SQL"         value="wthr-sql.log"/>
-    <property name="LOG_FILE_NAME_SCHEDULE"    value="wthr-schedule.log"/>
-    <property name="LOG_FILE_NAME_STATISTICS"  value="wthr-statistics.log"/>
-
-    <property name="MAX_FILESIZE" value="10MB"/>
-    <property name="MAX_HISTORY"  value="30"/>
-    <property name="LOG_PATTERN_FILE"        value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_ERROR"       value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <!--
-    <property name="LOG_PATTERN_ERROR"       value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%30t] [%5level] %42logger{35}.%-20M ${PID:-} %n%msg%n"/>
-    -->
-    <property name="LOG_PATTERN_PACKET"      value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_SESSION"     value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_CENTER_COMM" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_SQL"         value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_SCHEDULE"    value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_STATISTICS"  value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
-    <property name="LOG_PATTERN_CONSOLE" value="[%d{HH:mm:ss.SSS}] %highlight([%5level]) %highlight(${PID:-}): %cyan(%msg) %n"/>
-
-    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
-        <withJansi>true</withJansi>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <pattern>${LOG_PATTERN_CONSOLE}</pattern>
-        </encoder>
-    </appender>
-
-    <appender name="PACKET" class="ch.qos.logback.classic.sift.SiftingAppender">
-        <discriminator>
-            <key>id</key>
-            <defaultValue>${LOG_FILE_NAME_PACKET}</defaultValue>
-        </discriminator>
-        <sift>
-            <appender name="FILE-${id}" class="ch.qos.logback.core.rolling.RollingFileAppender">
-                <file>${LOG_PATH}wthr-${id}.log</file>
-                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-                    <charset>${LOG_CHARSET}</charset>
-                    <Pattern>${LOG_PATTERN_PACKET}</Pattern>
-                </encoder>
-
-                <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-                    <FileNamePattern>${LOG_BACKUP_PATH}${id}.${LOG_FILE_NAME_PATTERN}</FileNamePattern>
-                    <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-                    <maxHistory>${MAX_HISTORY}</maxHistory>
-                </rollingPolicy>
-            </appender>
-        </sift>
-    </appender>
-
-    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_FILE}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>error</level>
-            <onMatch>ACCEPT</onMatch>
-            <onMismatch>DENY</onMismatch>
-        </filter>
-        <file>${LOG_PATH}${LOG_FILE_NAME_ERROR}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_ERROR}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_ERROR}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="CENTER_COMM" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_CENTER_COMM}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_CENTER_COMM}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}CenterComm/${LOG_FILE_NAME_CENTER_COMM}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="FILE_SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_SQL}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_SQL}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}SQL/${LOG_FILE_NAME_SQL}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="FILE_SCHEDULE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_SCHEDULE}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_SCHEDULE}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}Schedule/${LOG_FILE_NAME_SCHEDULE}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <root level="${ROOT_LOG_LEVEL}">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="FILE"/>
-        <appender-ref ref="ERROR"/>
-    </root>
-
-    <logger name="com.its.app.thread" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="PACKET"/>
-    </logger>
-    <logger name="com.its.app.service" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="PACKET"/>
-    </logger>
-
-    <logger name="com.its.app.scheduler" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="FILE_SCHEDULE"/>
-        <appender-ref ref="ERROR"/>
-    </logger>
-
-    <logger name="com.its.app.xnetwork.udp" level="DEBUG" additivity="false">
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="FILE"/>
-        <appender-ref ref="CENTER_COMM"/>
-    </logger>
-
-    <!--
-        <logger name="org.apache.ibatis" level="DEBUG" additivity="false">
-            <appender-ref ref="CONSOLE"/>
-            <appender-ref ref="FILE"/>
-            <appender-ref ref="ERROR"/>
-        </logger>
-    -->
-
-    <logger name="jdbc"                level="OFF"   additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.sqlonly"        level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.sqltiming"      level="DEBUG" additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.audit"          level="OFF"   additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.resultset"      level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.resultsettable" level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-    <logger name="jdbc.connection"     level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="ERROR"/> </logger>
-
-</configuration>

+ 0 - 52
conf/wthr-comm-server.properties

@@ -1,52 +0,0 @@
-#[logging]
-logging.config=conf//wthr-comm-server-logback.xml
-
-#[Application properties]
-process.id=EXT03
-process.name=Weather External Communication Server
-
-#[server config]
-
-#[server <---> operator]
-server.center.bind.port=6010
-server.center.dump=false
-
-#[ATMP]
-atmp.crontab = 0 15 * * * *
-atmp.apikey = 2y3qwo%2BwhlG6E%2BZfcyDKLMCr5Lp4gy%2BNgGuvWmgAdq7O%2Bf%2Fs4DPQz2ZD1rzDLowBq%2F6pfSi5F6UWlyM5meRiaw%3D%3D
-atmp.apiver = 1.3
-atmp.strhour = 0
-atmp.endhour = 23
-
-#[FRCS]
-frcs.crontab = 0 10 * * * *
-
-
-#[Database properties]
-#spring.datasource.hikari.driver-class-name=com.tmax.tibero.jdbc.TbDriver
-#spring.datasource.hikari.jdbc-url=jdbc:tibero:thin:@192.168.20.29:8629:tibero
-#spring.datasource.hikari.username=gmutis
-#spring.datasource.hikari.password=gmutis
-
-#spring.datasource.hikari.driver-class-name=oracle.jdbc.OracleDriver
-spring.datasource.hikari.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
-#spring.datasource.hikari.jdbc-url=jdbc:oracle:thin:@127.0.0.1:1521:HANTE
-spring.datasource.hikari.jdbc-url=jdbc:log4jdbc:oracle:thin:@127.0.0.1:1521:HANTE
-spring.datasource.hikari.username=gmutis
-spring.datasource.hikari.password=gmutis
-
-spring.datasource.hikari.jpool-name=hikari-cp
-spring.datasource.hikari.jmaximum-pool-size=30
-spring.datasource.hikari.jminimum-idle=2
-
-# FOR WEB UI: START
-server.shutdown=graceful
-server.port=9873
-server.error.whitelabel.enabled=true
-server.error.include-exception=false
-server.error.include-stacktrace=never
-
-spring.mvc.view.prefix=/WEB-INF/jsp/
-spring.mvc.view.suffix=.jsp
-server.servlet.session.timeout=300
-# FOR WEB UI: END

+ 6 - 0
pom.xml

@@ -180,6 +180,12 @@
             <version>1.10.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.github.ulisesbocchio</groupId>
+            <artifactId>jasypt-spring-boot-starter</artifactId>
+            <version>3.0.4</version>
+        </dependency>
+
         <!-- FOR WEB UI: START -->
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 0 - 1
src/main/java/com/its/wthr/WthrCommServerApplication.java

@@ -158,7 +158,6 @@ public class WthrCommServerApplication implements CommandLineRunner, Application
 
         // schedule enable
         serverConfig.setStartSchedule(true);
-
     }
 
     public void terminateApplication() {

+ 4 - 7
src/main/java/com/its/wthr/config/AtmpConfig.java

@@ -28,20 +28,18 @@ public class AtmpConfig {
 
     @PostConstruct
     private void init() {
-        loadApiKey();
+        //loadApiKey();
         log.info("{}", this);
     }
 
     public boolean loadApiKey() {
-        try
-        {
+        try {
             String workingDir = System.getProperty("user.dir");
             FileInputStream in = null;
             try {
                 in = new FileInputStream(workingDir + "/conf/apiKey.properties");
             }
-            catch(Exception e)
-            {
+            catch(Exception e) {
                 log.error("{}.loadApiKey: Exception: {}", this.getClass().getSimpleName(), e.toString());
                 return false;
             }
@@ -56,8 +54,7 @@ public class AtmpConfig {
                 this.apiKey = apiKey;
             }
         }
-        catch(Exception e)
-        {
+        catch(Exception e) {
             log.error("{}.loadApiKey: Exception: {}", this.getClass().getSimpleName(), e.toString());
             return false;
         }

+ 4 - 7
src/main/java/com/its/wthr/config/FrcsConfig.java

@@ -28,20 +28,18 @@ public class FrcsConfig {
 
     @PostConstruct
     private void init() {
-        loadApiKey();
+        //loadApiKey();
         log.info("{}", this);
     }
 
     public boolean loadApiKey() {
-        try
-        {
+        try {
             String workingDir = System.getProperty("user.dir");
             FileInputStream in = null;
             try {
                 in = new FileInputStream(workingDir + "/conf/apiKey.properties");
             }
-            catch(Exception e)
-            {
+            catch(Exception e) {
                 log.error("{}.loadApiKey: Exception: {}", this.getClass().getSimpleName(), e.toString());
                 return false;
             }
@@ -56,8 +54,7 @@ public class FrcsConfig {
                 this.apiKey = apiKey;
             }
         }
-        catch(Exception e)
-        {
+        catch(Exception e) {
             log.error("{}.loadApiKey: Exception: {}", this.getClass().getSimpleName(), e.toString());
             return false;
         }

+ 63 - 0
src/main/java/com/its/wthr/config/JasyptConfig.java

@@ -0,0 +1,63 @@
+package com.its.wthr.config;
+
+import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
+import org.jasypt.encryption.StringEncryptor;
+import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
+import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
+import org.jasypt.salt.StringFixedSaltGenerator;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableEncryptableProperties
+public class JasyptConfig {
+
+    @Value("${jasypt.encryptor.password:asdkjfaslkjflkajslfjkajlkf}")
+    private final String encKey = "asdkjfaslkjflkajslfjkajlkf";
+
+    @Bean("jasyptStringEncryptor")
+    public StringEncryptor stringEncryptor() {
+
+        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
+        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
+
+        // ==> SimpleStringPBEConfig 사용시 아래 3개 반드시 설정해야함
+        config.setPassword(encKey);                                         // 암호화에 사용할 키
+        config.setPoolSize(1);                                              // Pool Size
+        config.setSaltGenerator(new StringFixedSaltGenerator("fixedSalt")); // 고정으로 암호화(Default: Random)
+        //config.setAlgorithm("PBEWithMD5AndTripleDES");
+        //config.setAlgorithm("PBEWithMD5AndDES"); // Jasypt 를 이용한 암호화 알고리즘
+        //config.setProviderName("SunJCE");
+        config.setKeyObtentionIterations("10000");
+        config.setStringOutputType("base64");
+        /*private Boolean proxyPropertySources = false;
+        private String bean = "jasyptStringEncryptor";
+        private String password;
+        private String algorithm = "PBEWithMD5AndDES";
+        private String keyObtentionIterations = "1000";
+        private String poolSize = "1";
+        private String providerName = null;
+        //config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
+        private String saltGeneratorClassname = "org.jasypt.salt.RandomSaltGenerator";
+        private String stringOutputType = "base64";*/
+        encryptor.setConfig(config);
+
+        return encryptor;
+    }
+
+    public String getKey() {
+        return this.encKey;
+    }
+
+    public String encrypt(String string) {
+        StringEncryptor encrypt = stringEncryptor();
+        return encrypt.encrypt(string);
+    }
+
+    public String decrypt(String string) {
+        StringEncryptor decrypt = stringEncryptor();
+        return decrypt.decrypt(string);
+    }
+
+}

+ 7 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/FcstVersionData.java

@@ -0,0 +1,7 @@
+package com.its.wthr.openApi.vilageFcstInfoService;
+
+/**
+ * 예보버전조회
+ */
+public class FcstVersionData extends VilageFcstInfo {
+}

+ 7 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/UltraSrtFcstData.java

@@ -0,0 +1,7 @@
+package com.its.wthr.openApi.vilageFcstInfoService;
+
+/**
+ * 초간기예보조회
+ */
+public class UltraSrtFcstData extends VilageFcstInfo {
+}

+ 26 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/UltraSrtNcstData.java

@@ -0,0 +1,26 @@
+package com.its.wthr.openApi.vilageFcstInfoService;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+
+/**
+ * 초간기실황조회
+ */
+public class UltraSrtNcstData extends VilageFcstInfo {
+
+    public String getBaseDate() {
+        LocalDateTime dateTime = LocalDateTime.now();
+        DateTimeFormatter fmtDay = DateTimeFormatter.ofPattern("yyyyMMdd");
+        return dateTime.format(fmtDay);
+    }
+
+    public String getBaseTime() {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(cal.getTime());
+        cal.add(Calendar.HOUR_OF_DAY, -1);	/* 주어진 시각에서 1초를 뺀 시각 */
+        return new SimpleDateFormat("HH").format(cal.getTime()) + "00";
+    }
+
+}

+ 7 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/VilageFcstData.java

@@ -0,0 +1,7 @@
+package com.its.wthr.openApi.vilageFcstInfoService;
+
+/**
+ * 단기예보조회
+ */
+public class VilageFcstData extends VilageFcstInfo {
+}

+ 225 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/VilageFcstInfo.java

@@ -0,0 +1,225 @@
+package com.its.wthr.openApi.vilageFcstInfoService;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 기상청 단기예보 조회서비스 Base Class
+ */
+@Slf4j
+public class VilageFcstInfo {
+
+    private String baseDate;
+    private String baseTime;
+
+    public VilageFcstInfo() {
+        setQueryDateTime();
+    }
+
+    public void setQueryDateTime() {
+        this.baseDate = getCurrentDay();
+        this.baseTime = changeQueryTime(getCurrentHour());
+    }
+
+    /**
+     * 현재 일자를 구한다(YYYYMMDD)
+     * @return
+     */
+    public String getCurrentDay() {
+        LocalDateTime dateTime = LocalDateTime.now();
+        DateTimeFormatter fmtDay = DateTimeFormatter.ofPattern("yyyyMMdd");
+        return dateTime.format(fmtDay);
+    }
+
+    /**
+     * 현재의 시간을 구한다.(HH24)
+     * @return
+     */
+    public int getCurrentHour() {
+        LocalDateTime dateTime = LocalDateTime.now();
+        DateTimeFormatter fmtHour = DateTimeFormatter.ofPattern("HH");
+        return Integer.parseInt(dateTime.format(fmtHour));
+    }
+
+    /**
+     * 주어진 시간을 기준으로 조회시각을 구한다.
+     * 주어진 시간에 따라 데이터 시간 설정(3시간 마다 업데이트 됨, 0200, 0500, 0800, 1100, 1400, 1700, 2000, 2300 (1일 8회))
+     * @param hour
+     * @return
+     */
+    public String changeQueryTime(int hour) {
+        String queryTime = "";
+        switch(hour) {
+            case  2: case  3: case  4: queryTime = "0200"; break;
+            case  5: case  6: case  7: queryTime = "0500"; break;
+            case  8: case  9: case 10: queryTime = "0800"; break;
+            case 11: case 12: case 13: queryTime = "1100"; break;
+            case 14: case 15: case 16: queryTime = "1400"; break;
+            case 17: case 18: case 19: queryTime = "1700"; break;
+            case 20: case 21: case 22: queryTime = "2000"; break;
+            default:                   queryTime = "2300"; break;
+        }
+        return queryTime;
+    }
+
+    /**
+     * 요청의 응답코드에 대한 오류메시지를 구한다.
+     * @param error
+     * @return
+     */
+    public String getErrorMessage(int error) {
+        String errorMessage;
+        switch(error) {
+            case  0: errorMessage = error + ": NORMAL_SERVICE, 정상"; break;
+            case  1: errorMessage = error + ": APPLICATION_ERROR, 어플리케이션 에러"; break;
+            case  2: errorMessage = error + ": DB_ERROR, 데이터베이스 에러"; break;
+            case  3: errorMessage = error + ": NODATA_ERROR, 데이터없음 에러"; break;
+            case  4: errorMessage = error + ": HTTP_ERROR, HTTP 에러"; break;
+            case  5: errorMessage = error + ": SERVICETIME_OUT, 서비스 연결실패 에러"; break;
+            case 10: errorMessage = error + ": INVALID_REQUEST_PARAMETER_ERROR, 잘못된 요청 파라메터 에러"; break;
+            case 11: errorMessage = error + ": NO_MANDATORY_REQUEST_PARAMETERS_ERROR, 필수요청 파라메터가 없음"; break;
+            case 12: errorMessage = error + ": NO_OPENAPI_SERVICE_ERROR, 해당 오픈 API 서비스가 없거나 폐기됨"; break;
+            case 20: errorMessage = error + ": SERVICE_ACCESS_DENIED_ERROR, 서비스 접근거부"; break;
+            case 21: errorMessage = error + ": TEMPORARILY_DISABLE_THE_SERVICEKEY_ERROR, 일시적으로 사용할 수 없는 서비스 키"; break;
+            case 22: errorMessage = error + ": LIMITED_NUMBER_OF_SERVICE_REQUESTS_EXCEEDS_ERROR, 서비스 요청제한횟수 초과에러"; break;
+            case 30: errorMessage = error + ": SERVICE_KEY_IS_NOT_REGISTERED_ERROR, 등록되지 않은 서비스키"; break;
+            case 31: errorMessage = error + ": DEADLINE_HAS_EXPIRED_ERROR, 기한만료된 서비스키"; break;
+            case 32: errorMessage = error + ": UNREGISTERED_IP_ERROR, 등록되지 않은 IP"; break;
+            case 33: errorMessage = error + ": UNSIGNED_CALL_ERROR, 서명되지 않은 호출"; break;
+            case 99: errorMessage = error + ": UNKNOWN_ERROR, 기타에러"; break;
+            default: errorMessage = error + ": 알수없는 오류코드"; break;
+        }
+        return errorMessage;
+    }
+
+    /**
+     * 하늘상태(SKY) 코드 설명
+     * @param sky
+     * @return
+     */
+    public String getSkyDesc(String sky) {
+        if (sky == null) {
+            return "-";
+        }
+        if ("1".equals(sky.trim())) {
+            return "맑음";
+        }
+        if ("3".equals(sky.trim())) {
+            return "구름많음";
+        }
+        if ("4".equals(sky.trim())) {
+            return "흐림";
+        }
+        return "-";
+    }
+
+    /**
+     * 강수형태(PTY) 코드 설명
+     * @param pty
+     * @return
+     */
+    public String etPtyDesc(String pty) {
+        if (pty == null) {
+            return "-";
+        }
+        if ("0".equals(pty.trim())) {
+            return "없음";    // 초단기, 단기
+        }
+        if ("1".equals(pty.trim())) {
+            return "비";     // 초단기, 단기
+        }
+        if ("2".equals(pty.trim())) {
+            return "비/눈";   // 초단기, 단기
+        }
+        if ("3".equals(pty.trim())) {
+            return "눈";     // 초단기, 단기
+        }
+        if ("4".equals(pty.trim())) {
+            return "소나기";   // 단기
+        }
+        if ("5".equals(pty.trim())) {
+            return "빗방울";   // 초단기
+        }
+        if ("6".equals(pty.trim())) {
+            return "빗방울눈날림";    // 초단기
+        }
+        if ("7".equals(pty.trim())) {
+            return "눈날림";   // 초단기
+        }
+        return "-";
+    }
+
+    /**
+     * 강수량(RN1, PCP) 범주 및 표시방법
+     * @param value
+     * @return
+     */
+    public String getRn1PcpDesc(String value) {
+        if (value == null || "-".equals(value.trim()) || "0".equals(value.trim())) {
+            return "강수없음";
+        }
+
+        float f = Float.parseFloat(value);
+        if(f < 1.0f) return "1.0mm 미만 ";
+        else if(f >= 1.0f && f < 30.0f) return "1.0~29.0mm";
+        else if(f >= 30.0f && f < 50.0f) return "30.0~50.0mm";
+        else return "50.0mm 이상";
+    }
+
+    /**
+     * 신적설(SNO) 범주 표시방법
+     * @param value
+     * @return
+     */
+    public String getSnoDesc(String value) {
+        if (value == null || "-".equals(value.trim()) || "0".equals(value.trim())) {
+            return "적설없음";
+        }
+
+        float f = Float.parseFloat(value);
+        if(f < 1.0f) return "1.0cm 미만 ";
+        else if(f >= 1.0f && f < 5.0f) return value+"cm";
+        else return "5.0cm 이상";
+    }
+
+    public String lookUpApi(StringBuilder urlBuilder) {
+        try {
+            URL url = new URL(urlBuilder.toString());
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setConnectTimeout(10000);   //The timeout in mills
+            conn.setRequestMethod("GET");
+            conn.setRequestProperty("Content-type", "application/json");
+            log.info("Response code: {}.", conn.getResponseCode());
+
+            BufferedReader rd;
+            if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
+                rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            } else {
+                rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
+            }
+
+            StringBuilder sb = new StringBuilder();
+            String line;
+            while ((line = rd.readLine()) != null) {
+                sb.append(line);
+            }
+            rd.close();
+            conn.disconnect();
+            return sb.toString();
+        } catch (MalformedURLException e) {
+            log.error("MalformedURLException Error: {}", e.getMessage());
+        } catch (IOException e) {
+            log.error("IOException Error: {}", e.getMessage());
+        }
+        return null;
+    }
+
+}

+ 16 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/SrtFcstItem.java

@@ -0,0 +1,16 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+/**
+ * 초단기예보 Item
+ */
+@Data
+public class SrtFcstItem {
+    public String baseDate;
+    public String baseTime;
+    public String category;
+    public int nx;
+    public int ny;
+    public String obsrValue;
+}

+ 16 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/SrtNcstItem.java

@@ -0,0 +1,16 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+/**
+ * 초단기실황 Item
+ */
+@Data
+public class SrtNcstItem {
+    public String baseDate;
+    public String baseTime;
+    public String category;
+    public int nx;
+    public int ny;
+    public String obsrValue;
+}

+ 12 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageBody.java

@@ -0,0 +1,12 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+@Data
+public class VilageBody {
+    public String dataType;
+    public VilageItems items;
+    public int pageNo;
+    public int numOfRows;
+    public int totalCount;
+}

+ 9 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageHeader.java

@@ -0,0 +1,9 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+@Data
+public class VilageHeader {
+    public String resultCode;
+    public String resultMsg;
+}

+ 22 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageItem.java

@@ -0,0 +1,22 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+/**
+ * 단기예보 Item
+ */
+@Data
+public class VilageItem {
+    public String baseDate;
+    public String baseTime;
+    public String category;
+
+    public String fcstDate;
+    public String fcstTime;
+    public String fcstValue;
+
+    public String obsrValue;
+
+    public int nx;
+    public int ny;
+}

+ 10 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageItems.java

@@ -0,0 +1,10 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+
+@Data
+public class VilageItems {
+    public ArrayList<VilageItem> item;
+}

+ 9 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageResponse.java

@@ -0,0 +1,9 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+@Data
+public class VilageResponse {
+    public VilageHeader header;
+    public VilageBody body;
+}

+ 8 - 0
src/main/java/com/its/wthr/openApi/vilageFcstInfoService/entity/VilageRoot.java

@@ -0,0 +1,8 @@
+package com.its.wthr.openApi.vilageFcstInfoService.entity;
+
+import lombok.Data;
+
+@Data
+public class VilageRoot {
+    public VilageResponse response;
+}

+ 0 - 1
src/main/java/com/its/wthr/scheduler/SchedulerTask.java

@@ -32,7 +32,6 @@ public class SchedulerTask {
             return;
         }
         Elapsed elapsed = new Elapsed();
-        //log.info("UnitSystSchedule :: start. {}", Thread.currentThread().getName());
 
         // 1. 프로세스 상태정보 업데이트
         this.unitSystService.updateUnitSyst(true);

+ 1 - 3
src/main/java/com/its/wthr/service/AbstractXmlService.java

@@ -15,12 +15,10 @@ import java.net.URLConnection;
 @Slf4j
 public class AbstractXmlService {
 
-    public NodeList getXmlNodeList(String url, String nodeTag)
-    {
+    public NodeList getXmlNodeList(String url, String nodeTag) {
         try {
             DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
             DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
-//            Document document = documentBuilder.parse(url);
 
             URL xmlUrl = new URL(url);
             URLConnection urlConnection = xmlUrl.openConnection();

+ 25 - 60
src/main/resources/application.yml

@@ -1,26 +1,14 @@
-application:
-  process:
-    id: EXT01
-    name: Weather(Open API) Communication Server
-    history: true
-  user:
-    id: admin
-    pswd: 1234
-
-  atmp:
-    enabled: true
-    crontab: 40 0/30 * * * *
-    api-key: GKhEEB6LS9UEgLea0CorQiKzY0xxP86eJfhj8a2wmx4jNJ%2FBhL8f7rBviPWQY92ugK8zPjLYGQ8QQ5TRShtYFQ%3D%3D
-    api-ver: 1.3
-    start-hour: 0
-    end-hour: 23
-
-  frcs:
-    enabled: true
-    crontab: 50 0/30 * * * *
-    api-key: GKhEEB6LS9UEgLea0CorQiKzY0xxP86eJfhj8a2wmx4jNJ%2FBhL8f7rBviPWQY92ugK8zPjLYGQ8QQ5TRShtYFQ%3D%3D
-    start-hour: 0
-    end-hour: 23
+spring:
+  application:
+    name: wthr-comm-server
+  main:
+    web-application-type: none
+    log-startup-info: true
+    banner-mode: off
+  config:
+    import: file:${user.dir}/conf/application.yml
+  profiles:
+    include: application
 
 server:
   port: 8873
@@ -34,41 +22,18 @@ server:
     session:
       timeout: 300
 
-spring:
-  application:
-    name: wthr-comm-server
-  profiles:
-    active: prod
-  main:
-    web-application-type: none
-    log-startup-info: true
-    banner-mode: off
-#  mvc:
-#    view:
-#      prefix: /WEB-INF/jsp/
-#      suffix: .jsp
-
----
-spring:
-  config:
-    activate:
-      on-profile: dev
-  datasource:
-    hikari:
-      driver-class-name: com.tmax.tibero.jdbc.TbDriver
-      jdbc-url: jdbc:tibero:thin:@115.91.94.42:8629:tibero
-      username: adits
-      password: adits
-
----
-spring:
-  config:
-    activate:
-      on-profile: prod
-  datasource:
-    hikari:
-      driver-class-name: com.tmax.tibero.jdbc.TbDriver
-      jdbc-url: jdbc:tibero:thin:@115.91.94.42:8629:tibero
-      username: adits
-      password: adits
+application:
+  process:
+    id: EXT01
+    name: Weather(Open API) Communication Server
+    history: true
+  user:
+    id: admin
+    pswd: 1234
 
+jasypt:
+  encryptor:
+    bean: jasyptStringEncryptor
+    property:
+      prefix: ENC(
+      suffix: )

+ 9 - 0
src/main/resources/console-appender.xml

@@ -0,0 +1,9 @@
+<included>
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <withJansi>true</withJansi>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_CONSOLE}</pattern>
+        </encoder>
+    </appender>
+</included>

+ 19 - 0
src/main/resources/file-error-appender.xml

@@ -0,0 +1,19 @@
+<included>
+    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>error</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${LOG_PATH}${LOG_FILE_NAME_ERROR}</file>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_ERROR}</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_ERROR}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
+            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+    </appender>
+</included>

+ 14 - 0
src/main/resources/file-log-appender.xml

@@ -0,0 +1,14 @@
+<included>
+    <appender name="FILE_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_PATH}${LOG_FILE_NAME}</file>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_FILE}</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
+            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+    </appender>
+</included>

+ 23 - 0
src/main/resources/file-packet-appender.xml

@@ -0,0 +1,23 @@
+<included>
+    <appender name="FILE_PACKET" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator>
+            <key>id</key>
+            <defaultValue>${LOG_FILE_NAME_PACKET}</defaultValue>
+        </discriminator>
+        <sift>
+            <appender name="FILE-${id}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <file>${LOG_PATH}packet/${id}.log</file>
+                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+                    <charset>${LOG_CHARSET}</charset>
+                    <Pattern>${LOG_PATTERN_PACKET}</Pattern>
+                </encoder>
+
+                <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+                    <FileNamePattern>${LOG_BACKUP_PATH}packet/${id}.${LOG_FILE_NAME_PATTERN}</FileNamePattern>
+                    <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+                    <maxHistory>${MAX_HISTORY}</maxHistory>
+                </rollingPolicy>
+            </appender>
+        </sift>
+    </appender>
+</included>

+ 14 - 0
src/main/resources/file-schedule-appender.xml

@@ -0,0 +1,14 @@
+<included>
+    <appender name="FILE_SCHEDULE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_PATH}${LOG_FILE_NAME_SCHEDULE}</file>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_SCHEDULE}</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_SCHEDULE}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
+            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+    </appender>
+</included>

+ 14 - 0
src/main/resources/file-sql-appender.xml

@@ -0,0 +1,14 @@
+<included>
+    <appender name="FILE_SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_PATH}${LOG_FILE_NAME_SQL}</file>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_SQL}</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_SQL}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
+            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+    </appender>
+</included>

+ 8 - 86
src/main/resources/logback-spring.xml

@@ -33,66 +33,14 @@
 <!--    <property name="LOG_PATTERN_CONSOLE"     value="[%d{HH:mm:ss.SSS}] %highlight([%5level]) %highlight(${PID:-}): %cyan(%msg) %n"/>-->
     <property name="LOG_PATTERN_CONSOLE"     value="[%d{HH:mm:ss.SSS}] [%5level] %msg %n"/>
 
-    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
-        <withJansi>true</withJansi>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_CONSOLE}</pattern>
-        </encoder>
-    </appender>
-
-    <appender name="FILE_PACKET" class="ch.qos.logback.classic.sift.SiftingAppender">
-        <discriminator>
-            <key>id</key>
-            <defaultValue>${LOG_FILE_NAME_PACKET}</defaultValue>
-        </discriminator>
-        <sift>
-            <appender name="FILE-${id}" class="ch.qos.logback.core.rolling.RollingFileAppender">
-                <file>${LOG_PATH}packet/${id}.log</file>
-                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-                    <charset>${LOG_CHARSET}</charset>
-                    <Pattern>${LOG_PATTERN_PACKET}</Pattern>
-                </encoder>
-
-                <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-                    <FileNamePattern>${LOG_BACKUP_PATH}packet/${id}.${LOG_FILE_NAME_PATTERN}</FileNamePattern>
-                    <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-                    <maxHistory>${MAX_HISTORY}</maxHistory>
-                </rollingPolicy>
-            </appender>
-        </sift>
-    </appender>
-
-    <appender name="FILE_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_FILE}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
-    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>error</level>
-            <onMatch>ACCEPT</onMatch>
-            <onMismatch>DENY</onMismatch>
-        </filter>
-        <file>${LOG_PATH}${LOG_FILE_NAME_ERROR}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_ERROR}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_ERROR}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
+    <springProfile name="!xxx">
+        <include resource="console-appender.xml"/>
+        <include resource="file-sql-appender.xml"/>
+        <include resource="file-packet-appender.xml"/>
+        <include resource="file-log-appender.xml"/>
+        <include resource="file-schedule-appender.xml"/>
+        <include resource="file-error-appender.xml"/>
+    </springProfile>
 
     <root level="INFO">
         <appender-ref ref="CONSOLE"/>
@@ -100,38 +48,12 @@
         <appender-ref ref="FILE_ERROR"/>
     </root>
 
-    <appender name="FILE_SCHEDULE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_SCHEDULE}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_SCHEDULE}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_SCHEDULE}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
     <logger name="${APP_CLASS_PATH}.scheduler" level="DEBUG" additivity="false">
         <appender-ref ref="CONSOLE"/>
         <appender-ref ref="FILE_SCHEDULE"/>
         <appender-ref ref="FILE_ERROR"/>
     </logger>
 
-    <appender name="FILE_SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${LOG_PATH}${LOG_FILE_NAME_SQL}</file>
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <charset>${LOG_CHARSET}</charset>
-            <pattern>${LOG_PATTERN_SQL}</pattern>
-        </encoder>
-        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_SQL}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
-            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-        </rollingPolicy>
-    </appender>
-
     <logger name="jdbc"                level="OFF"   additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="FILE_ERROR"/> </logger>
     <logger name="jdbc.sqlonly"        level="INFO"  additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="FILE_ERROR"/> </logger>
     <logger name="jdbc.sqltiming"      level="DEBUG" additivity="false"> <appender-ref ref="FILE_SQL" /> <appender-ref ref="FILE_ERROR"/> </logger>

+ 109 - 0
src/test/java/com/its/wthr/WthrCommServerApplicationTests.java

@@ -0,0 +1,109 @@
+package com.its.wthr;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.its.wthr.openApi.vilageFcstInfoService.UltraSrtNcstData;
+import com.its.wthr.openApi.vilageFcstInfoService.entity.VilageItems;
+import com.its.wthr.openApi.vilageFcstInfoService.entity.VilageRoot;
+import lombok.extern.slf4j.Slf4j;
+import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
+import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
+import org.jasypt.salt.StringFixedSaltGenerator;
+import org.junit.jupiter.api.Test;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+@Slf4j
+//@SpringBootTest(classes = WthrCommServerApplication.class)
+//@AutoConfigureMockMvc
+//@SpringBootTest(
+//        webEnvironment = SpringBootTest.WebEnvironment.MOCK,
+//        properties = "spring.config.location ="+
+//                "classpath:/application.yml"+
+//                ",classpath:/database.yaml"
+//)
+public class WthrCommServerApplicationTests {
+
+    @Test
+    void jasypt() {
+        String encKey = "asdkjfaslkjflkajslfjkajlkf";
+        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
+        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
+
+        // ==> SimpleStringPBEConfig 사용시 아래 3개 반드시 설정해야함
+        config.setPassword(encKey);                                         // 암호화에 사용할 키
+        config.setPoolSize(1);                                              // Pool Size
+        config.setSaltGenerator(new StringFixedSaltGenerator("fixedSalt")); // 고정으로 암호화(Default: Random)
+        //config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
+        //config.setAlgorithm("PBEWithMD5AndTripleDES");
+        config.setAlgorithm("PBEWithMD5AndDES"); // Jasypt 를 이용한 암호화 알고리즘
+        config.setProviderName("SunJCE");
+        config.setKeyObtentionIterations("10000");
+        config.setStringOutputType("base64");
+        /*private Boolean proxyPropertySources = false;
+        private String bean = "jasyptStringEncryptor";
+        private String password;
+        private String algorithm = "PBEWithMD5AndDES";
+        private String keyObtentionIterations = "1000";
+        private String poolSize = "1";
+        private String providerName = null;
+        //config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
+        private String saltGeneratorClassname = "org.jasypt.salt.RandomSaltGenerator";
+        private String stringOutputType = "base64";*/
+        encryptor.setConfig(config);
+
+        String yiits = encryptor.encrypt("adits");
+        String rutis = encryptor.encrypt("adits");
+        log.info("{}", yiits);
+        log.info("{}", rutis);
+    }
+
+    @Test
+    void testGetUltraSrtNcst() {
+        UltraSrtNcstData info = new UltraSrtNcstData();
+        String apiUrl = "https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst";
+        String serviceKey = "2y3qwo%2BwhlG6E%2BZfcyDKLMCr5Lp4gy%2BNgGuvWmgAdq7O%2Bf%2Fs4DPQz2ZD1rzDLowBq%2F6pfSi5F6UWlyM5meRiaw%3D%3D";
+        String nx = "91";
+        String ny = "106";
+        String baseDate = info.getBaseDate();
+        String baseTime = info.getBaseTime();
+        String dataType = "json";
+
+        StringBuilder urlBuilder = new StringBuilder(apiUrl);
+        try {
+            urlBuilder.append("?" + URLEncoder.encode("serviceKey","UTF-8") + "=" + serviceKey);
+            urlBuilder.append("&" + URLEncoder.encode("pageNo","UTF-8") + "=1");
+            urlBuilder.append("&" + URLEncoder.encode("numOfRows","UTF-8") + "=1000");
+            urlBuilder.append("&" + URLEncoder.encode("dataType","UTF-8") + "=" + URLEncoder.encode(dataType, "UTF-8"));
+            urlBuilder.append("&" + URLEncoder.encode("base_date","UTF-8") + "=" + URLEncoder.encode(baseDate, "UTF-8"));
+            urlBuilder.append("&" + URLEncoder.encode("base_time","UTF-8") + "=" + URLEncoder.encode(baseTime, "UTF-8"));
+            urlBuilder.append("&" + URLEncoder.encode("nx","UTF-8") + "=" + URLEncoder.encode(nx, "UTF-8"));
+            urlBuilder.append("&" + URLEncoder.encode("ny","UTF-8") + "=" + URLEncoder.encode(ny, "UTF-8"));
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+
+        log.info("{}", urlBuilder.toString());
+        String result = info.lookUpApi(urlBuilder);
+        log.info("{}", result);
+
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            VilageRoot response = mapper.readValue(result, VilageRoot.class);
+            log.info("{}", response);
+
+            if (response != null && response.getResponse() != null && response.getResponse().getBody() != null) {
+                VilageItems items = response.getResponse().getBody().items;
+                if (items.getItem() != null) {
+                    items.getItem().forEach(obj -> {
+                        log.info("{}", obj);
+                    });
+                }
+            }
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}