Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Improve error handling
Tom Scavo committed Jun 10, 2017
1 parent 8937906 commit d26845d
Showing 1 changed file with 149 additions and 33 deletions.
182 changes: 149 additions & 33 deletions bin/compute_vital_statistics.sh
@@ -22,9 +22,12 @@

display_help () {
/bin/cat <<- HELP_MSG
This script parses one or more SAML metadata aggregates and
produces a JSON file of vital statistics (such as validUntil,
creationInstant, etc.)
This script parses one or more SAML metadata files and
produces a JSON file of vital statistics. Each metadata file
must contain the following attributes:
/md:EntitiesDescriptor/@validUntil
/md:EntitiesDescriptor/md:Extensions/mdrpi:PublicationInfo/@creationInstant
The script depends on cached metadata. It will not fetch
a metadata file from the server.
@@ -86,21 +89,28 @@ display_help () {
OUTPUT
The script outputs a JSON file containing a single array.
Each array element is a JavaScript object with the following
fields:
metadataLocation: location
currentTime: dateTime
validUntil: dateTime
creationInstant: dateTime
validityInterval: duration
untilInvalid: duration
sinceCreation: duration
The script outputs a JSON file to OUT_DIR:
$out_filename
The JSON file contains a single array. Each array element is
a JavaScript object with the following fields:
successFlag boolean success or failure?
message string message string
metadataLocation string HTTP location
currentTime string ISO 8601 dateTime
validUntil dateTime ISO 8601 dateTime
creationInstant dateTime ISO 8601 dateTime
validityInterval duration ISO 8601 duration
untilInvalid duration ISO 8601 duration
sinceCreation duration ISO 8601 duration
For example:
{
"successFlag": true,
"message": "Integrity of compressed metadata confirmed",
"metadataLocation": "http://md.incommon.org/InCommon/InCommon-metadata.xml",
"currentTime": "2017-06-06T23:57:54Z",
"validUntil": "2017-06-16T18:41:12Z",
@@ -190,6 +200,9 @@ if [ ! -f "$xsl_path" ]; then
exit 2
fi

# output filename
out_filename="md_vital_statistics.json"

#######################################################################
# Process command-line options and arguments
#######################################################################
@@ -266,7 +279,6 @@ fi

# specify temporary files
xml_path="${tmp_dir}/saml-metadata.xml"
out_filename=md_vital_statistics.json
out_file="${tmp_dir}/$out_filename"

#######################################################################
@@ -281,6 +293,7 @@ escape_special_json_chars () {
}

append_json_object () {
local message=$( escape_special_json_chars "$message" )
local metadataLocation=$( escape_special_json_chars "$md_location" )
local currentTime=$( escape_special_json_chars "$now" )
local validUntil=$( escape_special_json_chars "$validUntil" )
@@ -289,8 +302,13 @@ append_json_object () {
local untilInvalid=$( escape_special_json_chars "$untilInvalid" )
local sinceCreation=$( escape_special_json_chars "$sinceCreation" )

local boolean_value="true"
! $success && boolean_value="false"

/bin/cat <<- JSON_OBJECT
{
"successFlag": $boolean_value,
"message": "$message",
"metadataLocation": "$metadataLocation",
"currentTime": "$currentTime",
"validUntil": "$validUntil",
@@ -302,7 +320,9 @@ append_json_object () {
JSON_OBJECT
}

parse_metadata () {
get_metadata () {

local status_code

md_location="$1"

@@ -311,73 +331,169 @@ parse_metadata () {
status_code=$?
if [ $status_code -eq 1 ]; then
# metadata must be cached
success=false
message="Metadata not found"
print_log_message -E "$script_name: metadata file not cached: $md_location"
clean_up_and_exit -d "$tmp_dir" 1
return 1
fi
if [ $status_code -gt 1 ]; then
success=false
message="Request for metadata failed"
print_log_message -E "$script_name: conditional_get failed ($status_code) on location: $md_location"
clean_up_and_exit -d "$tmp_dir" $status_code
return 3
fi

return 0
}

parse_metadata () {

local status_code
local tstamps
local validityIntervalSecs
local secsUntilInvalid
local secsSinceCreation

print_log_message -I "$script_name parsing cached metadata file: $md_location"

# extract @ID, @creationInstant, @validUntil (in that order)
tstamps=$( /usr/bin/xsltproc $xsl_path $xml_path )
status_code=$?
if [ $status_code -ne 0 ]; then
success=false
message="Unable to parse metadata"
print_log_message -E "$script_name: xsltproc failed ($status_code) on script: $xsl_path"
return 0
fi

# If @validUntil missing, then FAIL
# get @validUntil
validUntil=$( echo "$tstamps" | $_CUT -f3 )
status_code=$?
if [ $status_code -ne 0 ]; then
success=false
message="Unable to parse @validUntil"
print_log_message -E "$script_name: cut failed ($status_code)"
return 0
fi

# if @validUntil is missing, then FAIL
if [ -z "$validUntil" ]; then
success=false
message="XML attribute @validUntil not found"
print_log_message -E "$script_name: @validUntil not found"
clean_up_and_exit -d "$tmp_dir" 4
return 0
fi
print_log_message -D "$script_name found @validUntil: $validUntil"

# If @creationInstant missing, then FAIL
# get @creationInstant
creationInstant=$( echo "$tstamps" | $_CUT -f2 )
status_code=$?
if [ $status_code -ne 0 ]; then
success=false
message="Unable to parse @creationInstant"
print_log_message -E "$script_name: cut failed ($status_code)"
return 0
fi

# if @creationInstant is missing, then FAIL
if [ -z "$creationInstant" ]; then
success=false
message="XML attribute @creationInstant not found"
print_log_message -E "$script_name: @creationInstant not found"
clean_up_and_exit -d "$tmp_dir" 5
return 0
fi
print_log_message -D "$script_name found @creationInstant: $creationInstant"

# If validityInterval > 14 days, then FAIL
# compute validityInterval
validityIntervalSecs=$( secsUntil -b $creationInstant $validUntil )
status_code=$?
if [ $status_code -ne 0 ]; then
success=false
message="Unable to compute validity interval"
print_log_message -E "$script_name: secsUntil failed ($status_code)"
return 0
fi

# if validityInterval > 14 days, then FAIL # TODO: Generalize
if (( validityIntervalSecs > 14*24*60*60 )); then
success=false
message="Validity interval too large"
print_log_message -E "$script_name: validity interval exceeds maximum: $validityIntervalSecs"
clean_up_and_exit -d "$tmp_dir" 6
return 0
fi
validityInterval=$( secs2duration $validityIntervalSecs )
print_log_message -D "$script_name computed validity interval: $validityInterval"

# compute NOW
now=$( dateTime_now_canonical )
status_code=$?
if [ $status_code -ne 0 ]; then
success=false
message="Unable to compute current time"
print_log_message -E "$script_name: dateTime_now_canonical failed ($status_code)"
return 0
fi

# If secsUntilInvalid <= 0, then FAIL
# compute secsUntilInvalid
secsUntilInvalid=$( echo $validUntil | secsUntil -b $now )
status_code=$?
if [ $status_code -ne 0 ]; then
success=false
message="Unable to compute time to expiration"
print_log_message -E "$script_name: secsUntil failed ($status_code)"
return 0
fi

# if secsUntilInvalid <= 0, then FAIL
if (( secsUntilInvalid <= 0 )); then
print_log_message -E "$script_name: seconds until invalid not positive: $secsUntilInvalid"
clean_up_and_exit -d "$tmp_dir" 7
success=false
message="Metadata is expired"
print_log_message -C "$script_name: seconds until invalid not positive: $secsUntilInvalid"
return 0
fi
untilInvalid=$( secs2duration "$secsUntilInvalid" )
print_log_message -D "$script_name computed time until invalid: $untilInvalid"

# If secsSinceCreation <= 0, then FAIL
# compute secsSinceCreation
secsSinceCreation=$( echo $creationInstant | secsSince -e $now )
status_code=$?
if [ $status_code -ne 0 ]; then
success=false
message="Unable to compute time since creation"
print_log_message -E "$script_name: secsSince failed ($status_code)"
return 0
fi

# if secsSinceCreation <= 0, then FAIL
if (( secsSinceCreation <= 0 )); then
print_log_message -E "$script_name: seconds since creation not positive: $secsSinceCreation"
clean_up_and_exit -d "$tmp_dir" 8
success=false
message="Metadata is not valid"
print_log_message -C "$script_name: seconds since creation not positive: $secsSinceCreation"
return 0
fi
sinceCreation=$( secs2duration "$secsSinceCreation" )
print_log_message -D "$script_name computed time since creation: $sinceCreation"

# success
message="Metadata successfully parsed"
}

print_vital_statistics () {
print_output_file () {

local status_code

# begin output list
printf "[\n"

while true; do

parse_metadata "$1"
success=true

get_metadata "$1"
status_code=$?
if [ $status_code -eq 0 ]; then
parse_metadata
fi
append_json_object

shift; (( "$#" )) || break
@@ -397,7 +513,7 @@ print_vital_statistics () {
print_log_message -I "$script_name BEGIN"

# create the JSON output
print_vital_statistics "$@" > "$out_file"
print_output_file "$@" > "$out_file"
print_log_message -I "$script_name writing output file: $out_filename"

# move the output file to the web directory

0 comments on commit d26845d

Please sign in to comment.