<?xml version="1.0" encoding="utf-8"?>
<!-- -->
<!-- rasmussj@us.ibm.com -->
<!-- This is a modified version of the healthcheck stylesheet -->
<!-- It is used in conjunction with an Out Of Service Schedule to enable or disable LB Group Members -->
<!-- -->
<!--
Licensed Materials - Property of IBM
IBM WebSphere DataPower Appliances
Copyright IBM Corporation 2007. All Rights Reserved.
US Government Users Restricted Rights - Use, duplication or disclosure
restricted by GSA ADP Schedule Contract with IBM Corp.
-->
<!-- set three parameters 
= xpath expresion to search for
       = lb group to control
       = server in lb group to toggle up/down
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:dp="http://www.datapower.com/extensions" xmlns:dyn="http://exslt.org/dynamic" xmlns:dpconfig="http://www.datapower.com/param/config" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="dyn dpconfig dp date" exclude-result-prefixes="dyn dpconfig dp date">
	<!-- -->
	<xsl:output method="xml"/>
	<xsl:param name="dpconfig:expression"/>
	<xsl:param name="dpconfig:grp"/>
	<xsl:param name="dpconfig:svr"/>
	<xsl:variable name="type" select="'LoadBalancedBookService'"/>
	<!-- -->
	<xsl:template match="/">
		<!-- -->
		<!-- Import the Out of Service Schedule (OOS) -->
		<!-- and get the entries for this LB Group /Server(member)-->
		<!-- -->
		<xsl:variable name="oosSchedule" select="document('local:///bookQueryServiceOutofServiceSchedule.xml')"/>
		<xsl:variable name="serverSchedule" select="$oosSchedule/loadBalancerSchedule/outOfService[@lbGroup=$dpconfig:grp and @lbMember=$dpconfig:svr]"/>
		<!-- -->
		<!-- Standard Health Check entries -->
		<!-- The Main Check processor will looking for these  -->
		<!-- -->
		<healthcheckresults>
			<lbgroup>
				<xsl:value-of select="$dpconfig:grp"/>
			</lbgroup>
			<lbhost>
				<xsl:value-of select="$dpconfig:svr"/>
			</lbhost>
			<!-- -->
			<xsl:choose>
				<!-- -->
				<!-- The XPath that we are looking for in response is not found -->
				<!-- in the response from the server / member -->
				<!-- Mark the server sick -->
				<!-- -->
				<xsl:when test="count(dyn:evaluate($dpconfig:expression)) = 0">
					<health>sick</health>
					<dp:reject>
						<xsl:value-of select="concat('Invalid response from ', $dpconfig:svr, ' in lb-group ', $dpconfig:grp)"/>
					</dp:reject>
				</xsl:when>
				<!-- -->
				<!-- Are there OOS entries for this server / member? -->
				<!-- If so, execute the OOS processing template -->
				<!-- -->
				<xsl:when test="$serverSchedule">
					<xsl:message dp:priority="warn" dp:type="{$type}">
						<xsl:value-of select="concat('dpconfig:grp=', $dpconfig:grp)"/>
						<xsl:value-of select="concat(', dpconfig:svr=', $dpconfig:svr)"/>
						<xsl:value-of select="concat(', type=', $type)"/>
						<xsl:value-of select="', SERVER SCHEDULE FOUND'"/>
					</xsl:message>
					<!-- -->
					<!-- The template checkOutOfServiceSchedule will return the -->
					<!-- results of OOS rule testing in $serverScheduleReturn -->
					<!-- -->
					<xsl:variable name="serverScheduleReturn">
						<xsl:call-template name="checkOutOfServiceSchedule">
							<xsl:with-param name="serverSchedule" select="$serverSchedule"/>
						</xsl:call-template>
					</xsl:variable>
					<!-- -->
					<!-- Test the results of checkOutOfServiceSchedule -->
					<!-- If there is anything in it? Only a sick response would be returned -->
					<!-- If nothing is returned the member / server is not OOS -->
					<!-- -->
					<xsl:choose>
						<xsl:when test="string-length($serverScheduleReturn)>1">
							<xsl:message dp:priority="warn" dp:type="{$type}">($serverScheduleReturn)>1</xsl:message>
							<xsl:copy-of select="$serverScheduleReturn"/>
						</xsl:when>
						<!-- -->
						<!-- Otherwise all checked out, its good -->
						<!-- -->
						<xsl:otherwise>
							<xsl:message dp:priority="warn" dp:type="{$type}">($serverScheduleReturn) EMPTY </xsl:message>
							<health>good</health>
							<dp:accept/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:when>
				<!-- -->
				<!-- There were no OOS entries found, report healthy -->
				<!-- -->
				<xsl:otherwise>
					<xsl:message dp:priority="warn" dp:type="{$type}">
						<xsl:value-of select="concat('dpconfig:grp=', $dpconfig:grp)"/>
						<xsl:value-of select="concat(', dpconfig:svr=', $dpconfig:svr)"/>
						<xsl:value-of select="', SERVER SCHEDULE NOT FOUND'"/>
					</xsl:message>
					<health>good</health>
					<dp:accept/>
				</xsl:otherwise>
			</xsl:choose>
		</healthcheckresults>
		<!-- -->
	</xsl:template>
	<!-- -->
	<!-- This template processes the OOS Schedule -->
	<!-- -->
	<xsl:template name="checkOutOfServiceSchedule">
		<xsl:param name="serverSchedule"/>
		<!-- -->
		<!-- First check the range rules starting with the first (ndx=1) -->
		<!-- -->
		<xsl:variable name="rangeResults">
			<xsl:if test="$serverSchedule/range">
				<xsl:call-template name="checkRangeRules">
					<xsl:with-param name="serverSchedule" select="$serverSchedule"/>
					<xsl:with-param name="ndx" select="number(1)"/>
				</xsl:call-template>
			</xsl:if>
		</xsl:variable>
		<!-- -->
		<!-- Then check the repeating rules starting with the first (ndx=1)-->
		<!-- -->
		<xsl:variable name="repeatingResults">
			<xsl:if test="$serverSchedule/repeating">
				<xsl:call-template name="checkRepeatingRules">
					<xsl:with-param name="serverSchedule" select="$serverSchedule"/>
					<xsl:with-param name="ndx" select="number(1)"/>
				</xsl:call-template>
			</xsl:if>
		</xsl:variable>
		<!-- -->
		<!-- We only need to report sick once, so first check if the repeating rules reported sick -->
		<!-- If so, copy the <health>sick</health> response -->
		<!-- If not, check the repeating rules -->
		<!-- -->
		<xsl:choose>
			<xsl:when test="$rangeResults">
				<xsl:copy-of select="$rangeResults"/>
			</xsl:when>
			<xsl:when test="$repeatingResults">
				<xsl:copy-of select="$repeatingResults"/>
			</xsl:when>
		</xsl:choose>
	</xsl:template>
	<!-- -->
	<!-- This template processes the OOS Schedule Range rules -->
	<!-- The ndx param is used to tell which range rules we are testing -->
	<!-- -->
	<xsl:template name="checkRangeRules">
		<xsl:param name="serverSchedule"/>
		<xsl:param name="ndx"/>
		<!-- -->
		<!-- Get some date info and calculate -->
		<!-- differences from the from / to dates on rules -->
		<!-- -->
		<xsl:variable name="thisDate" select="date:date-time()"/>
		<xsl:variable name="diffFrom" select="date:difference($thisDate, $serverSchedule/range[$ndx]/@from)"/>
		<xsl:variable name="diffTo" select="date:difference($thisDate, $serverSchedule/range[$ndx]/@to)"/>
		<!-- -->
		<!-- If diffFrom is negative and diffTo is positive-->
		<!-- Today's date is in between, i.e. in the range -->
		<!-- Report the server sick (OOS) -->
		<!-- -->
		<xsl:choose>
			<xsl:when test="substring($diffFrom,1,1)='-' and substring($diffTo,1,1)!='-'">
				<xsl:variable name="rejectString" select="concat(
						'LBGroup (', $dpconfig:grp,
						') LBMemeber (', $dpconfig:svr, 
						') disabled due to out-of-service range', 
						' from(', $serverSchedule/range[$ndx]/@from, 
						'), to(', $serverSchedule/range[$ndx]/@to, ')')"/>
				<xsl:message dp:priority="warn" dp:type="{$type}">
					<xsl:value-of select="$rejectString"/>
				</xsl:message>
				<health>sick</health>
				<dp:reject>
					<xsl:value-of select="$rejectString"/>
				</dp:reject>
			</xsl:when>
			<!-- -->
			<!-- Otherwise the server is healthy -->
			<!-- If there are more rules to process, call the template again-->
			<!-- -->
			<xsl:otherwise>
				<xsl:if test="$serverSchedule/range[$ndx+1]">
					<xsl:message dp:priority="warn" dp:type="{$type}">CHECKING NEXT RANGE</xsl:message>
					<xsl:call-template name="checkRangeRules">
						<xsl:with-param name="serverSchedule" select="$serverSchedule"/>
						<xsl:with-param name="ndx" select="$ndx+1"/>
					</xsl:call-template>
				</xsl:if>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<!-- -->
	<!-- This template processes the OOS Schedule Repeating rules -->
	<!-- This ndx param is used to tell which of repeating rules we are testing -->
	<!-- -->
	<xsl:template name="checkRepeatingRules">
		<xsl:param name="serverSchedule"/>
		<xsl:param name="ndx"/>
		<!-- -->
		<!-- Get some date info -->
		<!-- Todays date in prefixed to the time values entered on the rules -->
				<!-- repeating rules do not have a date component -->
		<!-- And calculate differences from the from / to dates on rules -->
		<!-- -->
		<xsl:variable name="dayOfWeek" select="date:day-in-week()"/>
		<xsl:variable name="days" select="$serverSchedule/repeating[$ndx]/@days"/>
		<xsl:variable name="thisDate" select="date:date-time()"/>
		<xsl:variable name="from" select="concat(substring-before($thisDate, 'T'), $serverSchedule/repeating[$ndx]/@from)"/>
		<xsl:variable name="to" select="concat(substring-before($thisDate, 'T'),$serverSchedule/repeating[$ndx]/@to)"/>
		<xsl:variable name="diffFrom" select="date:difference($thisDate, $from)"/>
		<xsl:variable name="diffTo" select="date:difference($thisDate, $to)"/>
		<!-- -->
		<!-- If diffFrom is negative and diffTo is positive-->
		<!-- Today's date is in between, i.e. in the range -->
		<!-- Report the server sick (OOS) -->
		<!-- -->
		<xsl:choose>
			<xsl:when test="substring($diffFrom,1,1)='-' and substring($diffTo,1,1)!='-' and contains($days, $dayOfWeek)">
				<xsl:variable name="rejectString" select="concat(
						'LBGroup (', $dpconfig:grp,
						') LBMemeber (', $dpconfig:svr, 
						') disabled due to repeating out-of-service range, days(', $days, 
						') from(', $serverSchedule/repeating[$ndx]/@from, 
						'), to(', $serverSchedule/repeating[$ndx]/@to, ')')"/>
				<xsl:message dp:priority="warn" dp:type="{$type}">
					<xsl:value-of select="$rejectString"/>
				</xsl:message>
				<health>sick</health>
				<dp:reject>
					<xsl:value-of select="$rejectString"/>
				</dp:reject>
			</xsl:when>
			<!-- -->
			<!-- Otherwise the server is healthy -->
			<!-- If there are more rules to process, call the template again-->
			<!-- -->
			<xsl:otherwise>
				<xsl:if test="$serverSchedule/repeating[$ndx+1]">
					<xsl:message dp:priority="warn" dp:type="{$type}">CHECKING NEXT REPEATING</xsl:message>
					<xsl:call-template name="checkRepeatingRules">
						<xsl:with-param name="serverSchedule" select="$serverSchedule"/>
						<xsl:with-param name="ndx" select="$ndx+1"/>
					</xsl:call-template>
				</xsl:if>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<!-- -->
</xsl:stylesheet>


