Charm: ~robert-ayres:precise/tomcat   Revision: 1   Hook: jndi-db-pgsql-relation-changed
#!/bin/bash

set -e

VERSION=`config-get tomcat_version`
if [ \( "${VERSION}" != "tomcat6" \) -a \( "${VERSION}" != "tomcat7" \) ]; then
  juju-log --log-level CRITICAL "Tomcat version should be one of: tomcat6 or tomcat7"
  exit 1
fi

REMOTE_SERVICE=${JUJU_REMOTE_UNIT%/*}
SERVICE=${JUJU_UNIT_NAME%/*}
TEMP=/var/tmp

add_file_row () {
  file=$1
  if [ -e "${file}" ]; then
    grep -v "^$2"$'\t' "${file}" > "${file}.new" || true
    mv "${file}.new" "${file}"
  fi
  shift
  echo_delimited $'\t' "$@" >> "${file}"
}

add_jndi_memcached_server () {
  juju-log "Adding memcached server ${JUJU_REMOTE_UNIT} to jndi configuration"
  add_file_row "/etc/${VERSION}/${REMOTE_SERVICE}.jndi_mem" "${JUJU_REMOTE_UNIT}" `relation-get host`:`relation-get port`
}

add_jndi_terracotta_server () {
  juju-log "Adding terracotta server ${JUJU_REMOTE_UNIT} to jndi configuration"
  add_file_row "/etc/${VERSION}/${REMOTE_SERVICE}.jndi_tc" "${JUJU_REMOTE_UNIT}" `relation-get private-address`:9510
}

add_server () {
  remote_address=`relation-get private-address`
  unique_id=`unique_id`
  add_file_row /etc/${VERSION}/cluster.members "${JUJU_REMOTE_UNIT}" ${remote_address} ${unique_id}
  dir=`dotdee -d /etc/${VERSION}/server.xml`
  if [ -e "${dir}/34-static-interceptor" ]; then
    (umask 0027; config_static_member ${remote_address} ${unique_id} > "${dir}/35-`escape_unit_name "${JUJU_REMOTE_UNIT}"`")
    dotdee -u /etc/${VERSION}/server.xml
    restart_required=true
  fi
}

add_terracotta_server () {
  juju-log "Adding terracotta server ${JUJU_REMOTE_UNIT} to configuration"
  add_file_row /etc/${VERSION}/terracotta.servers "${JUJU_REMOTE_UNIT}" `relation-get private-address`:9510
}

check_checksum () {
  if [ `md5sum "$1" | cut -d " " -f 1` != $2 ]; then
    juju-log --log-level CRITICAL "Checksum of $1 failed"
    exit 1
  fi
}

check_database () {
  if [ -z "`relation-get database`" ]; then
    juju-log "Database not ready"
    exit 0
  fi
}

check_memcached () {
  if [ -z "`relation-get host`" ]; then
    juju-log "Memcached not ready"
    exit 0
  fi
}

check_website () {
  if [ -n "`relation-get hostname "${JUJU_UNIT_NAME}"`" ]; then
    exit 0
  fi
}

close_port () {
  juju-log "Closing port $1 for ${VERSION}"
  close-port $1
}

close_prefixed_port () {
  for port in "$1/$2"*; do
    [ -e "${port}" ] || continue
    p=${port#$1/$2}
    close_port ${p}
    rm -f "${port}"
  done
}

config_cluster () {
  echo -n '      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6"'
  if [ -z "$1" ]; then
    echo -n ' channelStartOptions="3"'
  fi
  echo ">"
}

config_clustering () {
  (umask 0027; cat <<"EOF" > "$1/31-manager")
        <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>
        <Channel className="org.apache.catalina.tribes.group.GroupChannel">
EOF
  (umask 0027; cat <<EOF > "$1/33-cluster")
          <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="$2" port="4000" autoBind="0" selectorTimeout="5000" maxThreads="6"/>
          <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
          </Sender>
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
EOF
  (umask 0027; cat <<"EOF" > "$1/37-cluster")
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
        </Channel>
        <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
        <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
        <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
        <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
      </Cluster>
EOF
}

config_datasource_resource () {
  name=`xmlstarlet esc "$1"`
  echo -n "    <Resource name=\"${name}\" global=\"${name}\" auth=\"Container\" type=\"javax.sql.DataSource\" driverClassName=\"`xmlstarlet esc "$2"`\" url=\"`xmlstarlet esc "$3"`\" username=\"`xmlstarlet esc "$4"`\" password=\"`xmlstarlet esc "$5"`\""
  IFS=";" read -a tokens <<<"$6"
  for token in "${tokens[@]}"; do
    IFS="=" read name value <<<"${token}"
    if [ -n "${name}" ]; then
      echo -n " ${name}=\"`xmlstarlet esc "${value}"`\""
    fi
  done
  echo "/>"
}

config_environment () {
  echo "    <Environment name=\"`xmlstarlet esc "$1"`\" value=\"`xmlstarlet esc "$2"`\" type=\"$3\"/>"
}

config_http_connector () {
  echo -n "    <Connector port=\"$1\" protocol=\""
  case $2 in
    bio)
      echo -n "org.apache.coyote.http11.Http11Protocol"
      ;;
    nio)
      echo -n "org.apache.coyote.http11.Http11NioProtocol"
      ;;
  esac
  echo -n '" connectionTimeout="20000" URIEncoding="UTF-8"'
  if [ -n "$3" ]; then
    echo -n " redirectPort=\"$3\""
  fi
  if [ -n "$4" ]; then
    echo -n " SSLEnabled=\"true\" scheme=\"https\" secure=\"true\" sslProtocol=\"TLS\" keystoreFile=\"/etc/${VERSION}/keystore.p12\" keystoreType=\"pkcs12\" keystorePass=\"`xmlstarlet esc "$5"`\""
  fi
  echo "/>"
}

config_jmx_listener () {
  echo '  <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002"/>'
}

config_jmx_passwords () {
  cat <<EOF
monitorRole $1
controlRole $2
EOF
}

config_multicast_membership () {
  echo "          <Membership className=\"org.apache.catalina.tribes.membership.McastService\" address=\"$1\" port=\"$2\" frequency=\"500\" dropTime=\"3000\"/>"
}

config_resource_link () {
  name=`xmlstarlet esc "$1"`
  echo "  <ResourceLink name=\"${name}\" global=\"${name}\" type=\"$2\"/>"
}

config_static_member () {
  echo "            <Member className=\"org.apache.catalina.tribes.membership.StaticMember\" port=\"4000\" host=\"$1\" uniqueId=\"$2\"/>"
}

config_static_membership () {
  (umask 0027; echo '          <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">' > "$1/34-static-interceptor")
  (umask 0027; echo "          </Interceptor>" > "$1/36-static-interceptor")
}

config_terracotta_valve () {
  echo "  <Valve className=\"$1\" tcConfigUrl=\"$2\"/>"
}

config_users () {
  cat <<"EOF"
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
  <role rolename="admin-gui"/>
  <role rolename="manager-gui"/>
  <role rolename="manager-status"/>
EOF
  if [ $1 = True ]; then
    if [ -n "$2" -a -n "$3" ]; then
      echo "  <user username=\"`xmlstarlet esc "$2"`\" password=\"`xmlstarlet esc "$3"`\" roles=\"admin-gui,manager-gui\"/>"
    fi
    if [ -n "$4" -a -n "$5" ]; then
      echo "  <user username=\"`xmlstarlet esc "$4"`\" password=\"`xmlstarlet esc "$5"`\" roles=\"manager-status\"/>"
    fi
  fi
  echo "</tomcat-users>"
}

configure_clustering () {
  if [ `config-get cluster_enabled` = True ]; then
    if [ ! -e "$1/31-manager" ]; then
      config_clustering "$1" `unit-get private-address`
    fi
    multicast=`config-get multicast`
    if [ ${multicast} = True ]; then
      if [ ! -e "$1/31-cluster-multicast" ]; then
        rm -f "$1/31-cluster-static" "$1"/3[4-6]-*
        (umask 0027; config_cluster true > "$1/31-cluster-multicast")
      fi
      (umask 0027; config_multicast_membership `config-get multicast_address` `config-get multicast_port` > "$1/32-multicast")
    else
      if [ ! -e "$1/31-cluster-static" ]; then
        rm -f "$1/31-cluster-multicast" "$1/32-multicast"
        (umask 0027; config_cluster "" > "$1/31-cluster-static")
        config_static_membership "$1"
        if [ -e /etc/${VERSION}/cluster.members ]; then
          while IFS=$'\t' read unit address unique_id; do
            (umask 0027; config_static_member ${address} ${unique_id} > "$1/35-`escape_unit_name "${unit}"`")
          done < /etc/${VERSION}/cluster.members
        fi
      fi
    fi
  else
    rm -f "$1"/3[1-7]-*
  fi
}

configure_connectors () {
  http_port=`config-get http_port`
  http_connector=`config-get http_connector`
  https_enabled=`config-get https_enabled`
  https_port=`config-get https_port`
  if [ ! -e "$1/24-http-${http_port}" ]; then
    close_prefixed_port "$1" 24-http-
    open_port ${http_port}
  fi
  (umask 0027; config_http_connector ${http_port} ${http_connector} ${https_port} "" "" > "$1/24-http-${http_port}")
  if [ ${https_enabled} = True ]; then
    if [ ! -e "$1/25-https-${https_port}" ]; then
      close_prefixed_port "$1" 25-https-
      open_port ${https_port}
    fi
    if [ ! -e /etc/${VERSION}/keystore.generated ]; then
      keystore_password=`config-get keystore_password`
    else
      keystore_password=`< /etc/${VERSION}/keystore.generated`
    fi
    (umask 0027; config_http_connector ${https_port} ${http_connector} "" true "${keystore_password}" > "$1/25-https-${https_port}")
  else
    close_prefixed_port "$1" 25-https-
  fi
  if [ \( ${http_port} -le 1023 \) -o \( \( ${https_enabled} = True \) -a \( ${https_port} -le 1023 \) \) ]; then
    if [ ! -e "$2/54-authbind" ]; then
      echo "AUTHBIND=yes" > "$2/54-authbind"
    fi
  else
    rm -f "$2/54-authbind"
  fi
}

configure_datasources () {
  server_dir=`dotdee -d /etc/${VERSION}/server.xml`
  rm -f "${server_dir}"/15-*
  context_dir=`dotdee -d /etc/${VERSION}/context.xml`
  rm -f "${context_dir}"/20-*
  for name in "${!jndi_db_service[@]}"; do
    service=${jndi_db_service[${name}]}
    database=${jndi_db_database[${name}]:-${SERVICE}}
    if [ -n "${service}" ]; then
      if [ -n "${database}" -a -e "/etc/${VERSION}/${service}_${database}.db" ]; then
        create_datasource "${name}" "/etc/${VERSION}/${service}_${database}.db" "${server_dir}" "${context_dir}"
      elif [ -e "/etc/${VERSION}/${service}.db" ]; then
        create_datasource "${name}" "/etc/${VERSION}/${service}.db" "${server_dir}" "${context_dir}"
      fi
    fi
  done
  dotdee -u /etc/${VERSION}/server.xml
  dotdee -u /etc/${VERSION}/context.xml
}

configure_java () {
  jmx_opts=""
  if [ `config-get jmx_enabled` = True ]; then
    if [ ! -e "$1/04-jmx-listener" ]; then
      (umask 0027; config_jmx_listener > "$1/04-jmx-listener")
    fi
    jmx_opts="-Dcom.sun.management.jmxremote.ssl=false"
    jmx_opts+=" -Dcom.sun.management.jmxremote.access.file=/etc/${VERSION}/jmxremote.access"
    jmx_opts+=" -Dcom.sun.management.jmxremote.password.file=/etc/${VERSION}/jmxremote.password"
    if [ `config-get jmx_localhost` = True ]; then
      jmx_opts+=" -Djava.rmi.server.hostname=localhost"
    else
      jmx_opts+=" -Djava.rmi.server.hostname=`unit-get private-address`"
    fi
  else
    rm -f "$1/04-jmx-listener"
  fi
  debug_opts=""
  if [ `config-get debug_enabled` = True ]; then
    debug_opts="-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n"
  fi
  echo -n 'JAVA_OPTS="-Djava.awt.headless=true' ${debug_opts} ${jmx_opts} `config-get java_opts` \
    > "$2/60-javaopts"; echo '"' >> "$2/60-javaopts"
}

configure_keystore () {
  keystore=`config-get keystore`
  if [ -n "${keystore}" ]; then
    (umask 0027; base64 -d <<<"${keystore}" > /etc/${VERSION}/keystore.p12)
    chown :${VERSION} /etc/${VERSION}/keystore.p12
    rm -f /etc/${VERSION}/keystore.generated
  else
    if [ ! -e /etc/${VERSION}/keystore.generated ]; then
      generate_keystore
    fi
  fi
}

configure_jndi_memcached () {
  server_dir=`dotdee -d /etc/${VERSION}/server.xml`
  rm -f "${server_dir}"/12-memcached-*
  context_dir=`dotdee -d /etc/${VERSION}/context.xml`
  rm -f "${context_dir}"/15-memcached-*
  for name in "${!jndi_memcached_service[@]}"; do
    service=${jndi_memcached_service[${name}]}
    if [ -n "${service}" -a -e "/etc/${VERSION}/${service}.jndi_mem" ]; then
      jndi_name=`escape_name ${name}`
      (umask 0027; config_environment "${name}" "`format_memcached_servers "/etc/${VERSION}/${service}.jndi_mem"`" java.lang.String > "${server_dir}/12-memcached-${jndi_name}")
      config_resource_link "${name}" java.lang.String \
        > "${context_dir}/15-memcached-${jndi_name}"
    fi
  done
  dotdee -u /etc/${VERSION}/server.xml
  dotdee -u /etc/${VERSION}/context.xml
}

configure_jndi_terracotta () {
  server_dir=`dotdee -d /etc/${VERSION}/server.xml`
  rm -f "${server_dir}"/12-terracotta-*
  context_dir=`dotdee -d /etc/${VERSION}/context.xml`
  rm -f "${context_dir}"/15-terracotta-*
  for name in "${!jndi_terracotta_service[@]}"; do
    service=${jndi_terracotta_service[${name}]}
    if [ -n "${service}" -a -e "/etc/${VERSION}/${service}.jndi_tc" ]; then
      jndi_name=`escape_name ${name}`
      (umask 0027; config_environment "${name}" `format_terracotta_servers "/etc/${VERSION}/${service}.jndi_tc"` java.lang.String > "${server_dir}/12-terracotta-${jndi_name}")
      config_resource_link "${name}" java.lang.String \
        > "${context_dir}/15-terracotta-${jndi_name}"
    fi
  done
  dotdee -u /etc/${VERSION}/server.xml
  dotdee -u /etc/${VERSION}/context.xml
}

configure_mysql () {
  juju-log "Configuring mysql for ${REMOTE_SERVICE}"
  database=`relation-get database "${JUJU_UNIT_NAME}"`
  host=`relation-get db_host`
  if [ -n "${database}" -a -n "${host}" ]; then
    user=`relation-get username "${JUJU_UNIT_NAME}"`
    password=`relation-get password`
    if [ -e "/etc/${VERSION}/${REMOTE_SERVICE}_${database}.db.part" ]; then
      juju-log "Adding database ${database}"
      echo -e "com.mysql.jdbc.Driver\tjdbc:mysql://${host}/${database}\t${user}\t${password}" \
        > "/etc/${VERSION}/${REMOTE_SERVICE}_${database}.db.part"
      mv "/etc/${VERSION}/${REMOTE_SERVICE}_${database}.db.part" \
        "/etc/${VERSION}/${REMOTE_SERVICE}_${database}.db"
      config_required=true
    fi
  fi
  for part in "/etc/${VERSION}/${REMOTE_SERVICE}_"*.db.part; do
    [ -e "${part}" ] || continue
    file=`basename "${part}"`
    database=`sed -e "s/^${REMOTE_SERVICE}_\(.\+\)\.db\.part$/\1/" <<<"${file}"`
    unit=${JUJU_UNIT_NAME##*/}
    relation-set hostname=`unit-get private-address` "database=${database}" "username=${unit}-${database}"
    exit 0
  done
}

configure_postgresql () {
  juju-log "Configuring postgresql for ${REMOTE_SERVICE}"
  host=`relation-get host`
  database=`relation-get database`
  user=`relation-get user`
  password=`relation-get password`
  (umask 0077; echo -e "org.postgresql.Driver\tjdbc:postgresql://${host}/${database}\t${user}\t${password}" > "/etc/${VERSION}/${REMOTE_SERVICE}.db")
}

configure_terracotta () {
  juju-log "Configuring terracotta"
  dir=`dotdee -d /etc/${VERSION}/context.xml`
  if [ ${VERSION} != tomcat6 ]; then
    class=org.terracotta.session.TerracottaTomcat70xSessionValve
  else
    class=org.terracotta.session.TerracottaTomcat60xSessionValve
  fi
  config_terracotta_valve ${class} `format_terracotta_servers /etc/${VERSION}/terracotta.servers` \
    > "${dir}/45-terracotta"
  dotdee -u /etc/${VERSION}/context.xml
}

configure_tomcat () {
  juju-log "Configuring ${VERSION}"
  configure_keystore
  server_dir=`dotdee -d /etc/${VERSION}/server.xml`
  defaults_dir=`dotdee -d /etc/default/${VERSION}`
  configure_connectors "${server_dir}" "${defaults_dir}"
  configure_clustering "${server_dir}"
  configure_java "${server_dir}" "${defaults_dir}"
  dotdee -u /etc/${VERSION}/server.xml
  dotdee -u /etc/default/${VERSION}
  config_jmx_passwords "`config-get jmx_monitor_password`" "`config-get jmx_control_password`" \
    > /etc/${VERSION}/jmxremote.password
  manager_enabled=`config-get manager_enabled`
  config_users ${manager_enabled} "`config-get admin_username`" \
    "`config-get admin_password`" "`config-get status_username`" \
    "`config-get status_password`" > /etc/${VERSION}/tomcat-users.xml
  if [ ${manager_enabled} = True ]; then
    install_tomcat_admin
  else
    remove_tomcat_admin
  fi
  configure_jndi_memcached
  configure_jndi_terracotta
  configure_datasources
}

configure_website () {
  juju-log "Configuring website"
  relation-set hostname=`unit-get private-address` port=`config-get http_port` https-port=`config-get https_port`
}

create_datasource () {
  IFS=$'\t' read driver url user password < "$2"
  jndi_name=`escape_name "$1"`
  (umask 0027; config_datasource_resource "$1" ${driver} ${url} "${user}" "${password}" "${jndi_db_options[$1]}" > "$3/15-${jndi_name}")
  config_resource_link "$1" javax.sql.DataSource > "$4/20-${jndi_name}"
}

create_mysql_datasources () {
  for name in "${!jndi_db_service[@]}"; do
    service=${jndi_db_service[${name}]}
    if [ "${service}" = "${REMOTE_SERVICE}" ]; then
      database=${jndi_db_database[${name}]:-${SERVICE}}
      if [ ! -e "/etc/${VERSION}/${service}_${database}.db.part" ]; then
        (umask 0077; touch "/etc/${VERSION}/${service}_${database}.db.part")
      fi
    fi
  done
}

create_relation_id () {
  echo "${REMOTE_SERVICE}" > /etc/${VERSION}/${JUJU_RELATION_ID}.relation
}

create_terracotta_log_directory () {
  if [ ! -e /var/log/terracotta ]; then
    (umask 0027; mkdir /var/log/terracotta)
    chown ${VERSION}:adm /var/log/terracotta
  fi
}

destroy_db_relation () {
  set_relation_id
  remove_db
  parse_jndi_db_config
  configure_datasources
  restart_tomcat
  remove_relation_id
}

echo_delimited () {
  d=$1
  echo -n "$2"
  shift 2
  for arg; do
    echo -n "${d}${arg}"
  done
  echo
}

escape_name () {
  name=${1//%/%25}
  name=${name//\//%2F}
  echo "${name}"
}

escape_unit_name () {
  echo ${1//\//-}
}

format_memcached_servers () {
  cut -f 2 "$1" | cut -d $'\n' -f 1- --output-delimiter=" "
}

format_terracotta_servers () {
  cut -f 2 "$1" | cut -d $'\n' -f 1- --output-delimiter=,
}

generate_keystore () {
  juju-log "Generating self-signed certificate..."
  (umask 0077; pwgen -s 16 > /etc/${VERSION}/keystore.generated)
  (umask 0027; openssl req -x509 -subj "/CN=`escape_unit_name ${JUJU_UNIT_NAME}`" -days 1825 -newkey rsa:2048 -nodes -keyout /dev/stdout 2> /dev/null | openssl pkcs12 -export -out /etc/${VERSION}/keystore.p12 -passout fd:3 3< /etc/${VERSION}/keystore.generated 2> /dev/null)
  chown :${VERSION} /etc/${VERSION}/keystore.p12
}

install_jmx () {
  juju-log "Downloading catalina jmx jar..."
  url=`config-get jmx_jar_url`
  wget -nv -c -P "${TEMP}" ${url}
  dist=`basename ${url}`
  check_checksum "${TEMP}/${dist}" `config-get jmx_jar_md5`

  juju-log "Installing catalina jmx jar..."
  cp "${TEMP}/${dist}" /usr/share/${VERSION}/lib
}

install_mysql () {
  if [ ! -e /usr/share/${VERSION}/lib/mysql-connector-java.jar ]; then
    juju-log "Installing mysql jdbc driver..."
    apt-get -y install libmysql-java
    (cd /usr/share/${VERSION}/lib; ln -s ../../java/mysql-connector-java.jar)
  fi
}

install_postgresql () {
  if [ ! -e /usr/share/${VERSION}/lib/postgresql.jar ]; then
    juju-log "Installing postgresql jdbc driver..."
    apt-get -y install libpg-java
    (cd /usr/share/${VERSION}/lib; ln -s ../../java/postgresql.jar)
  fi
}

install_terracotta () {
  if [ ! -e /usr/local/lib/terracotta ]; then
    juju-log "Downloading terracotta..."
    url=`config-get terracotta_url`
    wget -nv -c -P "${TEMP}" "${url}"
    dist=`basename ${url}`
    check_checksum "${TEMP}/${dist}" `config-get terracotta_md5`

    juju-log "Installing terracotta..."
    tar -C /usr/local/lib -xzf "${TEMP}/${dist}"
    (cd /usr/local/lib; ln -s terracotta-* terracotta)
    (cd /usr/share/${VERSION}/lib; ln -s ../../../local/lib/terracotta/sessions/terracotta-session-*.jar)
    (cd /usr/share/${VERSION}/lib; ln -s ../../../local/lib/terracotta/common/terracotta-toolkit-*.jar)
  fi
}

install_tomcat () {
  juju-log "Installing ${VERSION} packages..."
  packages=${VERSION}
  if [ ${VERSION} = tomcat6 ]; then
    packages+=" tomcat6-extras"
  fi
  apt-get -y install ${packages} wget dotdee xmlstarlet pwgen dnsutils
  if [ ${VERSION} != tomcat6 ]; then
    install_jmx
  fi
  service ${VERSION} stop 2> /dev/null || true
  service dotdee stop 2> /dev/null || true
  cp /dev/null /etc/init/dotdee.conf

  remove_config /etc/${VERSION}/server.xml
  cp /dev/null /etc/${VERSION}/server.xml
  chmod o-r /etc/${VERSION}/server.xml
  chown :${VERSION} /etc/${VERSION}/server.xml
  dotdee -s /etc/${VERSION}/server.xml
  dir=`dotdee -d /etc/${VERSION}/server.xml`
  (umask 0027; cp files/server.xml.d/[0-9][0-9]* "${dir}"; cp files/server.xml.d/${VERSION}/* "${dir}")
  dotdee -u /etc/${VERSION}/server.xml
  remove_config /etc/${VERSION}/context.xml
  cp /dev/null /etc/${VERSION}/context.xml
  dotdee -s /etc/${VERSION}/context.xml
  dir=`dotdee -d /etc/${VERSION}/context.xml`
  cp files/context.xml.d/* "${dir}"
  dotdee -u /etc/${VERSION}/context.xml
  remove_config /etc/default/${VERSION}
  dotdee -s /etc/default/${VERSION}
  cp files/jmxremote.access /etc/${VERSION}
  (umask 0027; cp /dev/null /etc/${VERSION}/jmxremote.password)
  chown :${VERSION} /etc/${VERSION}/jmxremote.password
  rm -rf /var/lib/${VERSION}/webapps/*
  rm -f /etc/${VERSION}/Catalina/localhost/*
}

install_tomcat_admin () {
  if ! dpkg -s ${VERSION}-admin &> /dev/null; then
    juju-log "Installing admin packages..."
    apt-get -y install ${VERSION}-admin
  fi
}

obtain_tomcat_lock () {
  if [ -e /etc/${VERSION} ]; then
    (umask 0077; touch /etc/${VERSION}/tomcat.lock)
    exec 9> /etc/${VERSION}/tomcat.lock; flock 9
  fi
}

open_port () {
  juju-log "Opening port $1 for ${VERSION}"
  open-port $1
}

parse_jndi_db_config () {
  unset jndi_db_service jndi_db_database jndi_db_options
  declare -Ag jndi_db_service jndi_db_database jndi_db_options
  IFS="," read -a tokens <<<"`config-get jndi_db_config`"
  for token in "${tokens[@]}"; do
    IFS=":" read name service database options other <<<"${token}"
    if [ -n "${name}" ]; then
      jndi_db_service[${name}]=${service}
      jndi_db_database[${name}]=${database}
      jndi_db_options[${name}]=${options}
    fi
  done
}

parse_jndi_memcached_config () {
  unset jndi_memcached_service
  declare -Ag jndi_memcached_service
  IFS="," read -a tokens <<<"`config-get jndi_memcached_config`"
  for token in "${tokens[@]}"; do
    IFS=":" read name service <<<"${token}"
    if [ -n "${name}" ]; then
      jndi_memcached_service[${name}]=${service}
    fi
  done
}

parse_jndi_terracotta_config () {
  unset jndi_terracotta_service
  declare -Ag jndi_terracotta_service
  IFS="," read -a tokens <<<"`config-get jndi_terracotta_config`"
  for token in "${tokens[@]}"; do
    IFS=":" read name service <<<"${token}"
    if [ -n "${name}" ]; then
      jndi_terracotta_service[${name}]=${service}
    fi
  done
}

release_tomcat_lock () {
  exec 9>&-
}

remove_config () {
  if dotdee -d "$1" 2> /dev/null; then
    dotdee --undo "$1"
    rm -rf "/etc/dotdee$1" "/etc/dotdee$1.d"
  fi
}

remove_db () {
  juju-log "Removing database for ${REMOTE_SERVICE}"
  rm -f "/etc/${VERSION}/${REMOTE_SERVICE}_"*.db \
    "/etc/${VERSION}/${REMOTE_SERVICE}_"*.db.part \
    "/etc/${VERSION}/${REMOTE_SERVICE}.db"
}

remove_file_row () {
  if [ -e "$1" ]; then
    if grep -v "^$2"$'\t' "$1" > "$1.new"; then
      mv "$1.new" "$1"
    else
      rm -f "$1" "$1.new"
    fi
  fi
}

remove_jndi_memcached () {
  juju-log "Removing memcached jndi configuration"
  rm -f "/etc/${VERSION}/${REMOTE_SERVICE}.jndi_mem"
}

remove_jndi_memcached_server () {
  juju-log "Removing memcached server ${JUJU_REMOTE_UNIT} from jndi configuration"
  remove_file_row "/etc/${VERSION}/${REMOTE_SERVICE}.jndi_mem" "${JUJU_REMOTE_UNIT}"
}

remove_jndi_terracotta () {
  juju-log "Removing terracotta jndi configuration"
  rm -f "/etc/${VERSION}/${REMOTE_SERVICE}.jndi_tc"
}

remove_jndi_terracotta_server () {
  juju-log "Removing terracotta server ${JUJU_REMOTE_UNIT} from jndi configuration"
  remove_file_row "/etc/${VERSION}/${REMOTE_SERVICE}.jndi_tc" "${JUJU_REMOTE_UNIT}"
}

remove_relation_id () {
  rm -f /etc/${VERSION}/${JUJU_RELATION_ID}.relation
}

remove_server () {
  remove_file_row /etc/${VERSION}/cluster.members "${JUJU_REMOTE_UNIT}"
  dir=`dotdee -d /etc/${VERSION}/server.xml`
  if [ -e "${dir}/34-static-interceptor" ]; then
    rm -f "${dir}/35-`escape_unit_name "${JUJU_REMOTE_UNIT}"`"
    dotdee -u /etc/${VERSION}/server.xml
    restart_required=true
  fi
}

remove_terracotta () {
  juju-log "Removing terracotta"
  rm -f /etc/${VERSION}/terracotta.servers
  dir=`dotdee -d /etc/${VERSION}/context.xml`
  rm -f "${dir}/45-terracotta"
  dotdee -u /etc/${VERSION}/context.xml
}

remove_terracotta_server () {
  juju-log "Removing terracotta server ${JUJU_REMOTE_UNIT} from configuration"
  remove_file_row /etc/${VERSION}/terracotta.servers "${JUJU_REMOTE_UNIT}"
}

remove_tomcat_admin () {
  if dpkg -s ${VERSION}-admin &> /dev/null; then
    juju-log "Removing admin packages..."
    dpkg -P ${VERSION}-admin
  fi
}

restart_tomcat () {
  if service ${VERSION} status > /dev/null; then
    juju-log "Restarting ${VERSION}"
    service ${VERSION} restart
  fi
}

set_relation_id () {
  REMOTE_SERVICE=`< /etc/${VERSION}/${JUJU_RELATION_ID}.relation`
}

signed_decimal () {
  if [ \( $1 -gt 255 \) -o \( $1 -lt -128 \) ]; then
    echo -128
  elif [ $1 -gt 127 ]; then
    echo $((-129 + ($1 - 127)))
  else
    echo $1
  fi
}

start_tomcat () {
  if ! service ${VERSION} status > /dev/null; then
    juju-log "Starting ${VERSION}"
    service ${VERSION} start
  fi
}

stop_tomcat () {
  if service ${VERSION} status > /dev/null; then
    juju-log "Stopping ${VERSION}"
    service ${VERSION} stop
  fi
}

unique_id () {
  echo -n "{0,0,0,0,0,0,0,0,0,0,0,0"
  address=`relation-get private-address`
  address=`dig ${address} +short`
  for o in ${address//\./ }; do
    echo -n ",`signed_decimal ${o}`"
  done
  echo "}"
}

obtain_tomcat_lock
COMMAND=`basename $0`
case "$COMMAND" in
  install)
    install_tomcat
    ;;
  start)
    start_tomcat
    ;;
  stop)
    stop_tomcat
    ;;
  config-changed)
    parse_jndi_memcached_config
    parse_jndi_terracotta_config
    parse_jndi_db_config
    configure_tomcat
    restart_tomcat
    ;;
  upgrade-charm)
    parse_jndi_memcached_config
    parse_jndi_terracotta_config
    parse_jndi_db_config
    configure_tomcat
    restart_tomcat
    ;;
  cluster-relation-departed)
    remove_server
    if [ -n "${restart_required}" ]; then
      restart_tomcat
    fi
    ;;
  cluster-relation-joined)
    add_server
    if [ -n "${restart_required}" ]; then
      restart_tomcat
    fi
    ;;
  website-relation-joined)
    check_website
    configure_website
    ;;
  jndi-db-mysql-relation-broken)
    destroy_db_relation
    ;;
  jndi-db-mysql-relation-changed)
    configure_mysql
    if [ -n "${config_required}" ]; then
      parse_jndi_db_config
      configure_datasources
      restart_tomcat
    fi
    ;;
  jndi-db-mysql-relation-joined)
    create_relation_id
    install_mysql
    parse_jndi_db_config
    create_mysql_datasources
    ;;
  jndi-db-pgsql-relation-broken)
    destroy_db_relation
    ;;
  jndi-db-pgsql-relation-changed)
    check_database
    install_postgresql
    configure_postgresql
    parse_jndi_db_config
    configure_datasources
    restart_tomcat
    ;;
  jndi-db-pgsql-relation-joined)
    create_relation_id
    ;;
  jndi-memcached-relation-broken)
    set_relation_id
    remove_jndi_memcached
    parse_jndi_memcached_config
    configure_jndi_memcached
    restart_tomcat
    remove_relation_id
    ;;
  jndi-memcached-relation-changed)
    check_memcached
    add_jndi_memcached_server
    parse_jndi_memcached_config
    configure_jndi_memcached
    restart_tomcat
    ;;
  jndi-memcached-relation-departed)
    remove_jndi_memcached_server
    parse_jndi_memcached_config
    configure_jndi_memcached
    restart_tomcat
    ;;
  jndi-memcached-relation-joined)
    create_relation_id
    ;;
  jndi-terracotta-relation-broken)
    set_relation_id
    remove_jndi_terracotta
    parse_jndi_terracotta_config
    configure_jndi_terracotta
    restart_tomcat
    remove_relation_id
    ;;
  jndi-terracotta-relation-departed)
    remove_jndi_terracotta_server
    parse_jndi_terracotta_config
    configure_jndi_terracotta
    restart_tomcat
    ;;
  jndi-terracotta-relation-joined)
    create_relation_id
    create_terracotta_log_directory
    add_jndi_terracotta_server
    parse_jndi_terracotta_config
    configure_jndi_terracotta
    restart_tomcat
    ;;
  terracotta-relation-broken)
    remove_terracotta
    restart_tomcat
    ;;
  terracotta-relation-departed)
    remove_terracotta_server
    configure_terracotta
    restart_tomcat
    ;;
  terracotta-relation-joined)
    install_terracotta
    create_terracotta_log_directory
    add_terracotta_server
    configure_terracotta
    restart_tomcat
    ;;
esac
release_tomcat_lock