maxl utils

Preview:

Citation preview

Using MaxL to Automate Essbase

Cameron LackpourinterRel Consulting

Disclaimer• These slides represent the work and opinions of the

presenter and do not constitute official positions of Oracle.

• This material has not been peer reviewed and is presented here with the permission of the presenter.

• This material should not should not be reproduced without the written permission of the presenter and interRel Consulting.

What this session isn’t• Not an introduction to MaxL• Great presentation at Kaleidoscope 2008

by Tracy McMullen• Link:

http://www.odtug.com/apex/f?p=500:570:280884916307492::NO::P570_CONTENT_ID:3630

• Or just search the Tech Resources section of www.odtug.com for “maxl”

So, what’s the content?• Variables, variables, variables• Making your auditors happy (encryption)• Playing the Shell game• Setting a trap for errors• The triumvirate of NT cmd scripts,

VBScript, and MaxL

How does it come together?• Fix what Oracle won’t

– Make Essbase look like Planning– Change Read filters to Metaread

• Next session– “Getting It All Automated With Perl Scripting”

What does MaxL stand for?• (M)aximum (a)wfulness e(x)pressed in a

(L)anguage• (M)ost (a)wesome e(x)cellent (L)anguage• (M)ulti-dimensional database (ax)ccess

(L)anguage– Thanks to Tim Faitch

• (M)ulti-dimensional (a)utomation E(x)pression (L)anguage– Thanks to Glenn Schwartzberg

Hardcoding gives me hives• Especially when MaxL gives you three

options– Command line– Locally defined– Environment

Ugly but succinct positionals

/*Login to Essbase */

login $1 $2 on $3 ;

exit ;

But the result is beautiful• TypeC:\>essmsh sample1.msh essadmin essbase d630

• Get backMAXL> login essadmin essbase on d630 ;

OK/INFO - 1051034 - Logging in user [essadmin].

OK/INFO - 1051035 - Last login on Friday, May 08, 2009 12:02:32 PM.

OK/INFO - 1241001 - Logged in to Essbase.

MaxL Shell completed

Respect the environment• OS defined• Addressable by name• Type (in Windows command shell)

C:\>set computername

• Get backCOMPUTERNAME=D630

A little more readable• Stick a “$” in the front and the namelogin $1 $2 on $COMPUTERNAME ;

exit ;

And the result is the same• TypeC:\>essmsh sample2.msh essadmin essbase

• ResponseMAXL> login essadmin essbase on D630 ;

OK/INFO - 1051034 - Logging in user [essadmin].

OK/INFO - 1051035 - Last login on Friday, May 08, 2009 12:01:33 PM.

OK/INFO - 1241001 - Logged in to Essbase.

MaxL Shell completed

Locally defined within code/* Declare variables */

set varUserName = essadmin ;

set varPassword = essbase ;

set varServerName = d630 ;

set varSpoolFile = 'c:\tempdir\odtug_2009\local.log' ;

/* Connect to server */

login $varUserName $varPassword on $varServerName;

/* Write STDOUT to log file */

spool on to $varSpoolFile ;

echo $varUserName;

/* Exit from MaxL shell */

exit ;

The result doesn’t change, much• TypeC:\>essmsh local.msh

• ResponseMAXL> login essadmin essbase on d630 ;

OK/INFO - 1051034 - Logging in user [essadmin].

OK/INFO - 1051035 - Last login on Friday, May 08, 2009 12:54:10 PM.

OK/INFO - 1241001 - Logged in to Essbase.

essadmin

MaxL Shell completed

local.logessadmin

• More on this later

What’s wrong with this picture?• Admin username and password• Auditors seem to dislike this

– Why is that, exactly?• And you can’t fix it with local variables• But you can if positional

So which is best?• Positional

– Must be on command line– Most flexible– Cryptic

• Environment– Must be defined within OS

• Local– Easiest to understand/read– Not good for server migration

Encryption review• Public key encryption

– Asymmetric key algorithms • Encrypt (public) and decrypt (private) keys are

different• Generated through large random number and

black-box magic

• MaxL generates both keys for you• Different every time it’s run• Stick with the same pair

Generate those keys• TypeC:\>essmsh –gk

• ResponsePublic Key for Encryption: 26429,694177571

Private Key for Decryption: 316108469,694177571

MaxL Shell completed

Simple codelogin essadmin essbase on d630 ;

exit ;

Encrypt script with public key• TypeC:\>essmsh -E tobeencrypted.msh 26429,694177571

• ResponseEssbase MaxL Shell - Release 9.3.1 (ESB9.3.1.3.0B017)

Copyright (c) 2000, 2007, Oracle and/or its affiliates.

All rights reserved.

MaxL Shell completed

tobeencrypted.mshslogin $key 994958605500155654401932116812299621 $key

080321016292835195975318016812299621 on d630;

exit ;

It blew up real good• TypeC:\>essmsh tobeencrypted.mshs

• ResponseMAXL> login $key 994958605500155654401932116812299621 $key

080321016292835195975318016812299621 on d630;

essmsh error: Variable doesn't exist - $key

essmsh error: Variable doesn't exist - $key

MaxL Shell completed

So decrypt with private key• Type• C:\>essmsh -D tobeencrypted.mshs 316108469,694177571

• ResponseMAXL> login $key 994958605500155654401932116812299621 $key

080321016292835195975318016812299621 on d630;

OK/INFO - 1051034 - Logging in user [essadmin].

OK/INFO - 1051035 - Last login on Friday, May 08, 2009 2:24:59 PM.

OK/INFO - 1241001 - Logged in to Essbase.

MaxL Shell completed

Hardcoded username and password• Parameters don’t make sense• No joy for locally defined variables• Only focuses on login statement

Three shells and a pea• No sleight of hand – you are not marks• Sometimes the OS needs to help out

– Creating/Deleting/Moving files– Kicking off other processes– Other tasks

Code still isn’t complicatedlogin essadmin essbase on d630 ;

/*Wait for 60 seconds */

shell 'ping -n 60 localhost > nul' ;

Scripts within scripts• Nesting is easy• msh scriptname• Login info passed• Think of the possibilities

Useless by themselves• properties.msh/* Declare variables */

set varUserName = essadmin ;

set varPassword = essbase ;

set varServerName = d630 ;

set varSpoolFile = 'c:\tempdir\odtug_2009\nested.log' ;

• connect.msh/* Connect to server */

login $varUserName $varPassword on $varServerName;

/* Write STDOUT to log file */

spool on to $varSpoolFile ;

• disconnect.msh/* Exit from MaxL shell */

exit ;

Sum is greater than its parts• nested.mshmsh properties.msh ;

msh connect.msh ;

msh disconnect.msh ;

• Stole it from:http://essbaselabs.blogspot.com/2009/04/organizing-maxl-

scripts.html

– Thanks to Matt Milella

Eeny, meeny, miny, moe• We’re catching errors, not tigers• iferror

• OS return codes• STDERR and spool

You’re doing this, right?• What could possibly go wrong?• Every action needs to be tested for failure• That 3 am call• Iferror and define label are your

BFFs

What do want to do?• Login• Clear out good old Sample Basic• Load• Calc

Murphy is paying a visitlogin essadmin essbase on d630;

alter database Sample.Basic1 reset data ;

import database Sample.Basic data from local text data_file

'C:\Hyperion\AnalyticServices\app\Sample\Basic\calcdat.txt'

on error write to 'c:\tempdir\odtug_2009\calcdat.err' ;

execute calculation Sample.Basic.CalcAll ;

exit ;

Whoops• TypeC:\>essmsh hellomurphy.msh

• Response (trimmed)MAXL> alter database Sample.Basic1 reset data ;

ERROR - 1056024 - Database Sample.Basic1 does not exist.

MAXL> import database Sample.Basic data from local text data_file

2> 'C:\Hyperion\AnalyticServices\app\Sample\Basic\calcdat.txt'

3> on error write to 'c:\tempdir\odtug_2009\calcdat.err' ;

Catch the errorlogin essadmin essbase on d630;

iferror 'ErrorHandler' ;

alter database Sample.Basic1 reset data ;

iferror 'ErrorHandler' ;

import database Sample.Basic data from local text data_file

'C:\Hyperion\AnalyticServices\app\Sample\Basic\calcdat.txt'

on error write to 'c:\tempdir\odtug_2009\calcdat.err' ;

iferror 'ErrorHandler' ;

execute calculation Sample.Basic.CalcAll ;

iferror 'ErrorHandler' ;

define label 'ErrorHandler' ;

exit ;

And now it gracefully(?) ends• TypeC:\>essmsh catchthaterror.msh

• ResponseMAXL> login essadmin essbase on d630;

OK/INFO - 1051034 - Logging in user [essadmin].

OK/INFO - 1051035 - Last login on Friday, May 08, 2009 2:55:24 PM.

OK/INFO - 1241001 - Logged in to Essbase.

MAXL> alter database Sample.Basic1 reset data ;

ERROR - 1056024 - Database Sample.Basic1 does not exist.

MaxL Shell completed

The OS is your friend• %ERRORLEVEL% is crude, yet effective• 0 = successful MaxL script• <> 0 = trouble• Not just for MaxL

Good old %erorrlevel%• TypeC:\>%errorlevel%

• Response'2' is not recognized as an internal or external command,

operable program or batch file.

No errors = 0• TypeC:\>essmsh parameters.msh essadmin essbase d630

• ResponseMAXL> login essadmin essbase on d630 ;

OK/INFO - 1051034 - Logging in user [essadmin].

OK/INFO - 1051035 - Last login on Friday, May 08, 2009 3:05:02 PM.

OK/INFO - 1241001 - Logged in to Essbase.

MaxL Shell completed

C:\>%errorlevel%

'0' is not recognized as an internal or external command,

operable program or batch file.

DOS (not really) lives@ECHO OFF

%hyperion_home%\analyticservices\bin\essmsh.exe catchthaterror.msh

IF NOT %ERRORLEVEL% == 0 (SET errormsg=Error! - catchthaterror.msh ran with errors and return code %ERRORLEVEL% & GOTO ERROR)

REM No errors, so jump over the error logger

GOTO END

:ERROR

> call_CatchThatError.log ECHO %errormsg%

:END

Output = badError! - CatchThatError.msh ran with errors and return code 2

Piping output to files• spool

• Two choices– STDOUT

– STDERR

• Or log both

Two of a kindspool stdout on to 'c:\tempdir\odtug_2009\SpoolMe.log' ;

spool stderr on to 'c:\tempdir\odtug_2009\SpoolMe.err' ;

login essadmin essbase on d630;

iferror 'ErrorHandler' ;

alter database Sample.Basic1 reset data ;

iferror 'ErrorHandler' ;

etc.

etc.

etc.

• SpoolMe.logMAXL> login essadmin essbase on d630;

OK/INFO - 1051034 - Logging in user [essadmin].

OK/INFO - 1051035 - Last login on Friday, May 08, 2009 3:14:41 PM.

OK/INFO - 1241001 - Logged in to Essbase.

MAXL> alter database Sample.Basic1 reset data ;

• SpoolMe.errERROR - 1056024 - Database Sample.Basic1 does not exist.

What does it look like?

Okay, but so what?• Test for the presence of SpoolMe.log

– Tells you that the job ran• Test for the presence of SpoolMe.err

– Tells you if there was a failure• Throw in %ERRORLEVEL%

In the Windows worldREM Call and run SpoolMe.msh

%hyperion_home%\analyticservices\bin\essmsh.exe SpoolMe.msh

REM If SpoolMe.log doesn't exist, error

IF NOT EXIST SpoolMe.log (SET errormsg=Error! - SpoolMe.msh failed to run & GOTO ERROR)

REM If SpoolMe.err does exist, error

IF EXIST SpoolMe.err (SET errormsg=Error! - SpoolMe.msh ran with errors & GOTO ERROR)

REM No errors, so jump over the error logger

GOTO END

Nice n’ Easy*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

Load and calc of Sample.Basic

Current time at \\D630 is 5/8/2009 3:20 PM

The command completed successfully.

ECHO is off.

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Error! - SpoolMe.msh ran with errors

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

ECHO is off.

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Execution of SpoolMe.msh ended at :

Current time at \\D630 is 5/8/2009 3:20 PM

The command completed successfully.

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

What do I do with this?• Typical use

– Loading and calculating data– Creating partitions– Applying security

• Atypical– Fixing Planning

Planning and filters• Planning

– Metadata filtering– Like METAREAD

• Essbase and Financial Reports– READ

• Why?

Planning meta filtering

Admin Planner

Not in reporting tools

Admin Planner

What’s the problem?Access Member specificationRead "BalanceSheet",@IDES("IncomeStatement"),@IDES("E02"),"F

orecast","Plan","Working","BU Version_1","Final"

None @IDES("Account"),@IDES("Scenario"),@IDES("Version"),@ID ES("Entity")

Easy fix in EASAccess Member specificationRead "BalanceSheet",@IDES("IncomeStatement"),@IDES("E02"),"F

orecast","Plan","Working","BU Version_1","Final"

None @IDES("Account"),@IDES("Scenario"),@IDES("Version"),@ID ES("Entity")

Metaread "BalanceSheet",@IDES("IncomeStatement"),@IDES("E02"),"F orecast","Plan","Working","BU Version_1","Final"

Isn’t that pretty?

Planning strikes againAccess Member specificationRead "BalanceSheet",@IDES("IncomeStatement"),@IDES("E02"),"F

orecast","Plan","Working","BU Version_1","Final"

None @IDES("Account"),@IDES("Scenario"),@IDES("Version"),@ID ES("Entity")

What do we want to happen?• Refresh Planning

– Dimensions– Security

• Apply Metaread rights to Planning filters

How do we do this?• Automate

– CubeRefresh.cmd– NT CMD, VBScript, and MaxL script(s)

• Drive values through OS parameters• Wrap the whole thing in error checking

– ERRORLEVEL

– spool

Steps1. Planning refresh with CubeRefresh.cmd2. Write filters to disk3. Read them into memory4. Generate MaxL code to apply

METAREAD5. Run the new nested script6. Be happy

Refresh_Planning.cmd command lineParameter ValuePlanning encrypted password file c:\tempdir\odtug_2009\password.txt

Planning application plansamp

Planning admin username admin

Refresh or create /R

Filter switches /FS

Essbase server %computername%

First half of private key 316108469

Second half of private key 694177571

Looks likerefresh_planning.cmd c:\tempdir\odtug_2009\password.txt plansamp

admin /R /FS %computername% 316108469,694177571

Automate Planning refresh• Modified CubeRefresh.cmd• Dumps to prompt• Add EXIT, save to script dirModCubeRefresh.cmd

@echo off

set PLN_JAR_PATH=C:\Hyperion\products\Planning\bin

call "%PLN_JAR_PATH%\setHPenv.bat"

"%HS_JAVA_HOME%\bin\java" -Dhyperion.home=%HYPERION_HOME% com.hyperion.planning.HspCubeRefreshCmd %1 %2 %3 %4 %5 /COMMAND:CubeRefresh.cmd >>%6

EXIT

Run the refreshREM start /wait /min modcuberefresh.cmd -

f:c:\tempdir\odtug_2009\password.txt /A:plansamp /U:admin /R /FS %log%

START /WAIT /MIN ModCubeRefresh.cmd -f:%1 /A:%2 /U:%3 %4 %5 %log%

REM Test for errors from the Planning refresh process

IF %ERRORLEVEL% == 1 (SET errormsg=Error! - Planning refresh of %2 on %COMPUTERNAME% failed & GOTO ERROR)

Write all filters to discREM Write filters to disc

%hyperion_home%\products\Essbase\EssbaseClient\bin\essmsh.exe -D write_filters_to_disc.mshs %7,%8

REM If error, go to end, else write

IF ERRORLEVEL == 1 (SET errormsg=Error! - Read of filters from Essbase failed & GOTO ERROR)

write_filters_to_disc.mshs/* Create log file that will contain the filter contents */

spool on to 'Write_Filters_To_Disc.log';

/* Log on to the server using the: userid, password, and servername */

login $key 152862484425455861686132835 $key 420285733240440925357332674133471265 on $COMPUTERNAME ;

/* Set the column width to 1000 characters to allow the filter plenty of room. */

set column_width 1000 ;

/* Show those filters */

display filter row all ;

/* End the spooling. */

spool off ;

/* End of code. */

exit ;

Create MaxL scriptREM Use Windows Scripting Host to parse the filter file and

write out MaxL code to add MetaRead filters

CSCRIPT Create_MetaRead_Filters.wsf /Application:%2 /FilterFile:Write_Filters_To_Disc.log /OutputFile:Metaread_Add_Filters.msh

REM If the output file doesn't exist, an error has occurred

IF NOT EXIST MetaRead_Add_Filters.msh (SET errormsg=Error! - Creation of MaxL include file failed %2 & GOTO ERROR)

Metaread_Add_Filters.mshALTER FILTER 'PlanSamp'.'Consol'.'fplanuser' ADD META_READ ON

'"BalanceSheet",@IDES("IncomeStatement"),@IDES("E02"),"Forecast ","Plan","Working","Final","BU Version_1"' ;

Nest alter filter codeREM Execute add metaread MaxL script

%hyperion_home%\products\Essbase\EssbaseClient\bin\essmsh.exe -D call_metaread_add_filters.mshs %7,%8

REM If the log file doesn't exist, an error has occurred

IF EXIST call_metaread_add_filters.err (SET errormsg=Error! - Execution of MaxL include file for METAREAD ADD failed & GOTO ERROR)

call_metaread_add_filters.mshs/* Write out only errors to the log file. Use this to determine error

status. */

spool stderr on to 'call_metaread_add_filters.err' ;

/* Log on to the server using the: userid, password, and servername*/

login $key 152862484425455861686132835 $key 420285733240440925357332674133471265 on $COMPUTERNAME ;

/* Include the VBScript-generated METAREAD ADD MaxL code. */

msh 'metaread_add_filters.msh';

/* End the spooling. */

spool off ;

/* End of code. */

exit ;

Refresh_Planning.log*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

Planning refresh of plansamp on DEMO111 beginning at:

Current time at \\DEMO111 is 5/10/2009 11:14 AM

The command completed successfully.

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Output from ModCubeRefresh.cmd

Cube refresh completed successfully.

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Planning refresh succeeded

Now getting filters from all Essbase databases

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Filter dump successful.

Parse all filters to create MaxL include for plansamp

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Creation of MaxL include code successful

Execute MaxL include code to create METAREAD filters

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Error! - Execution of MaxL include file for METAREAD ADD failed

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

Planning refresh of plansamp on and application of METAREAD filters ended at:

Current time at \\DEMO111 is 5/10/2009 11:14 AM

The command completed successfully.

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

The proof of the pudding

What have we learned?• Scripting is fun• But only if it’s:

– Not hardcoded– Secure– Logged– Error trapped

• One way to make Essbase dance

Q&A

Thanks for your time

Cameron LackpourinterRel Consulting

Recommended