Thanks to Grails 3 is based on Spring Boot, we can use tons of cool feature from Spring Boot and Grails 3 is very friendly to amazing other Spring Frameworks.
Document correct on Grails 3.2.6
Spring Boot inject environment variable when application starts meaning value of SUPPORT_PAGE_JVM_ROUTE in app handler, not one in machine that builds war
tomcat:
jvmRoute: ${SUPPORT_PAGE_JVM_ROUTE}
User annotation org.springframework.beans.factory.annotation.Value
@Value('${tomcat.jvmRoute}')
String jvmRouteString
We can create environment specific War/Jar file. What you need is environment specific application.yml
For instance, support page war for errigalqa, you need to create application-errigalqa.yml You don't need to redefine all config values in application.yml, only ones you want to override such as dataSource.
To build war, all you need is put “-Dgrails.env=errigalqa” before grails command.
Benefit of this is very simple deployment. You don't need to put configuration file, tomcat container on deployment server. In practice, you may need startup script that define Environment Variable.
Drawback of this are
Those drawbacks could be overcome with more automated build process
Do “kill <pid>“ (no options such as -9) will do graceful shutdown and will call BootStrap.destroy() method.
Part of Application.yml
---
tomcat:
ajp:
port: 8018
remoteauthentication: false
enabled: true
# Environment Variable will be loaded when application starts, i.e. at app handler
jvmRoute: ${SUPPORT_PAGE_JVM_ROUTE}
Configuration Bean for Tomcat
package com.errigal.support.page.systemconfig
import org.apache.catalina.connector.Connector
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
/***************************************************************
* Copyright (c) 2017 Errigal Inc.
*
* This software is the confidential and proprietary information
* of Errigal, Inc. You shall not disclose such confidential
* information and shall use it only in accordance with the
* license agreement you entered into with Errigal.
*
***************************************************************/
/**
* Start AJP for load balancer
* https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html
* https://blog.swdev.ed.ac.uk/2015/06/24/adding-embedded-tomcat-ajp-support-to-a-spring-boot-application/
* https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
*
* @ConfigurationProperties this let this class only load property with prefix tomcat
*
* User: wonlee
* Date: 15/03/2017
*/
@Configuration
@ConfigurationProperties(prefix = "tomcat")
class TomcatConfiguration {
@Value('${tomcat.ajp.port}')
int ajpPort
@Value('${tomcat.ajp.remoteauthentication}')
String remoteAuthentication
@Value('${tomcat.ajp.enabled}')
boolean tomcatAjpEnabled
@Value('${tomcat.jvmRoute}')
String jvmRouteString
@Bean
public EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory()
if (tomcatAjpEnabled) {
Connector ajpConnector = new Connector("AJP/1.3")
ajpConnector.setProtocol("AJP/1.3")
ajpConnector.setPort(ajpPort)
ajpConnector.setSecure(false)
ajpConnector.setAllowTrace(false)
ajpConnector.setScheme("http")
tomcat.addAdditionalTomcatConnectors(ajpConnector)
}
/*
* Set jvmRoute which is required by jk_mod (load balancer)
* http://stackoverflow.com/questions/31166336/how-to-set-embedded-tomcat-jvmroute
*
* Tomcat uses System Property to set jvmRoute
* https://tomcat.apache.org/tomcat-8.5-doc/config/systemprops.html
*
* jvmRoute won't be added to cookie name if it is empty string
*/
System.setProperty("jvmRoute", jvmRouteString)
return tomcat
}
}
on: EXTLB - Prepare new Load Balancer setting cd /etc/httpd/conf sudo cp mod-jk.conf mod-jk.conf.bk sudo vi mod-jk.conf.bk Append following lines at the end JkMount /Support/ SupportPageLoadBalancer JkMount /Support/* SupportPageLoadBalancer JkMount /Support SupportPageLoadBalancer sudo cp workers.properties workers.properties.bk sudo vi workers.properties.bk Line2, at the end of "worker.list=", add "SupportPageLoadBalancer" to the list So the line has to look like worker.list=jkstatus,NocPortalLoadBalancer,SnmpManagerLoadBalancer,SnmpManagerEMSLoadBalancer,ReportingManagerLoadBalancer,TicketerLoadBalancer,CasLoadBalancer,SoapLoadBalancer,SupportPageLoadBalancer Add following line after Soap Worker Config lines # Configure SupportPage worker.SupportPageLoadBalancer.type=lb worker.SupportPageLoadBalancer.sticky_session=1 worker.SupportPageWorker1.reference=worker.ajptemplate worker.SupportPageWorker1.host=extapps1.ext worker.SupportPageWorker1.port=8018 worker.SupportPageWorker1.reply_timeout=600000 worker.SupportPageWorker2.reference=worker.ajptemplate worker.SupportPageWorker2.host=extapps2.ext worker.SupportPageWorker2.port=8018 worker.SupportPageWorker2.reply_timeout=600000 Append following lines at the end worker.SupportPageLoadBalancer.balance_workers=SupportPageWorker1,SupportPageWorker2
Do restart the HTTPD: sudo service httpd restart
Setup SSO for Support Page
APPS1 & APPS2
cd /usr/local/conf/cas/services/
touch support_page-1008.json
vi support_page-1008.json
{
"@class" : "org.jasig.cas.services.RegexRegisteredService",
"serviceId" : "https://nocportal.extenetsystems.com/Support/.*",
"name" : "Support Page",
"id" : 1008
}
Change will be applied automatically to CAS