blob: 564a5fd88e3047f07b1aca3dab6383b710d43be3 [file] [log] [blame]
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
function usage() {
cat <<EOF
USAGE: modify_war <args>
WHERE <args>:
-e <jar>
Assumes the input file is an .ear file and will add the
given jar as a shared, application library. The file will
be added in a /lib directory (by default) and any embedded
.war files will have a corresponding Class-Path entry added
to their MANIFEST.MF file. The option can be given multiple times.
-h
Displays this help message.
-j <jar>
Additional library to add to the input file. Can be given
multiple times.
-J <jvm opt>
JVM argument to pass to sub-commands. Typically this might
be to define proxy values. For example -J"-Dhttp.proxyHost=my-proxy"
-l <lib>
Library directory where new jars will be placed inside war.
Defaults to WEB-INF/lib.
-m <lib>
Library directory where new jars will be placed inside ear.
Defaults to /lib.
-o <file>
The output file.
-p <param=value>
Specific parameter for inclusion into the session filter
definition as a regular init-param. Can be given multiple times.
-r
Test run which only outputs an updated web.xml file.
-t <cache-type>
Type of cache. Must be one of 'peer-to-peer' or
'client-server'. Default is peer-to-peer.
-v
Verbose output
-w <war/ear file>
The input file - either a WAR or EAR. The following actions
will be performed depending on the type of file:
WARs will have a <filter> element added to the web.xml and
will have the appropriate jars copied to WEB-INF/lib.
If the file is an EAR, then the appropriate jars will be
copied to lib, within the ear and each embedded war files'
manifest will have a Class-Path entry added (if one does
not already exist).
An appropriate slf4j binding jar must be included for ears
or wars using -e or -j respectively. The following jars are
provided:
slf4j-jdk14
slf4j-log4j12
geode-modules-slf4j-weblogic
-x
Do not create a self-contained war/ear file by copying all
necessary jars into the file. When this option is used,
additional jars will need to be made available to the
container:
geode-modules.jar
geode-modules-session-internal.jar
geode-core.jar
geode-common.jar
geode-management.jar
antlr.jar
log4j-core.jar
log4j-api.jar
log4j-jul.jar
fastutil.jar
javax.transactions-api.jar
jgroups.jar
micrometer-core.jar
slf4j-api.jar
slf4j-jdk14.jar (not for WebLogic)
geode-modules-slf4j-weblogic.jar (WebLogic only)
This option still modifies any web.xml files.
EOF
}
# Two logging levels - 'I'nfo and 'D'ebug
function log() {
local MSG=$1
local LVL=${2:-I}
if [ "$LVL" == "D" ]; then
if [ -n "$DEBUG" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') $LVL $MSG" >&2
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') $LVL $MSG" >&2
fi
}
function exiting() {
local MSG=$1
local CODE=${2:-0}
if [ -n "$MSG" ]; then
echo "ERROR: $MSG"
fi
rm -rf $TMP_DIR
exit $CODE
}
function add_war_jars() {
local WAR_LIB_DIR=$1/$ARG_WAR_LIB_DIR/
mkdir -p $WAR_LIB_DIR
log "Copying jar(s) into war's '$ARG_WAR_LIB_DIR' directory" D
for J in ${ARG_WAR_LIBS[*]}; do
log " $J" D
cp $J $WAR_LIB_DIR || exiting "Unable to copy $J to temp location $WAR_LIB_DIR" 1
done
}
function process_manifest() {
local MANIFEST=$1
local TMP_MANIFEST
log "Processing manifest $MANIFEST" D
CP_LIBS=""
for J in ${OTHER_JARS[*]} ${ARG_EAR_LIBS[*]}; do
CP_LIBS="$CP_LIBS $ARG_EAR_LIB_DIR/$(basename $J)"
done
TMP_MANIFEST="$TMP_DIR/manifest.mf.$$"
cp $MANIFEST $TMP_MANIFEST
awk -v CP_LIBS="$CP_LIBS" '
BEGIN {
cp = 0
split(CP_LIBS, cp_array)
}
/^Class-Path/ {print $0 CP_LIBS; cp = 1; getline}
/^ *\r?$/ {
if (cp == 0) {
print "Class-Path:" CP_LIBS
cp = 1
}
}
{print $0}
END { if (cp == 0) print "Class-Path:" CP_LIBS }
' $TMP_MANIFEST > $MANIFEST
rm $TMP_MANIFEST
}
function process_web_xml() {
local WORK_DIR=$1
local ARG_P=""
local JVM_OPTS=""
for i in ${ARG_GEMFIRE_PARAMETERS[*]}; do
ARG_P="$ARG_P -p $i"
done
for j in ${ARG_JVM_OPTS[*]}; do
JVM_OPTS="$JVM_OPTS $j"
done
WEB_XML=$(find $WORK_DIR -name web.xml)
TMP_WEB_XML="${WORK_DIR}/web.xml.$$"
CMD="${JAVACMD} $JVM_OPTS -jar $SESSION_JAR $ARG_P -t $ARG_CACHE_TYPE -w $WEB_XML"
log "Executing java cmd: ${CMD}" D
if [ $ARG_TEST_RUN -eq 0 ]; then
eval ${CMD} > $TMP_WEB_XML || exiting "Error updating web.xml" 1
cp $TMP_WEB_XML $WEB_XML
rm -f $TMP_WEB_XML
else
eval ${CMD} || exiting "Error updating web.xml" 1
fi
}
function process_input_file() {
local WORK_DIR=$1
if [[ "$ARG_INPUT_FILE" =~ \.war$ ]]; then
process_web_xml $WORK_DIR
add_war_jars $WORK_DIR
return
fi
WAR_LIST=$( find $WORK_DIR -name '*.war' )
for WAR in $WAR_LIST; do
log "Processing embedded war file $WAR" D
TMP_WAR_DIR="${WAR}.$$"
log "Unzipping war to $TMP_WAR_DIR" D
unzip -q -o -d $TMP_WAR_DIR $WAR
process_web_xml $TMP_WAR_DIR
if [ $ARG_TEST_RUN -eq 0 ]; then
add_war_jars $TMP_WAR_DIR
MANIFEST=$( find $TMP_WAR_DIR -name MANIFEST.MF )
if [ $ARG_PROCESS_LIBS -eq 1 -a -n "$MANIFEST" ]; then
process_manifest $MANIFEST
fi
log "Creating new war $WAR" D
if [ -n "$MANIFEST" ]; then
$JARCMD cmf $MANIFEST $WAR -C $TMP_WAR_DIR .
else
$JARCMD cf $WAR -C $TMP_WAR_DIR .
fi
fi
rm -rf $TMP_WAR_DIR
done
}
######## Mainline #########
X=`dirname $0`
EXE_DIR=`cd $X; pwd`
LIB_DIR=`cd ${X}/../lib; pwd`
VERSION="@GEODE_VERSION@"
if [ -z "$GEODE" ]; then
exiting "Please set the GEODE environment variable to the root of the Geode install location" 1
fi
SESSION_JAR="${LIB_DIR}/geode-modules-session-${VERSION}.jar"
declare -a OTHER_JARS
OTHER_JARS=(${GEODE}/lib/geode-core-${VERSION}.jar \
${GEODE}/lib/geode-logging-${VERSION}.jar \
${GEODE}/lib/geode-serialization-${VERSION}.jar \
${GEODE}/lib/geode-common-${VERSION}.jar \
${GEODE}/lib/geode-log4j-${VERSION}.jar \
${GEODE}/lib/geode-management-${VERSION}.jar \
${GEODE}/lib/antlr-@ANTLR_VERSION@.jar \
${GEODE}/lib/log4j-core-@LOG4J_VERSION@.jar \
${GEODE}/lib/log4j-api-@LOG4J_VERSION@.jar \
${GEODE}/lib/log4j-jul-@LOG4J_VERSION@.jar \
${GEODE}/lib/fastutil-@FASTUTIL_VERSION@.jar \
${GEODE}/lib/javax.transaction-api-@TX_VERSION@.jar \
${GEODE}/lib/jetty-http-@JETTY_VERSION@.jar \
${GEODE}/lib/jetty-io-@JETTY_VERSION@.jar \
${GEODE}/lib/jetty-server-@JETTY_VERSION@.jar \
${GEODE}/lib/jetty-util-@JETTY_VERSION@.jar \
${GEODE}/lib/jgroups-@JGROUPS_VERSION@.jar \
${GEODE}/lib/commons-io-@COMMONS_IO_VERSION@.jar \
${GEODE}/lib/commons-lang3-@COMMONS_LANG_VERSION@.jar \
${GEODE}/lib/shiro-core-@SHIRO_VERSION@.jar \
${GEODE}/lib/commons-validator-@COMMONS_VALIDATOR_VERSION@.jar \
${GEODE}/lib/micrometer-core-@MICROMETER_VERSION@.jar \
${LIB_DIR}/geode-modules-${VERSION}.jar \
${LIB_DIR}/geode-modules-session-internal-${VERSION}.jar \
${LIB_DIR}/slf4j-api-@SLF4J_VERSION@.jar \
${LIB_DIR}/slf4j-jdk14-@SLF4J_VERSION@.jar)
TMP_DIR="/tmp/modify_war.$$"
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
JAVACMD="$JAVA_HOME/bin/java"
JARCMD="$JAVA_HOME/bin/jar"
if [[ ! -x "$JAVACMD" || ! -x "$JARCMD" ]] ; then
echo "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation."
exit 1;
fi
else
hash java >/dev/null 2>&1 || { echo "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation."; exit 1;}
hash jar >/dev/null 2>&1 || { echo "ERROR: JAVA_HOME is not set and no 'jar' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation."; exit 1;}
JAVACMD="java"
JARCMD="jar"
fi
ARG_INPUT_FILE=""
ARG_WAR_LIB_DIR="WEB-INF/lib"
ARG_EAR_LIB_DIR="lib"
ARG_OUTPUT_FILE=""
ARG_TEST_RUN=0
ARG_CACHE_TYPE=""
ARG_PROCESS_LIBS=1
declare -a ARG_GEMFIRE_PARAMETERS=""
declare -a ARG_WAR_LIBS="$SESSION_JAR"
declare -a ARG_EAR_LIBS=""
declare -a ARG_JVM_OPTS=""
trap exiting INT QUIT TERM
mkdir $TMP_DIR
CMD_ARGS="-j $SESSION_JAR"
while getopts "e:hj:J:l:m:o:p:rt:vw:x" OPT; do
case $OPT in
e)
if [ ! -f $OPTARG ]; then
exiting "Cannot read file '$OPTARG' given with option -e" 1
fi
ARG_EAR_LIBS[${#ARG_EAR_LIBS[@]}]=$OPTARG
;;
h)
usage
exiting "" 1
;;
j)
if [ ! -f $OPTARG ]; then
exiting "Cannot read file '$OPTARG' given with option -j" 1
fi
ARG_WAR_LIBS[${#ARG_WAR_LIBS[@]}]=$OPTARG
;;
J)
ARG_JVM_OPTS[${#ARG_JVM_OPTS[@]}]=$OPTARG
;;
l)
ARG_WAR_LIB_DIR=$OPTARG
;;
m)
ARG_EAR_LIB_DIR=$OPTARG
;;
o)
ARG_OUTPUT_FILE=$OPTARG
;;
p)
ARG_GEMFIRE_PARAMETERS[${#ARG_GEMFIRE_PARAMETERS[@]}]=$OPTARG
;;
r)
ARG_TEST_RUN=1
;;
t)
case $OPTARG in
peer-to-peer|client-server)
ARG_CACHE_TYPE=$OPTARG
;;
*)
exiting "Invalid cache type '$OPTARG' given with option -t. Options are 'peer-to-peer' or 'client-server'." 1
;;
esac
;;
v)
DEBUG=1
;;
w)
if [ ! -f $OPTARG ]; then
exiting "Cannot read file '$OPTARG' given with option -w" 1
fi
ARG_INPUT_FILE=$OPTARG
;;
x)
ARG_PROCESS_LIBS=0
;;
[?])
echo "Unknown option '$OPTARG'"
echo
usage
exit 1
;;
:)
echo "Option '$OPTARG' requires an argument"
echo
usage
exit 1
;;
esac
done
# Some validation
if [ -z "$ARG_INPUT_FILE" ]; then
exiting "Please supply an input file with the -w option" 1
fi
if [ -z "$ARG_OUTPUT_FILE" ]; then
ARG_OUTPUT_FILE="sessions-$(basename $ARG_INPUT_FILE)"
fi
if [[ "$ARG_INPUT_FILE" =~ \.war$ && -n "${ARG_EAR_LIBS[*]}" ]]; then
log "Input file appears to be a war but -e also specified. EAR processing will be skipped." W
fi
if [[ "$ARG_INPUT_FILE" =~ \.war$ && $ARG_PROCESS_LIBS -eq 1 ]]; then
for J in ${OTHER_JARS[*]}; do
ARG_WAR_LIBS[${#ARG_WAR_LIBS[@]}]=$J
done
fi
unzip -q -o -d $TMP_DIR $ARG_INPUT_FILE
process_input_file $TMP_DIR
if [[ $ARG_TEST_RUN -eq 0 && $ARG_PROCESS_LIBS -eq 1 && "$ARG_INPUT_FILE" =~ \.ear$ ]]; then
log "Copying additional jars into ear's '$ARG_EAR_LIB_DIR' directory" D
mkdir -p $TMP_DIR/$ARG_EAR_LIB_DIR
for i in ${OTHER_JARS[*]} ${ARG_EAR_LIBS[*]}; do
log " $i" D
cp $i $TMP_DIR/$ARG_EAR_LIB_DIR/ || exiting "Unable to copy $i to $TMP_DIR/$ARG_EAR_LIB_DIR" 1
done
fi
if [ $ARG_TEST_RUN -eq 0 ]; then
mkdir -p $TMP_DIR/META-INF
touch $TMP_DIR/META-INF/MANIFEST.MF
$JARCMD cmf $TMP_DIR/META-INF/MANIFEST.MF $ARG_OUTPUT_FILE -C $TMP_DIR .
log "Created file: $ARG_OUTPUT_FILE" I
fi
exiting