User Tools

Site Tools


development:grails:grails3applicationguide

Grails 3 Application Guide

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

Configuration File

User Environment Variable on the server

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}

Access to Variable in application.yml

User annotation org.springframework.beans.factory.annotation.Value

  @Value('${tomcat.jvmRoute}')
  String jvmRouteString

Environment Specific War/Jar

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

  • multiple different war for each environment
  • multiple build process may required for each environment

Those drawbacks could be overcome with more automated build process

Graceful Shutdown

Do “kill <pid>“ (no options such as -9) will do graceful shutdown and will call BootStrap.destroy() method.

Configure Tomcat

Enable JMX and jvmRoute

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
  }
}

Single Sign On

Load-balancer Set-Up (support_page example)

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
development/grails/grails3applicationguide.txt · Last modified: 2021/06/25 10:09 by 127.0.0.1