#!/bin/bash

##
## This script can be used after Java version upgrade, to update
##   Java settings for Talend applications / services.
## The Java path is stored in many places and without this script,
##   Talend applications will continue to run with old Java version
##
## Before running this script, check and set three variables below:
## - TALEND_HOME - must be set to Talend home folder (e.g. "/opt/Talend-7.3.1")
## - PROD_VER    - must be set to Product version    (e.g. "7.3.1")
## - JAVA_HOME   - new Java home. This value will be set for Talend applications
##
## The recommended sequence for Java upgrade:
## 1. Install new Java version (the old one still should be in place)
## 2. Stop all Talend services with systemctl stop <service>
## 3. Update this script with actual values for TALEND_HOME, PROD_VER and JAVA_HOME variables
## 4. (If needed, set as executable and then) run this script to update Java for Talend apps
## 5. Start all Talend application (either with systemctl start <service>, or by rebooting)
## 6. (Optional) if needed, the old Java version can be removed later
##
## Important:
##   when upgrading from Java 8 to Java 11, two services does not support this and will not be updated:
##     - Talend Data Quality Portal
##     - Talend Nexus service
##

TALEND_HOME=/opt/Talend-7.3.1
PROD_VER=7.3.1
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.8.10-0.el7_8.x86_64

# This user is used by system services ('talenduser' by default)
SRV_USER=talenduser

# We will modify system files, so we must be running with root privileges
if [ "`id -u`" != "0" ]; then
  echo "This script requires root privileges."
  echo "Re-run this script as root."
  exit 1
fi

# Check that we have 'sed' with in-place feature
if [ "`sed --help | grep -c -e '--in-place'`" = "0" ]; then
  echo "Error: sed version is too old."
  echo "This script requires 'sed' utility that supports in-place file update."
  echo "Upgrade your sed utility version and then re-run this script again."
  exit 1
fi

# Check environment
if [ ! -f ${TALEND_HOME}/uninstall ]; then
  echo "Error: variable TALEND_HOME is wrong: no Talend installation is detected !"
  exit 1
fi

if [ ! -f ${JAVA_HOME}/bin/java ]; then
  echo "Error: variable JAVA_HOME is wrong: Java is not detected at that location"
  exit 1
fi

JAVA_VER=`${JAVA_HOME}/bin/java -version 2>&1 | grep version | sed 's/^[^"]*"//' | sed 's/".*//'`
JAVA_11=`echo $JAVA_VER | sed 's/^11\..*/OK/'`

# Check compatibility: Java 11 can be run only with Talend 7.2, 7.3 or 8.0
if [ "$JAVA_11" = "OK" ]; then
  case "$PROD_VER" in
    7.2.* | 7.3.* | 8.0.* )
      # all is fine
      ;;
    * )
      echo "Error: Java 11 is supported only for Talend 7.2, 7.3 or 8.0"
      exit 1
      ;;
  esac
fi

if [ "`grep -c $SRV_USER /etc/passwd`" = "0" ]; then
  echo "Error: cannot find local user $SRV_USER !"
  echo "This is the user for system services."
  echo "Check script variable SRV_USER and update if needed."
  exit 1
fi

# Extra check - that new Java can be executed by talenduser
SRV_OK=`sudo -u $SRV_USER /bin/bash -c "[[ -x $JAVA_HOME/bin/java ]] && echo OK || echo NOK"`
if [ "$SRV_OK" != "OK" ]; then
  echo "Error: new Java installation is not accessible for $SRV_USER !"
  echo "Check and adjust file rights and then re-run this script."
  exit 1
fi

# Check that Talend services are not running
SRV_LIST=`(cd /etc/systemd/system; ls -1 talend-*-${PROD_VER}.service)`
if [ -z "$SRV_LIST" ]; then
  echo "Error: cannot detect any of Talend $PROD_VER services !"
  echo "Is variable PROD_VER set correctly ?"
  exit 1
fi

for cSrv in $SRV_LIST
do
  cStat=`systemctl is-active $cSrv`
  if [ "$?" = "0" ]; then
    echo "Error: not all Talend services are stopped."
    echo "Stop all Talend services and re-try."
    exit 1
  fi
done

echo Updating Talend services to use Java $JAVA_VER from ${JAVA_HOME} ...

# First updating systemd service descriptor files with new JAVA_HOME
for cSrv in kafka zookeeper nexus cmdline elastic kibana logstash
do
  if [ -f /etc/systemd/system/talend-$cSrv-${PROD_VER}.service ]; then
    if [ "$cSrv" != "nexus" -o "$JAVA_11" != "OK" ]; then
      echo "Updating systemd descriptor for Talend $cSrv service ..."
      sed -i "s|Environment=JAVA_HOME=.*|Environment=JAVA_HOME=$JAVA_HOME|" /etc/systemd/system/talend-$cSrv-${PROD_VER}.service
    fi
  fi
done

# 2nd updating scripts in utils folder
for cScript in dqdict iam mdm tac tds cmdline dataprep tcomp jobserver bpm kafka mongodb
do
  if [ -f $TALEND_HOME/utils/srv_$cScript ]; then
    echo "Updating script utils/srv_$cScript ..."
    sed -i "s|JAVA_HOME=.*|JAVA_HOME=$JAVA_HOME|" $TALEND_HOME/utils/srv_$cScript
  fi
done

# Extra care for dataprep and tcomp services
for cScript in dataprep tcomp
do
  if [ -f $TALEND_HOME/utils/srv_$cScript ]; then
    sed -i "s|if \[ -n \"/.*\" \]; then|if \[ -n \"$JAVA_HOME\" \]; then|" $TALEND_HOME/utils/srv_$cScript
  fi
done

# Updating JAVA_BIN for DataPrep and TCOMP
for cFile in dataprep/start.sh dataprep/services/tcomp/start.sh
do
  if [ -f $TALEND_HOME/$cFile ]; then
    sed -i "s|JAVA_BIN=.*|JAVA_BIN=$JAVA_HOME/bin/java|" $TALEND_HOME/$cFile
  fi
done

# Updating Runtime service
if [ -f $TALEND_HOME/runtime/bin/talend-runtime-$PROD_VER-service ]; then
  echo "Updating Runtime service ..."
  sed -i "s|JAVA_HOME=.*|JAVA_HOME=${JAVA_HOME}|" $TALEND_HOME/runtime/bin/talend-runtime-$PROD_VER-service
fi
if [ -f $TALEND_HOME/runtime/etc/talend-runtime-$PROD_VER-wrapper.conf ]; then
  cFile=$TALEND_HOME/runtime/etc/talend-runtime-$PROD_VER-wrapper.conf
  sed -i "s|JAVA_HOME=.*|JAVA_HOME=${JAVA_HOME}|" $cFile
  if [ "$JAVA_11" = "OK" ]; then
    if [ "`egrep -c -e '^wrapper\.java\.additional\.1=-Djava\.endorsed\.dirs=' $cFile`" = "1" ]; then
      # We need to patch this file against Java 11 (remove endorsed dirs)
      for i in 1 2
      do
        sed -i "s|^wrapper\.java\.additional\.$i=|#wrapper.java.additional.$i=|" $cFile
      done

      for i in 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
      do
        if [ "`grep -c -e \"wrapper\.java\.additional\.$i=\" $cFile`" = "1" ]; then
	  let i2=i-2
	  sed -i "s|wrapper\.java\.additional\.${i}=|wrapper\.java\.additional\.${i2}=|" $cFile
	fi
      done
    fi
  fi
fi

# Updating Job Server service
if [ -f /etc/systemd/system/talend-rjs-${PROD_VER}.service ]; then
  echo "Updating JobServer service ..."
  cFile=/etc/systemd/system/talend-rjs-${PROD_VER}.service
  #Extracts the old Java home
  oldJavaHome=`grep "Environment=JAVA_HOME=" $cFile |sed 's|Environment=JAVA_HOME=||'`
  if [ -n "$oldJavaHome" ]; then
    # Try to remove it from Environment PATH element
    if [ -n "`grep 'Environment=PATH=' $cFile | grep -F \"$oldJavaHome\" `" ]; then
      sed -i "s|\(Environment=PATH=.*\):$oldJavaHome|\1|" $cFile
    fi
  fi
  # Now replace JAVA_HOME
  sed -i "s|Environment=JAVA_HOME=.*|Environment=JAVA_HOME=$JAVA_HOME|" $cFile
  # and add JAVA_HOME/bin to the PATH
  sed -i "s|\(Environment=PATH=.*\)|\1:$JAVA_HOME/bin|" $cFile

  # Update Agent scripts
  for cScript in start_rs.sh stop_rs.sh
  do
    if [ -f $TALEND_HOME/jobserver/agent/$cScript ]; then
      sed -i "s|MY_JAVA=.*|MY_JAVA=$JAVA_HOME/bin/java|" $TALEND_HOME/jobserver/agent/$cScript
    fi
  done
fi

# Update TDQ Portal (only if Java version != 11)
if [ -f /etc/systemd/system/talend-tdqp-${PROD_VER}.service ]; then
  if [ "$JAVA_11" != "OK" ]; then
    echo "Updating TDQ Portal service ..."
    for cDescr in talend-tdqp talend-tdqp-db
    do
      if [ -f /etc/systemd/system/${cDescr}-${PROD_VER}.service ]; then
        sed -i "s|Environment=JAVA_HOME=.*|Environment=JAVA_HOME=${JAVA_HOME}|" /etc/systemd/system/${cDescr}-${PROD_VER}.service
      fi
    done
    if [ -f $TALEND_HOME/utils/srv_tdqp ]; then
      sed -i "s|JAVA_HOME=.*|JAVA_HOME=${JAVA_HOME}|" $TALEND_HOME/utils/srv_tdqp
    fi
  fi
fi

# Reload updated Systemd descriptor files
systemctl daemon-reload

echo "Java version update is completed."

if [ -f /etc/systemd/system/talend-nexus-${PROD_VER}.service -a "$JAVA_11" = "OK" ]; then
  echo "Warning: Talend Nexus service was NOT updated to use Java 11"
fi

if [ -f /etc/systemd/system/talend-tdqp-${PROD_VER}.service -a "$JAVA_11" = "OK" ]; then
  echo "Warning: Talend DQ Portal service was NOT updated to use Java 11"
fi