diff --git a/build.gradle b/build.gradle index 3c536fbd..c341f0c2 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,9 @@ repositories { dependencies { compileOnly 'org.projectlombok:lombok:1.18.24' + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:2.7.2' + annotationProcessor 'org.projectlombok:lombok:1.18.24' + implementation 'org.springframework.boot:spring-boot-starter-actuator:2.7.2' implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.7.2' implementation 'org.springframework.boot:spring-boot-starter-security:2.7.2' @@ -31,6 +34,7 @@ dependencies { implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE' developmentOnly 'org.springframework.boot:spring-boot-devtools:2.7.2' + implementation 'org.apache.tomcat:tomcat-catalina-ha:9.0.62' implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16' runtimeOnly 'org.postgresql:postgresql:42.3.6' @@ -44,9 +48,6 @@ dependencies { implementation 'org.apache.poi:poi:4.1.0' implementation 'org.apache.poi:poi-ooxml:4.1.0' - annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:2.7.2' - annotationProcessor 'org.projectlombok:lombok:1.18.24' - //crossEditor 요구 라이브러리 //implementation files('libs/commons-codec-1.15.jar') // 이미 추가되어 있어서 제외. implementation files('libs/commons-fileupload-1.4.jar') diff --git a/src/main/java/com/dbnt/faisp/config/tomcat/TomcatConfiguration.java b/src/main/java/com/dbnt/faisp/config/tomcat/TomcatAjpConfiguration.java similarity index 92% rename from src/main/java/com/dbnt/faisp/config/tomcat/TomcatConfiguration.java rename to src/main/java/com/dbnt/faisp/config/tomcat/TomcatAjpConfiguration.java index e4e2ded6..d96676a3 100644 --- a/src/main/java/com/dbnt/faisp/config/tomcat/TomcatConfiguration.java +++ b/src/main/java/com/dbnt/faisp/config/tomcat/TomcatAjpConfiguration.java @@ -1,7 +1,6 @@ package com.dbnt.faisp.config.tomcat; import org.apache.catalina.connector.Connector; -import org.apache.coyote.ProtocolHandler; import org.apache.coyote.ajp.AbstractAjpProtocol; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; @@ -9,10 +8,8 @@ import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.net.InetAddress; - @Configuration -public class TomcatConfiguration { +public class TomcatAjpConfiguration { @Value("${tomcat.ajp.protocol}") private String protocol; diff --git a/src/main/java/com/dbnt/faisp/config/tomcat/TomcatClusterContextCustomizer.java b/src/main/java/com/dbnt/faisp/config/tomcat/TomcatClusterContextCustomizer.java new file mode 100644 index 00000000..0c07f239 --- /dev/null +++ b/src/main/java/com/dbnt/faisp/config/tomcat/TomcatClusterContextCustomizer.java @@ -0,0 +1,94 @@ +package com.dbnt.faisp.config.tomcat; + +import org.apache.catalina.Context; +import org.apache.catalina.Engine; +import org.apache.catalina.ha.session.ClusterSessionListener; +import org.apache.catalina.ha.session.DeltaManager; +import org.apache.catalina.ha.session.JvmRouteBinderValve; +import org.apache.catalina.ha.tcp.ReplicationValve; +import org.apache.catalina.ha.tcp.SimpleTcpCluster; +import org.apache.catalina.tribes.group.GroupChannel; +import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor; +import org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor; +import org.apache.catalina.tribes.group.interceptors.TcpFailureDetector; +import org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor; +import org.apache.catalina.tribes.membership.McastService; +import org.apache.catalina.tribes.membership.StaticMember; +import org.apache.catalina.tribes.transport.ReplicationTransmitter; +import org.apache.catalina.tribes.transport.nio.NioReceiver; +import org.apache.catalina.tribes.transport.nio.PooledParallelSender; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; +import org.springframework.stereotype.Component; + +@Component +public class TomcatClusterContextCustomizer implements TomcatContextCustomizer { + + @Value("${tomcat.cluster.static-member-host:}") + private String staticMemberHost; + @Value("${tomcat.cluster.static-member-port:}") + private Integer staticMemberPort; + @Value("${tomcat.cluster.static-member-unique-id:}") + private String staticMemberUniqueId; + @Value("${tomcat.cluster.receiver-address:}") + private String receiverAddress; + @Value("${tomcat.cluster.receiver-port:}") + private Integer receiverPort; + @Value("${tomcat.cluster.receiver-max-threads:}") + private Integer receiverMaxThreads; + + @Override + public void customize( final Context context ) { + context.setDistributable(true); + // BackupManager manager = new BackupManager(); + DeltaManager manager = new DeltaManager(); + manager.setExpireSessionsOnShutdown(false); + manager.setNotifyListenersOnReplication(true); + context.setManager(manager); + configureCluster( (Engine)context.getParent().getParent() ); + } + + private void configureCluster(Engine engine) { + //cluster setting + SimpleTcpCluster cluster = new SimpleTcpCluster(); + cluster.setChannelStartOptions(3); + cluster.setChannelSendOptions(8); + + //channel setting + GroupChannel channel = new GroupChannel(); + StaticMembershipInterceptor interceptor = new StaticMembershipInterceptor(); + + // 대상 정보 + StaticMember staticMember = new StaticMember(); + staticMember.setHost(staticMemberHost); + staticMember.setPort(staticMemberPort); + staticMember.setSecurePort(-1); + staticMember.setUniqueId(staticMemberUniqueId); + interceptor.addStaticMember(staticMember); + + //receiver(현재 자신의 정보) + NioReceiver receiver = new NioReceiver(); + receiver.setAddress(receiverAddress); + receiver.setPort(receiverPort); + receiver.setMaxThreads(receiverMaxThreads); + channel.setChannelReceiver(receiver); + + channel.addInterceptor(interceptor); + + //sender setting + ReplicationTransmitter sender = new ReplicationTransmitter(); + sender.setTransport(new PooledParallelSender()); + channel.setChannelSender(sender); + + //interceptor setting + channel.addInterceptor(new TcpPingInterceptor()); + channel.addInterceptor(new TcpFailureDetector()); + channel.addInterceptor(new MessageDispatchInterceptor()); + + cluster.addValve(new ReplicationValve()); + cluster.addValve(new JvmRouteBinderValve()); + cluster.setChannel(channel); + cluster.addClusterListener(new ClusterSessionListener()); + engine.setCluster(cluster); + } +} diff --git a/src/main/java/com/dbnt/faisp/config/tomcat/TomcatClusterUtil.java b/src/main/java/com/dbnt/faisp/config/tomcat/TomcatClusterUtil.java new file mode 100644 index 00000000..ffb7b555 --- /dev/null +++ b/src/main/java/com/dbnt/faisp/config/tomcat/TomcatClusterUtil.java @@ -0,0 +1,24 @@ +package com.dbnt.faisp.config.tomcat; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class TomcatClusterUtil implements WebServerFactoryCustomizer { + private final TomcatClusterContextCustomizer tomcatClusterContextCustomizer; + + @Value("${tomcat.cluster.enabled}") + private boolean clusterEnabled; + + @Override + public void customize( final TomcatServletWebServerFactory factory ) { + if(clusterEnabled){ + factory.addContextCustomizers(tomcatClusterContextCustomizer); + } + } +} + diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 44d9ec32..f0c309b8 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -1,6 +1,8 @@ -tomcat.ajp.protocol=HTTP/1.1 spring.devtools.livereload.enabled=true +tomcat.ajp.protocol=HTTP/1.1 +tomcat.cluster.enabled=false + #file upload spring.servlet.multipart.location=C:\\faispUploadFiles spring.servlet.multipart.max-file-size=200MB diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test1.properties similarity index 81% rename from src/main/resources/application-test.properties rename to src/main/resources/application-test1.properties index c466f842..ff740e22 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test1.properties @@ -1,5 +1,16 @@ +#tomcat tomcat.ajp.protocol=HTTP/1.1 +logging.level.org.apache.tomcat: DEBUG +logging.level.org.apache.catalina: DEBUG +tomcat.cluster.enabled=true +tomcat.cluster.static-member-host=172.80.0.3 +tomcat.cluster.static-member-port=4040 +tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2} +tomcat.cluster.receiver-address=172.80.0.2 +tomcat.cluster.receiver-port=4040 +tomcat.cluster.receiver-max-threads=4 + #file upload spring.servlet.multipart.location=/uploadFiles spring.servlet.multipart.max-file-size=200MB diff --git a/src/main/resources/application-test2.properties b/src/main/resources/application-test2.properties new file mode 100644 index 00000000..af7e0070 --- /dev/null +++ b/src/main/resources/application-test2.properties @@ -0,0 +1,77 @@ +#tomcat +tomcat.ajp.protocol=HTTP/1.1 + +logging.level.org.apache.tomcat: DEBUG +logging.level.org.apache.catalina: DEBUG +tomcat.cluster.enabled=true +tomcat.cluster.static-member-host=172.80.0.2 +tomcat.cluster.static-member-port=4040 +tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1} +tomcat.cluster.receiver-address=172.80.0.3 +tomcat.cluster.receiver-port=4040 +tomcat.cluster.receiver-max-threads=4 + +#file upload +spring.servlet.multipart.location=/uploadFiles +spring.servlet.multipart.max-file-size=200MB +spring.servlet.multipart.max-request-size=500MB + +site.domain=http://118.219.150.34:50580 + +#file +file.dir.publicBoard=/publicBoard +file.dir.faRpt=/faRpt +file.dir.vulnerable=/vulnerable +file.dir.part=/part +file.dir.equip=/equip +file.dir.sailor=/sailor +file.dir.affair=/affair +file.dir.affair.plan=/affairPlan +file.dir.affair.result=/affairResult +file.dir.editor=/editor +file.dir.sri=/sri +file.dir.ciw=/ciw +file.dir.cia.safty=/cia/safty +file.dir.cia.company=/cia/company +file.dir.cia.foreigner=/cia/foreigner +file.dir.cia.edu=/cia/edu +file.dir.activityCase=/activityCase +file.dir.majorStatus=/majorStatus +file.dir.monitoring=/monitoring +file.dir.intelligenceNetwork=/intelligenceNetwork + +file.dir.affairTemp=/affairTemp + +editor.img.view=/file/editorFileDisplay?fileNm= + +#thymeleaf +spring.thymeleaf.prefix=classpath:templates/ +spring.thymeleaf.check-template-location=true +spring.thymeleaf.suffix=.html +spring.thymeleaf.mode=HTML + +#Datasource Configuration +spring.sql.init.encoding=utf-8 +#maximum-pool-size: CPU core count +spring.datasource.hikari.maximum-pool-size=4 +#postgresql +spring.datasource-main.driverClassName=org.postgresql.Driver +spring.datasource-main.jdbcUrl=jdbc:postgresql://118.219.150.34:50503/faisp +spring.datasource-main.username=dbnt0031 +spring.datasource-main.password=dbnt0928! +#oracle +spring.datasource-kwms.driverClassName=oracle.jdbc.driver.OracleDriver +spring.datasource-kwms.jdbcUrl=jdbc:oracle:thin:@118.219.150.34:51521:kwms +spring.datasource-kwms.username=kwms +spring.datasource-kwms.password=dbnt0928 + +#jpa +spring.jpa.show-sql=false +spring.jpa.generate-ddl=false +spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + +# MyBatis +mybatis.mapper-locations: mybatisMapper/*.xml +mybatis.configuration.map-underscore-to-camel-case=true +mybatis.type-aliases-package=com.dbnt.faisp.main.**.model +logging.level.com.atoz_develop.mybatissample.repository=TRACE \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-was1.properties similarity index 84% rename from src/main/resources/application-prod.properties rename to src/main/resources/application-was1.properties index 385020d7..4a29186e 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-was1.properties @@ -1,5 +1,12 @@ +#tomcat tomcat.ajp.protocol=AJP/1.3 -#server.port=80 +tomcat.cluster.enabled=true +#tomcat.cluster.static-member-host=10.187 +#tomcat.cluster.static-member-port=50540 +#tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2} +#tomcat.cluster.receiver-address=118.219.150.34 +#tomcat.cluster.receiver-port=4042 +#tomcat.cluster.receiver-max-threads=4 #file upload spring.servlet.multipart.location=/backup/faisp/uploadFiles diff --git a/src/main/resources/application-was2.properties b/src/main/resources/application-was2.properties new file mode 100644 index 00000000..5a70d4cb --- /dev/null +++ b/src/main/resources/application-was2.properties @@ -0,0 +1,74 @@ +#tomcat +tomcat.ajp.protocol=AJP/1.3 +tomcat.cluster.enabled=true +#tomcat.cluster.static-member-host=118.219.150.34 +#tomcat.cluster.static-member-port=50540 +#tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1} +#tomcat.cluster.receiver-address=118.219.150.34 +#tomcat.cluster.receiver-port=4042 +#tomcat.cluster.receiver-max-threads=4 + +#file upload +spring.servlet.multipart.location=/backup/faisp/uploadFiles +spring.servlet.multipart.max-file-size=200MB +spring.servlet.multipart.max-request-size=500MB + +site.domain=10.187.58.12 + +#file +file.dir.publicBoard=/publicBoard +file.dir.faRpt=/faRpt +file.dir.vulnerable=/vulnerable +file.dir.part=/part +file.dir.equip=/equip +file.dir.sailor=/sailor +file.dir.affair=/affair +file.dir.affair.plan=/affairPlan +file.dir.affair.result=/affairResult +file.dir.editor=/editor +file.dir.sri=/sri +file.dir.ciw=/ciw +file.dir.cia.safty=/cia/safty +file.dir.cia.company=/cia/company +file.dir.cia.foreigner=/cia/foreigner +file.dir.cia.edu=/cia/edu +file.dir.activityCase=/activityCase +file.dir.majorStatus=/majorStatus +file.dir.monitoring=/monitoring +file.dir.intelligenceNetwork=/intelligenceNetwork + +file.dir.affairTemp=/affairTemp + +editor.img.view=/file/editorFileDisplay?fileNm= + +#thymeleaf +spring.thymeleaf.prefix=classpath:templates/ +spring.thymeleaf.check-template-location=true +spring.thymeleaf.suffix=.html +spring.thymeleaf.mode=HTML + +#Datasource Configuration +spring.sql.init.encoding=utf-8 +#maximum-pool-size: CPU core count +spring.datasource.hikari.maximum-pool-size=8 +#postgresql +spring.datasource-main.driverClassName=org.postgresql.Driver +spring.datasource-main.jdbcUrl=jdbc:postgresql://10.187.142.13:5432/experdb +spring.datasource-main.username=faisp +spring.datasource-main.password=dbnt0928! +#tibero +spring.datasource-kwms.driverClassName=com.tmax.tibero.jdbc.TbDriver +spring.datasource-kwms.jdbcUrl=jdbc:tibero:thin:@10.188.171.206:9629:KCGHRDB +spring.datasource-kwms.username=KCGEXT +spring.datasource-kwms.password=kcgextuser + +#jpa +spring.jpa.show-sql=false +spring.jpa.generate-ddl=false +spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + +# MyBatis +mybatis.mapper-locations: mybatisMapper/*.xml +mybatis.configuration.map-underscore-to-camel-case=true +mybatis.type-aliases-package=com.dbnt.faisp.main.**.model +logging.level.com.atoz_develop.mybatissample.repository=TRACE \ No newline at end of file diff --git a/src/main/resources/templates/login/dashboard.html b/src/main/resources/templates/login/dashboard.html index 4430fea5..380e41c1 100644 --- a/src/main/resources/templates/login/dashboard.html +++ b/src/main/resources/templates/login/dashboard.html @@ -7,10 +7,10 @@
-
+
-
대시보드
+