17 November 2014

CalcMgrExecuteMaxLScript and RUNJAVA

Introduction

This is just a super (well sort of) quick post on the @CalcMgr CDF and running MaxL scripts.

You saw that I previously discussed the @CalcMgrExecuteEncryptMaxLFile command and showed how both to use that calc script function as well as the RUNJAVA equivalent.

Over the weekend, mostly because we are sad individuals, Peter Nitschke, Tyler Feddersen, and I were going over how to use @CalcMgrExecute in conjunction with MaxL shelling to run batch code.  Fascinating, eh?  Maybe.

In the course of that, I stumbled my way through the RUNJAVA syntax (which, of course, is maddeningly different than the RUNJAVA commands for running the encrypted MaxL file and no, not in the way you would think) and came up with one or two interesting twists on passing both member names and just plain old parameters to a MaxL script.

One note – I am not going to go into how to use shelling in MaxL scripts, but am just going to cover the basics and one or two odd things in running MaxL scripts in this post.

What am I trying to run?

Here’s the MaxL script noencrypt.msh:


The username, password, servername, and a single member name must be passed as parameters.

RUNJAVA

When it comes to using the Calc Mgr MaxLFunctions CDF with RUNJAVA the important bit to understand is that it is position dependent.  By that I mean the code that runs encrypted MaxL scripts and the code that runs non-encrypted MaxL scripts has no explicit flag that tells RUNJAVA to run them one way or the other.  Instead, it is the presence of the –D and encrypted keys (or maybe it’s just –D – dunno on that one as I try to have some kind of a life) that forces an encrypted script execute.  

And the absence of that information makes the RUNJAVA invocation of the CDF run the MaxL script as non-encrypted.  Interesting, eh?  I have to look into other commands but again, I sort of have a life, or at least I try to.

Remember this about RUNJAVA – it does absolutely zero syntax checking.  You could stick NowIsTheTimeForAllGoodMenToComeToTheAidOfTheirParty and EAS wouldn’t throw an error.

Non-encrypted MaxL file

If you want to do it the right way, see the below:

One thing that is nice about this is that you do not have to pass the username, password, and servername to the MaxL script unless you wish to as the RUNJAVA parameters you see there are just that – parameters.  And just like running a MaxL script from a command line, what gets passed, if anything, is up to you.

Another thing to note is the double quotes, double backslashes.  I’ve used double quotes and single forward slashes – it never occurred to me that my advice on MaxL scripts quoting and escaping also applied to RUNJAVA.  Thanks, Peter, for pointing that out.

Encrypted MaxL file

This is in contrast to the way an encrypted MaxL script is called via RUNJAVA.  I suppose one could argue that this is not all that unreasonable – when an encrypted MaxL script is called from the command line it must receive the decrypt flag and the public key.  What the @CalcMgrExecute (or its RUNJAVA) equivalent also requires is the username and password in encrypted for even though the called MaxL script has that information.  Weird.

After the encryption information, you can optionally pass more parameters such as the server name and a member name.

@CalcMgrExecuteMaxLFile

If RUNJAVA isn’t your cup of tea, you could always use @CalcMgrExecuteMaxLFile.  The nice thing about this command is that it will syntax check your code.  I actually used this technique first to back into what I would need for the RUNJAVA equivalent.

Remember that you must have a block to run this in (it is, after all, a calc script function), and only select one block in your code unless you want to run this multiple times, once for each block.

Non-encrypted

Note that parameters must be enclosed within a @LIST function.  You will also note that only the member name Inventory has a @NAME function surrounding it.

Encrypted

For a point of contrast to RUNJAVA, note that this approach does NOT force you to pass the encrypted username and password – just the public key.  No, I have no idea why the two are different since they call the same function within the CDF.  Some Things Are Not Meant To Be Understood.

Would you believe?

In both encrypted and non-encrypted MaxL, note this odd bit:

Note the @NAME() around the username.  This will syntax check and run quite nicely.  But remember, hypadmin is a username, not a member.

Alas and alack, but not all that surprisingly, when I remove @NAME() from around the member name Inventory, EAS pukes:

From this, I take it that the CDF doesn’t care if you wrap non-member names in @NAME() but does care if you leave that off of real member names.  Weird but there it is.

And of course RUNJAVA could give a tinker’s damn about @NAME – it takes parameters as you pass them and off it goes.


Addendum


Peter had shown me a technique that ignored the username and password early in our email chain.  For whatever reason, I could not get it to work.  And then, as so often happens in at least my life, I told him that, and then I tried it again, and then…it worked.  Arrrgh.  So here’s the code, thanks to Peter:

 

Just in case you missed the syntax for not passing the username and password, it is:
"",""

That is doublequote-doublequote-comma-doublequote-doublequote.  I swore that I tried exactly that in my tests but given that it failed and then worked, I got something wrong. 

I did ask Peter how he figured that syntax out as it is not documented (well, that is sort of the purpose of this post, but still).  His reply, “I'm lazy? *grin* Wanted to see how little I could put in a piece of code and have it work.”  The sign of a true hacker.  Thanks again, Peter.
Conclusion
The Calc Mgr CDF is really powerful, hardly used (although that seems to be changing), and is still not documented.  Play around with it, look for that essfunc.xml file on your server to give you a few ideas, and have fun.

Be seeing you.

Thanks again to Peter and Tyler on this – always fun, if a bit geeky, to share interests in code.

4 comments:

  1. @NAME is extremely useful if you've Boolean attributes. I've a friend of mine calling me "Cameron and you blogged about executing MaxL from Calc Man, for me it is not working". Guess what he had text attribute with "TRUE" and "FALSE" :(

    ReplyDelete
  2. I like how the two of us are now CameronCelvin or CelvinCameron.

    So are you saying he had the asynchronous flag set to TRUE/FALSE instead of true/false?

    Java is case-sensitive, right?

    And we did document it, right?

    What else can we do?

    :)

    Regards,

    Cameron Lackpour

    ReplyDelete
  3. :)

    Instead of CL and CK we can now use CC ;)

    Well, we'll keep doing that and some might read it (thoroughly) :)

    ReplyDelete
  4. CamCelvin! Camvin! Celmeron!

    Sounds like I'm shouting names from the Hobbit.

    Anyways. Some additional notes from some testing with shell to batch.

    - You need to have absolute paths for everything
    - I 'think' the command isn't running elevated (I suppose I could check), so some of the commands don't work (pushd is a big one, I think because running as non elevated it can't directly access network shares).
    - Seems to have a bug with the CALL command. The session doesn't return control so the calc script never finishes. Also, restarting the services while this is 'stuck' seems to corrupt the app
    - The START command works perfectly, and you can even put in a /Wait command to wait for the command to return
    - PSEXEC works with the start command, so this would be the recommended method, even when triggering things at localhost. The -h command will trigger an elevated session if required, or you can nest service account usernames/passwords in the string.
    - By default the function is run out of \\essbase-server\c$\Oracle\Middleware\user_projects\ESSBASE1

    Cheers
    pete

    ReplyDelete