Create a Quarterly EPM Cloud Upgrade Cadence with Six Week Test Cycles

Use the script in this section to create a self-service solution to skip updates so that Oracle Enterprise Performance Management Cloud environments are updated on a quarterly basis with a six-week test cycle. In this case, the production environments are updated six weeks after the test environments.

By default, EPM Cloud applies a monthly update to your environments. You use the skipUpdate command to skip the applying of monthly updates to an environment or to view current skip update requests. You can automate the manual running of the skipUpdate commands by using the scripts included in this section. These scripts automate the skip update process so that the updates are applied on a quarterly basis with six weeks test cycle.

Note:

  1. You cannot skip updates for more than three consecutive months. This script throws an error if you try to have an EPM Cloud environment updated only in February and October.
  2. All updates that have happened during the intervening period are applied to your environment during the next update. For example, assume that you use this script to schedule quarterly updates to occur only for February, May, August, and November updates. In this case, the May update, for example, will apply all applicable EPM Cloud monthly updates and patches that were released after the February update to your environment. The maintenance process may take more time than usual when the update is applied.
  3. This script sets up the update cadence for one quarter only.

    Sample Scenario: The test environment update cycle is established as the first Fridays of February (24.02 update), May (24.05 update), August (24.08 update), and November (24.11 update). The Production Environment will be updated on the third Fridays of March (24.02 update) with the version that was used to update the test environment on the first Friday of February (24.02 update). Similar update to the production environment will occur on the third week of June (24.05 update), September (24.08 update), and December (24.11 update). In this scenario, the production environment is not updated to the current update, but with the update that is currently on the test environment.

Windows Sample Script

Create skip_update.ps1 by copying the following script. Store it in a local directory. See Running the Script for information on running this script:
# Skip Update PowerShell script

$inputproperties = ConvertFrom-StringData(Get-Content ./input.properties -raw)
$username="$($inputproperties.username)"
$password="$($inputproperties.password)"
$url="$($inputproperties.url)"
$updateversions="$($inputproperties.updateversions)"
$podtype="$($inputproperties.podtype)"
$proxyserverusername="$($inputproperties.proxyserverusername)"
$proxyserverpassword="$($inputproperties.proxyserverpassword)"
$proxyserverdomain="$($inputproperties.proxyserverdomain)"

echo "Starting skip_update.ps1 script."

$monthsarr = ("01","02","03","04","05","06","07","08","09","10","11","12")
$global:monthsarrfromcurrent = @()
$global:yearsarrfromcurrent = @()
$updateversionsarr = $updateversions.Split(",")
$currentyear=Get-Date -Format yy
$currentmonth=Get-Date -Format MM
$nextyear=[int]$currentyear+1

function populateFromCurrentArrays() {
    $startposition = 0

    for ($i = 0; $i -le ($monthsarr.length - 1); $i++) {
	if (${currentmonth} -eq $monthsarr[$i]) {
            if (${podtype} -eq "prod") {
                if (${updateversionsarr} -contains ${currentmonth}) {
                    $startposition=$i-2
		} else {
                    $startposition=$i-1
	        }
            } else {
                if (${updateversionsarr} -contains ${currentmonth}) {
                    $startposition=$i
		} else {
                    $startposition=$i-1
		}
            }
	    break
	}
    }

    if (${startposition} -lt 0) {
        $startposition=$startposition+12
    }

    for ($i = 0; $i -le ($monthsarr.length - 1); $i++) {
	if (${i} -ge ${startposition}) {
            $global:monthsarrfromcurrent += $monthsarr[$i]
            $global:yearsarrfromcurrent += $currentyear
        }
    }

    for ($i = 0; $i -le ($monthsarr.length - 1); $i++) {
	if (${i} -lt ${startposition}) {
            $global:monthsarrfromcurrent += $monthsarr[$i]
            $global:yearsarrfromcurrent += $nextyear
        }
    }
}

function skipUpdateAdd($yearnumber, $monthnumber) {
    echo "Running: epmautomate.bat skipUpdate add version=${yearnumber}.${monthnumber} comment=`"adding skipUpdate`""
    epmautomate skipUpdate add version=${yearnumber}.${monthnumber} comment="adding skipUpdate"
}

function processSkipUpdates() {
    $addcount = 0
    $countlimit = 0

    if (${podtype} -eq "prod") {
        $countlimit = 3
    } else {
        $countlimit = 2
    }

    if ((${proxyserverusername} -eq "") -And (${proxyserverpassword} -eq "") -And (${proxyserverdomain} -eq "")) {
        echo "Running: epmautomate.bat login ${username} ${password} ${url}"
        epmautomate login ${username} ${password} ${url}
    } else {
        echo "Running: epmautomate.bat login ${username} ${password} ${url} ProxyServerUserName=${proxyserverusername} ProxyServerPassword=${proxyserverpassword} ProxyServerDomain=${proxyserverdomain}"
        epmautomate login ${username} ${password} ${url} ProxyServerUserName=${proxyserverusername} ProxyServerPassword=${proxyserverpassword} ProxyServerDomain=${proxyserverdomain}
    }

    echo "Running: epmautomate.bat skipUpdate remove"
    epmautomate skipUpdate remove

    for ($i = 0; $i -le ($global:monthsarrfromcurrent.length - 1); $i++) {
        $match = 1

        if (${addcount} -eq ${countlimit}) {
            echo "Update calls are completed. No more will be attempted."
            break
	}

        for ($j = 0; $j -le ($updateversionsarr.length - 1); $j++) {
	    if ((${currentmonth} -eq $updateversionsarr[$j]) -And (${addcount} -gt 0)) {
                $match = 1
		break
	    }

	    if (($global:monthsarrfromcurrent[$i] -eq $updateversionsarr[$j]) -And (${addcount} -eq 0)){
                $match = 0
		break
	    }
	}

        if (${match} -eq 1) {
            skipUpdateAdd $global:yearsarrfromcurrent[$i] $global:monthsarrfromcurrent[$i]
            $addcount += 1
	}
    }

    echo "Running: epmautomate.bat skipUpdate list"
    epmautomate skipUpdate list
    echo "Running: epmautomate.bat logout"
    epmautomate logout
}

function compareUpdateMonths($thismonth, $nextmonth) {
    $nextmonthorig=${nextmonth}

    if (${nextmonth} -lt ${thismonth}) {
        $nextmonth+=12
    }

    $monthdiff = $nextmonth - $thismonth

    if (${monthdiff} -gt 4) {
        echo "There are more than 3 versions skipped from version ${thismonth} to version ${nextmonthorig}. Please correct updateversions in input.properties so that there are not more than three versions skipped between each update version. Exiting."
        exit 1
    }
}

function validateUpdateVersions() {
    for ($i = 0; $i -le ($updateversionsarr.length - 1); $i++) {
        $nextint = $i + 1
	$thisupdatemonth = $updateversionsarr[$i]
        $thisupdatemonthint=[int]$thisupdatemonth
	$nextupdatemonth=$updateversionsarr[$nextint]
        $nextupdatemonthint=[int]$nextupdatemonth

        if (${nextupdatemonth} -eq "") {
            $nextupdatemonth=$updateversionsarr[0]
            $nextupdatemonthint=[int]$nextupdatemonth
	}

        compareUpdateMonths $thisupdatemonthint $nextupdatemonthint
    }
}

validateUpdateVersions
populateFromCurrentArrays
processSkipUpdates

Linux/UNIX Sample Script

Create skip_update.sh by copying the following script. Store it in a local directory. See Running the Script for information on running this script:
#!/bin/sh

. ./input.properties

echo "Starting skip_update.sh script."

export JAVA_HOME=${javahome}

declare -a monthsarr=(01 02 03 04 05 06 07 08 09 10 11 12)
declare -a monthsarrfromcurrent
declare -a yearsarrfromcurrent
updateversionsarr=( $(echo "${updateversions}" | sed 's/,/ /g') ) 
currentyear=$(date +%y)
nextyear=$((currentyear+1))
currentmonth=$(date +%m)

populateFromCurrentArrays() {
    local startposition=0

    for i in ${!monthsarr[@]}
    do
        if [[ "${currentmonth}" == "${monthsarr[$i]}" ]]
        then 
            if [[ "${podtype}" == "prod" ]]
            then
                if [[ ${updateversionsarr[@]} =~ ${currentmonth} ]]
                then
                    startposition=$((i-2))
                else
                    startposition=$((i-1))
                fi
                break
            else
                if [[ ${updateversionsarr[@]} =~ ${currentmonth} ]]
                then
                    startposition=$i
                else
                    startposition=$((i-1))
                fi
                break
            fi
        fi
    done

    if [[ ${startposition} -lt 0 ]]
    then
        startposition=$((startposition+12))
    fi 

    for i in ${!monthsarr[@]}
    do
        if [[ ${i} -ge ${startposition} ]]
        then 
            monthsarrfromcurrent=("${monthsarrfromcurrent[@]}" "${monthsarr[$i]}")
            yearsarrfromcurrent=("${yearsarrfromcurrent[@]}" "${currentyear}")
        fi
    done

    for i in ${!monthsarr[@]}
    do
        if [[ ${i} -lt ${startposition} ]]
        then 
            monthsarrfromcurrent=("${monthsarrfromcurrent[@]}" "${monthsarr[$i]}")
            yearsarrfromcurrent=("${yearsarrfromcurrent[@]}" "${nextyear}")
        fi
    done
}

skipUpdateAdd() {
    local yearnumber="$1"
    local monthnumber="$2"

    echo "Running: ${epmautomatescript} skipUpdate add version=${yearnumber}.${monthnumber} comment=\"adding skipUpdate\""
    ${epmautomatescript} skipUpdate add version=${yearnumber}.${monthnumber} comment="adding skipUpdate"
}

processSkipUpdates() {
    local addcount=0
    local countlimit=0

    if [[ "${podtype}" == "prod" ]]
    then
        countlimit=3
    else
        countlimit=2
    fi

    if [[ "${proxyserverusername}" == "" ]] && [[ "${proxyserverpassword}" == "" ]] && [[ "${proxyserverdomain}" == "" ]]
    then
        echo "Running: ${epmautomatescript} login ${username} ${password} ${url}"
        ${epmautomatescript} login ${username} ${password} ${url}
    else
        echo "Running: ${epmautomatescript} login ${username} ${password} ${url} ProxyServerUserName=${proxyserverusername} ProxyServerPassword=${proxyserverpassword} ProxyServerDomain=${proxyserverdomain}"
        ${epmautomatescript} login ${username} ${password} ${url} ProxyServerUserName=${proxyserverusername} ProxyServerPassword=${proxyserverpassword} ProxyServerDomain=${proxyserverdomain}
    fi
    echo "Running: ${epmautomatescript} skipUpdate remove"
    ${epmautomatescript} skipUpdate remove

    for i in ${!monthsarrfromcurrent[@]}
    do
        local match=1

        if [[ ${addcount} -eq ${countlimit} ]]
        then
            echo "Update add calls are completed. No more will be attempted."
            break
        fi

        for j in ${!updateversionsarr[@]}
        do
            if [[ "${currentmonth}" == "${updateversionsarr[$j]}" ]] && [[ ${addcount} -gt 0 ]]
            then
                match=1
                break
            fi

            if [[ "${monthsarrfromcurrent[$i]}" == "${updateversionsarr[$j]}" ]] && [[ ${addcount} -eq 0 ]]
            then
                match=0
                break
            fi
        done

        if [[ ${match} -eq 1 ]]
        then 
            skipUpdateAdd ${yearsarrfromcurrent[$i]} "${monthsarrfromcurrent[$i]}"
            addcount=$((addcount+1))
        fi
    done

    echo "Running: ${epmautomatescript} skipUpdate list"
    ${epmautomatescript} skipUpdate list
    echo "Running: ${epmautomatescript} logout"
    ${epmautomatescript} logout
}

compareUpdateMonths() {
    local thismonth=$1
    local nextmonth=$2
    local nextmonthorig=${nextmonth}
 
    if [[ ${nextmonth} -lt ${thismonth} ]]
    then
        nextmonth=$((nextmonth+12))
    fi

    monthdiff=$((nextmonth-thismonth))

    if [[ ${monthdiff} -gt 4 ]]
    then 
        echo "There are more than 3 versions skipped from version ${thismonth} to version ${nextmonthorig}. Please correct updateversions in input.properties so that there are not more than three versions skipped between each update version. Exiting."
        exit 1
    fi
}

validateUpdateVersions() {
    for i in ${!updateversionsarr[@]}
    do
        nextint=$((i+1))
        thisupdatemonth="${updateversionsarr[$i]}"
        thisupdatemonthint=${thisupdatemonth#0}
        nextupdatemonth="${updateversionsarr[$nextint]}"
        nextupdatemonthint=${nextupdatemonth#0}

        if [[ ${nextupdatemonth} == "" ]]
        then 
            nextupdatemonth="${updateversionsarr[0]}"
            nextupdatemonthint=${nextupdatemonth#0}
        fi

        compareUpdateMonths ${thisupdatemonthint} ${nextupdatemonthint}
    done
}

validateUpdateVersions
populateFromCurrentArrays
processSkipUpdates

Server-Side Groovy Script

Create skip_update.groovy Groovy script by copying the following script and then updating it. See Running the Script for information on running this script:

Update the following variables in this groovy script:

  • username User name of a Service Administrator on the environment on which you want to set the non-monthly update cadence.
  • password Password of the Service Administrator or the name and location of the encrypted password file.
  • url URL of the environment on which you want to set the non-monthly update cadence.
  • updateversions A comma separated list of EPM Cloud updates that should be applied to the environment identified by the url parameter. For example, updateversions=02,05,08,11.

    Versions must be specified as two digits; include a preceding zero for updates 01 through 09. The script attempts to run the skipUpdate command for the updates not included in the updateversions parameter value. For example, if you specify updateversions=02,05,08,11, the script tries to set skip update flags for the 01 (January), 03 (March), 04 (April), 06 (June), 07 (July), 09 (September), 10 (October), and 12 (December) updates. In this case, EPM Cloud updates 02 (February), 05 (May), 08 (August), and 11 (November) are applied to the environment.

  • podtype EPM Cloud environment type. Valid values are test and prod.
  • proxyserverusername The user name to authenticate a secure session with the proxy server that controls access to the internet.
  • proxyserverpassword The password to authenticate the user with the proxy server.
  • proxyserverdomain The name of the domain defined for the proxy server.

Note:

If you do not use a proxy server, do not specify any values for the proxyserverusername, proxyserverpassword, and proxyserverdomain parameters.
import java.text.SimpleDateFormat

String username = 'service_administrator'
String password = 'examplePWD'
String url = 'example_EPM_URL'
String updateversions = '01,04,07,10'
String podtype = 'test'
String proxyserverusername = ''
String proxyserverpassword = ''
String proxyserverdomain = ''

def currentdate = new Date()
def yf = new SimpleDateFormat("yy")
def mf = new SimpleDateFormat("MM")
String[] monthsarr = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]
List<String> monthsarrfromcurrent = new ArrayList<>()
List<String> yearsarrfromcurrent = new ArrayList<>()
String currentyear = yf.format(currentdate)
String nextyear = (currentyear.toInteger() + 1).toString()
String currentmonth = mf.format(currentdate)

String[] updateVersionsStringArr = updateversions.split(',');
def updateversionsarr = new int[updateVersionsStringArr.length];
for(int i = 0; i < updateVersionsStringArr.length; i++)
{
    updateversionsarr[i] = Integer.parseInt(updateVersionsStringArr[i]);
}

def LogMessage(String message) {
    def date = new Date()
    def sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
    println('[' + sdf.format(date) + '][GROOVY] ' + message);
}

def LogOperationStatus(EpmAutomateStatus opstatus) {
    def returncode = opstatus.getStatus()
    LogMessage(opstatus.getOutput())
    LogMessage('return code: ' + returncode)
}

int CompareUpdateMonths(int thismonth, int nextmonth) {
    int nextmonthorig = nextmonth

    if (nextmonth < thismonth) {
        nextmonth = nextmonth + 12
    }

    int monthdiff = nextmonth - thismonth

    if (monthdiff > 4) {
        LogMessage('There are more than 3 versions skipped from version ' + thismonth + ' to version ' + nextmonthorig + '. Please correct updateversions so that there are not more than three versions skipped between each update version. Exiting.')
        return 1
    }
    
    return 0
}

int ValidateUpdateMonths(int[] updateversionsarr) {
    for(int i = 0; i < updateversionsarr.length; i++)
    {
        int nextint = i + 1
        String nextupdatemonth = ""
        int nextupdatemonthint = 0
        String thisupdatemonth = updateversionsarr[i]
        int thisupdatemonthint = thisupdatemonth.toInteger()
        
        if (nextint < updateversionsarr.length) {
            nextupdatemonth = updateversionsarr[nextint]
        } else {
            nextupdatemonth = updateversionsarr[0]
        }
        
        nextupdatemonthint = nextupdatemonth.toInteger()
        
        int returncode = CompareUpdateMonths(thisupdatemonthint, nextupdatemonthint)
        if (returncode > 0) {
            return 1
        }
    }
    return 0
}

def SkipUpdateAdd(EpmAutomate automate, String yearnumber, String monthnumber) {
    String yeardotmonth = yearnumber + '.' + monthnumber
    LogMessage('Running: epmautomate skipUpdate add version=' + yeardotmonth + ' comment=\"adding skipUpdate\"')
    EpmAutomateStatus status = automate.execute('skipupdate','add','version=' + yeardotmonth,'comment=\"adding skipUpdate\"')
    LogOperationStatus(status)
}

LogMessage('Starting skip update processing')
EpmAutomate automate = getEpmAutomate()

// validate update months
int returncode = ValidateUpdateMonths(updateversionsarr)
if (returncode != 0) {
    return 1
}

// populate arrays
int startposition = 0
for(int i = 0; i < monthsarr.length; i++)
{
    if (currentmonth == monthsarr[i]) {
        if (podtype.equals("prod")) {
            if (updateVersionsStringArr.contains(currentmonth)) {
                startposition = (i-2)
            } else {
                startposition = (i-1)
            }
        } else {
            if (updateVersionsStringArr.contains(currentmonth)) {
                startposition = i
            } else {
                startposition = (i-1)
            }
        }

        break
    }
}

if (startposition < 0) {
    startposition = startposition + 12
}
 
for(int i = 0; i < monthsarr.length; i++)
{
    if (i >= startposition) {
        monthsarrfromcurrent.add(monthsarr[i])
        yearsarrfromcurrent.add(currentyear)
    }
}

for(int i = 0; i < monthsarr.length; i++)
{
    if (i <= startposition) {
        monthsarrfromcurrent.add(monthsarr[i])
        yearsarrfromcurrent.add(nextyear)
    }
}

// process skip updates
LogMessage("Operation: encrypt " + password + " oracleKey password.epw")
EpmAutomateStatus status = automate.execute('encrypt',password,"oracleKey","password.epw")
LogOperationStatus(status)

if ((proxyserverusername != null && proxyserverusername != '') && (proxyserverpassword != null && proxyserverpassword != '') && (proxyserverdomain != null && proxyserverdomain != '')) {
    LogMessage("Operation: login " + username + " password.epw " + url + " ProxyServerUserName=" + proxyserverusername + " ProxyServerPassword=" + proxyserverpassword + " ProxyServerDomain=" + proxyserverdomain)
    status = automate.execute('login',username,"password.epw",url,"ProxyServerUserName=" + proxyserverusername,"ProxyServerPassword=" + proxyserverpassword,"ProxyServerDomain=" + proxyserverdomain)
    LogOperationStatus(status)
} else {
    LogMessage("Operation: login " + username + " password.epw " + url)
    status = automate.execute('login',username,"password.epw",url)
    LogOperationStatus(status)
}
LogMessage('Running: epmautomate skipUpdate remove')
status = automate.execute('skipupdate','remove')
LogOperationStatus(status)

int addcount = 0
int countlimit = 0

if (podtype.equals("prod")) {
    countlimit = 3
} else {
    countlimit = 2
}

for (int i = 0; i < monthsarrfromcurrent.size(); i++) {
    int match = 1
    
    if (addcount == countlimit){
        LogMessage('Update add calls are completed. No more will be attempted.')
        break
    }
    
    for(int j = 0; j < updateversionsarr.length; j++) {

        if ((Integer.parseInt(currentmonth) == updateversionsarr[j]) && (addcount > 0)) {
            match = 1
            break
        }
    
        if ((Integer.parseInt(monthsarrfromcurrent.get(i)) == updateversionsarr[j]) && (addcount == 0)) {
            match = 0
            break
        }
    }
    
    if (match == 1) {
        SkipUpdateAdd(automate, yearsarrfromcurrent.get(i), monthsarrfromcurrent.get(i))
        addcount+=1
    }
}

LogMessage('Running: epmautomate skipUpdate list')
status = automate.execute('skipupdate','list')
LogOperationStatus(status)
println(status.getItemsList())

LogMessage('Running: epmautomate logout')
status = automate.execute('logout')
LogOperationStatus(status)

LogMessage('Skip update processing completed')

Creating the input.properties File to Run skip_update Windows and Linux/UNIX Scripts

To run skip_update.ps1 or skip_update.sh, create the input.properties file and update it with information for your environment. Save the file in a local directory. Contents of this file differ depending on your operating system.

Windows

username=exampleAdmin
password=examplePassword.epw
url=exampleURL
updateversions=01,04,07,10
podtype=test

Linux/UNIX

javahome=JAVA_HOME
epmautomatescript=EPM_AUTOMATE_LOCATION
username=exampleAdmin
password=examplePassword.epw
url=exampleURL
updatemonths=02,05,08,11

Table 3-14 input.properties Parameters

Parameter Description
javahome JAVA_HOME location. For Linux/UNIX only.
epmautomatescript Absolute path of EPM Automate executable (epmautomate.sh). For Linux/UNIX only.
username User name of a Service Administrator.
password Password of the Service Administrator or the name and location of the encrypted password file.
url URL of the environment on which you want to set the non-monthly update cadence.
updateversions updateversions A comma separated list of EPM Cloud updates that should be applied to the environment identified by the url parameter. For example, updateversions=02,05,08,11.

Versions must be specified as two digits; include a preceding zero for updates 01 through 09. The script attempts to run the skipUpdate command for the updates not included in the updateversions parameter value. For example, if you specify updateversions=02,05,08,11, the script tries to set skip update flags for the 01 (January), 03 (March), 04 (April), 06 (June), 07 (July), 09 (September), 10 (October), and 12 (December) updates. In this case, EPM Cloud updates 02 (February), 05 (May), 08 (August), and 11 (November) are applied to the environment.

podtype EPM Cloud environment type. Valid values are test and prod.

Running the Script

  1. For Windows and Linux/UNIX: only
    • Create skip_update.ps1 or skip_update.sh by copying the script from a preceding section.
    • Create the input.properties file and save it in the directory where skip_update script is located. Contents of this file differs depending on your operating system. See Creating the input.properties File to Run skip_update Windows and Linux/UNIX Scripts.

      Make sure that you have write privileges in this directory. For Windows, you may need to start PowerShell using the Run as Administrator option to be able to run the script.

    • Launch the script.
      • Windows PowerShell: run skip_update.ps1.
      • Linux/UNIX: run ./skip_update.sh.
  2. Server-Side Groovy: