Sei sulla pagina 1di 32

Scripting With Maximo

Anamitra Bhattacharyya [Lead Developer]


Sampath Sriramadhesikan [Lead Designer]
Scripting is a new featre that was introdced in Maximo version !"# $ased on
the feed$ack from the ser commnity who yearned to have a simpler yet
effective way of cstomi%ing the prodct withot having to go throgh the pain of
system downtime and steep learning crve"
While Maximo provides great many cstomi%ation points& most of them needs
'A(A coding skills to do any meaningfl [logic $ased] cstomi%ation" )t also
wold often need deep knowledge of Maximo apis as well as the Maximo
internals" *hat can often $e a danting task even for an experienced
programmer"
)n comes Maximo scripting to help ease some of these concerns" Maximo
scripting is primarily $ased on the 'S+ ,,- specification which is part of 'A(A ."
*his 'S+ allows a 'A(A application [in this case Maximo] to host script engines
which are compliant to this specification" *he engines that are spported in an
//*B Maximo !# are
0" Mo%illa +hino 1'avaScript2 which ships with the )BM3/racle1Sn2 'D4
," 'ython which is inclded as part of Maximo
*his $asically implies that sers can se either of these , scripting langages to
cstomi%e Maximo sing the Maximo scripting framework" We do nderstand
that there are other poplar 'S+ ,,- compliant scripting engines like
'+$y35roovy and it shold $e fairly simple to add spport for these $y adding
these engines [6ars] in Maximo application classpath" *he way the scripting
framework is written 7 it shold $e a$le to detect those 6ars from the classpath
and show them as availa$le langages in the scripting application" 8owever )
wold like to mention that at this point Maximo has only $een tested with the
+hino9'avaScript and 'ython engines and 'S+ ,,- $eing fairly new& a lot of the
:compliant; engines may have potential isses with their implementation which
can prevent seamless integration with Maximo"
<ow lets get familiar with the different artifacts of the scripting framework" Below
is a figre which can give yo a visal feel for the design and rn9time artifacts"
Design *ime
<o
=es
<o
)s there an existing
script>
)dentify Maximo
component point to
cstomi%e
?reate Launchpoint
for that component
point
Select script
=es
Modify varia$le
$indings [if needed]
Bind Variables
Athor3@dit
Script
?ommit Design
?ommit Design
Data$ase
?ompile @rror>
Attach Lancpoint
Aroxy to target
Maximo ?omponent
?ompile
Script
?ache
?ompile
d Script
Based on this design flow chart we can see that there are - distinct artifacts 7
Lanchpoint& Script and (aria$les which make p the framework"
Script
Birst of corse is the script which is a text file that yo can edit inside Maximo or
otside of Maximo [in yor choice of editors and import $ack into Maximo]" @very
script has an associated attri$te 7 scriptlangage which helps the rn9time
figre ot the appropriate script engine to invoke for processing the script" *he
vale list for availa$le script langages come from the providing script engines in
the classpath" )ts common for script engines to provide mltiple alias or short
names for the langage spport provided $y that engine" Bor example the 6ython
engine provides , names 7 6ython and python 7 $oth referring to the same
engine3script langage" Selecting either one is fine and prodces identical
$ehavior" Most engines spport script compilation which eventally converts the
script to a execta$le $ytecode [for the '(M]" *he ones that we spport //*B 7
'avaScript and 'ython $oth spport complied scripts" When the deployer is
commiting the design process 7 in the $ackgrond the framework wold compile
and cache the script" *his process is often referred to as generating :hot; scripts
which are ready to execte" <ote if there is a compile failre the process will not
commit and the deployer has to fix the script to proceed"
Before we 6mp frther into these artifacts we will look into the application
spport for the scripting framework"
Script/Launch point Creation
*his is done via wi%ards lanched from the list ta$ in the atoscript application"
*he atoscript application can $e lanched from the 5o*o C System
?onfigration C Atoscript men" )n the list ta$ drop down actions list there are
a slew of wi%ards that lets yo
0" ?reate a vanilla script withot any lanch point"
," ?reate Scripts with /$6ect lanch point"
-" ?reate Scripts with Attri$te lanch point"
D" ?reate Scripts with Action lanch point"
#" ?reate scripts with cstom condition lanch point"
*hese wi%ards will drive yo throgh the process of creating a script and
associating lanch points with it" We will discss lanch points in details in a later
section"
Script/Launch point maintenance
After the script and lanch point have $een created 7 sers can come to the
atoscript application for maintenance" *his can $e done sing the
main3varia$les3lanch point ta$s in that application" /ne can modify the script&
add or pdate the varia$les and their $indings as well as the $indings in the
lanch point level [if they are overrida$le]" Deletion of varia$les are not allowed
nless none of the lanch points refer to that varia$le"
Variables and Bindings
<ext in line are the variables and their bindings" (aria$les are what the scripts
se to interact with Maximo" (aria$les can $e )<& )</E* or /E*" *hese follow
the classical defintion of )<9 pass $y vale& )</E*3/E* 7 passed $y reference"
*he script can modify only the )</E* and /E* type of varia$les" Modification of
)< varia$les in the script has no impact otside the script" (aria$les can $e
$ond to a Maximo artifact like a m$o attri$te& a maxvar& a maximo system
property or can $e $ond to a literal vale which does not tie $ack to any
Maximo artifact" <ote varia$les $ond to a maxvar or a system property are of
type )< only as they cannot $e modified $y the script" (aria$les can $e scalar or
array type" Array type varia$les are only spported for m$o attri$te $indings
and are always of )< type" More on array type varia$les later as this wold need
a dedicated section to discss" (aria$le data type for m$o attri$tes is driven $y
the m$o attri$te datatype" So for example a varia$le $ond to Archase /rder
m$os totalcost attri$te will inherit its type ie a do$le" (aria$les $ond to
maxvar and system properties are always of type String" (aria$les $ond to
literal vales can define their datatype explicitly $y setting :literaldatatype;
attri$te in the atoscriptvars ta$le" *he spported literal data types are 7 AL<&
)<*@5@+& SMALL)<*& D@?)MAL& =/+<& DA*@*)M@ and BL/A*" (aria$le
$indings can $e defined $oth at the script level and the launchpoint level 9
provided the definition at the script level allows override of that vale" More a$ot
this on the Launchpoints section"
/ne other important aspect of the /E* and )</E* varia$les is how their vales
can $e set $ack to the M$os" M$o attri$tes can $e set with the </A?*)/< flag
which determines if modifying the vale of the m$o attri$te will case the field
validations action rotine to $e called or not" M$o attri$tes can $e set with the
</(AL)DA*)/< flag which determines if modifying the vale of the m$o
attri$te will case the field validations validate rotine to $e called or not" M$o
atri$tes can $e set sing </A??@SS?8@?4 flags which determine if the
Action3(alidation rotine of the m$o attri$tes will get called or not" A m$o
attri$te can $e set with any com$ination of these flags" All these can $e done
from the script3lanch point creation wi%ards and maintenance application $y
selecting those [check$ox] options"
Implicit and Explicit Variables
Another important featre is the concept of Implicit and Explicit varia$les"
@xplicit varia$les are what we 6st read a$ot 7 the ones that yo define and
$ind in the varia$les page explicitly" )mplicit varia$les are the ones that yo do
not define in that page and are provided to yo $ehind the scenes $y the
framework" )mplicits follow the convention over configration pattern where the
framework will intelligently in6ect varia$les at rn9time which might otherwise
wold have needed 'A(A coding to fetch3set" Some of the implicits are in6ected
$ased on the explicit varia$les defined and some are in6ected irrespective of
them" Lets cover the ones that are in6ected irrespective of the explicit varia$les
first" *he list of them is as $elow with a little $lr$ descri$ing what they are for"
Name Type Description Applicability
app String <ame of the Maximo
application which initiated
the script exection"
All lanch points
ser String <ame of the ser whose
action initiated the script
exection"
All lanch points
m$o psdi"m$o"M$o *he crrent m$o in the
context of the script
exection" Bor example in
case of the /$6ect Lanch
Aoint this will $e the M$o
which is generating the
events on which the script
framework is listening on"
Bor attri$te lanch point
this is the attri$tes owner
m$o" Bor Action lanch point
this is say the @scalation or
workflows m$o"
All lanch points
m$oname String *he name of the crrent
m$o in the context of the
script exection"
All lanch points
errorkey String *his one is for throwing
MF@xceptions from the
script withot having to
explicitly import or refer to
that AA)" *his refers to the
error key in the
MF@xception" *his works
together with the errorgrop
and the params implicit
varia$les" Bor those not
familiar with the
All lanch points
Name Type Description Applicability
MF@xception api 7 its the
standard way to throw
@xceptions from Maximo
$ased components" *he
exception message is
translated which is the main
advantage of sing this api
as opposed to 6st raising a
standard 'ava @xception
which is not going to $e
translated"
errorgrop String )ts sage is the same as the
previos one ie the errorkey"
*his one points to the error
grop of the MF@xception"
*ogether with the errorkey it
helps niGely point to a
error message in Maximo
message repository"
All lanch points
params String[] *his is the params for the
MF@xception error
message" So if the
MF@xception $eing thrown
sing this mechanism is
parameteri%ed then this
params implicit varia$le
shold $e sed to set the
parameters"
All lanch points
interactive $oolean )ts a $oolean varia$le
indicating whether the script
is exected in an
interactive3E) session [vale
tre] or a $ackgrond
session [like say )ntegration]"
All lanch points
evalreslt $oolean *his is a $oolean varia$le of
type /E* to indicate the
reslt of the condition
evalation"
/nly ?ondition
Lanch point
onadd $oolean *his $oolean varia$le
indicates where the M$o in
the script is $eing added [ie
new M$o 7 vale tre] or
not" *he script developer
can se this to do
All Lanch
points" )deally
wold $e
vala$le for
/$6ect Lanch
Aoints where the
Name Type Description Applicability
conditional actions or
validations $ased on the
state of the M$o"
script is
applica$le for
mltiple event
types [Add&
Epdate& Delete
etc]
onpdate $oolean *his $oolean varia$le
indicates where the M$o in
the script is $eing pdated
[ie exiting M$o 7 vale tre]
or not" *he script developer
can se this to do
conditional actions or
validations $ased on the
state of the M$o"
Same as onadd
7 All Lanch
points"
ondelete $oolean Boolean varia$le indicating
whether the m$o in the
script context is getting
deleted [vale tre] or not"
Same as onadd
7 All Lanch
points"
action String *he name of the Action that
was generated from the
Action Lanch Aoint wi%ard"
Action Lanch
Aoint
script<ame String *he name of the Script thats
getting exected"
All Lanch points
lanchAoint String *he name of the lanch
point for which the script is
getting exected"
All Lanch points
script8ome psdi"m$o"M$o *his is the same as the
implict varia$le :m$o;
descri$ed earlier" *his
dplication is for $ackward
compati$ility"
Action Lanch
Aoint
wfinstance psdi"workflow"
WB)nstance
*he workflow instance m$o" Action Lanch
Aoint 7 only
when the Action
is lanched from
a workflow"
<ow lets talk a$ot those implicit varia$les that are in6ected into the script $ased
on the explicitly defined varia$les"
/ne thing to keep in mind 7 all these implicit varia$les that we descri$e $elow
are $ased on the explicitly defined varia$les whose $inding type is a M$o
attri$te" *here are no implicit varia$les for explicitly defined varia$les of other
$inding types like 7 Literals& Maxvars and System properties" Below is the list of
the implicit varia$les" Assme :var; is the explicitly defined varia$le that $inds to
a m$o attri$te"
Name Type Description Applicability
varHreGired Boolean +eGired flag of
the m$o attri$te
that var $inds to"
All lanch points"
*he script can
modify it provided
that var is of type
/E* or )</E*"
varHreadonly Boolean +eadonly flag of
the m$o attri$te
that var $inds to"
All lanch points"
*he script can
modify it provided
that var is of type
/E* or )</E*"
varHhidden Boolean 8idden flag of the
m$o attri$te that
var $inds to"
All lanch points"
*he script can
modify it provided
that var is of type
/E* or )</E*"
varHinternal Same type as the
m$o attri$te to
which var $inds to"
Bor synonym
domain kind of
m$o attri$tes [like
stats] this
represents the
internal [maxvale]
vale for the m$o
attri$te"
All lanch points"
Applica$le only if
var is $ond to a
m$o attri$te that
$inds to a
synonym domain"
*he script cannot
modify it"
varHprevios Same type as the
m$o attri$te to
which var $inds to"
*he previos vale
of the m$o
attri$te ie the
vale 6st $efore
the attri$te vale
got changed"
Attri$te lanch
points 7 applica$le
only for the
attri$te that
generated the
event" *he script
cannot modify it"
varHinitial Same type as the
m$o attri$te to
which var $inds to"
*he initial vale of
the m$o attri$te
ie the vale
assigned to that
attri$te when the
m$o was
initiali%ed"
All lanch points"
*he script cannot
modify it"
Name Type Description Applicability
varHmodified Boolean )ndicates whether
the m$o attri$te
to which the
varia$le var $inds
to has $een
modified or not"
All lanch points"
*he script cannot
modify it"
We will cover more a$ot them sing examples as part of lanch points section"
Array Variables
Lets talk a little $it a$ot the array varia$les as that wold introdce yo to the
concept of M$o +elationship Aath [M+A]"
*he M+A format is an extension of the crrent attri$te path notation" *he
crrent m$o attri$te path notation spports the dot :"; to allow traversing related
M$os and fetching attri$te vale from them" An example of the crrent format is
shown $elow [the examples are $ased of the A/ m$o]I
poline"pocost"costlinenm 7 which gives s the first A/L)<@Js [the relation name
is A/L)<@] 0
st
A/?/S*Js [the relation name is A/?/S*] colstlinenm attri$te"
/+
poline[i]"pocost[6]"costlinenm 9 which gives s the i th A/L)<@Js [the relation
name is A/L)<@] 6 th A/?/S*Js [the relation name is A/?/S*] colstlinenm
attri$te"
*he M+A notation $ilds p on this attri$te path notation" *he one fndamental
difference $eing that M+A leads to a List3Array of M$o attri$tes" Bor example if
we take the examples a$ove an M+A may look likeI
poline"pocost"costlinenmK 7 which give s a com$ined list or array of A/?/S*
m$os for all A/L)<@s"
poline[linecostL0MM]"pocost[percentageN0MM]"costlinenmK 7 which gives s all
costlinenmOs where the A/?/S* m$os has percentage N 0MM for all A/L)<@s
with linecostL0MM" *his is effectively filtering the relation clase [poline and
pocost] to sift only those m$os that satisfy the specific condition" *his can
generically $e represented $y I
poline[condition0]"pocost[condition,]"costlinenmK
where condition0 and condirion, can $e a Maximo condition or a raw SPL
where" As yo mst have already noticed 7 the K at the end of this notation
indicates arrays as opposed to 6st a scalar vale"
?onsider another variation of this as shown $elowI
poline[condition0]"pocost[i]"costlinenm
which implies costlinenm from all i th A/?/S* of every A/L)<@ that satisfies
condtion0"
We see that the content with the $race Q[Q and Q]J can $e overloaded in - different
ways"
0" )t can $e a nm$er signifying an array index"
," )t can $e a Maximo condition which can $e prefixed with the cond:
-" ?an $e a raw SPL where
<ow letJs take into consideration the different scenarios3context of this M+A
evalation" <ote these cases descri$ed $elow can $e mixed in a M+A as part of
the different relation tokens"
!" #ith no $ilter
*his is a M+A where none of the relation tokens has any associated filter" *his is
the simplest case where the M+A looks like +0"+,R where +0 and +, are
relation names and there is no associated filter clase with these relations" )n
this case the evalation wold involve 6st iterating over the content of +0 and
+, M$oSets and preparing a list of +, m$os"
!" #ith index $ilter:
*his is a M+A where one or more of the relation tokens has an associated index
filter" *his is the case where the M+A looks like +0[index0]"+[R]R" where a
relation token [one or more] has index filter SL for that M$oset identified $y the
relation +0 se the M$o at index :index0; for the M+A evalation" *his is an in9
memory filtering and does not impact the state of the M$oSet on which the index
filter is getting applied"
!" #ith condition $ilter:
*his is a M+A where one or more of the relation tokens has an associated filter
with a Maximo condition" *his is another example of in9memory filtering where
the M+A looks like +0[condIc0]"+,[R] where c0 is a name of a Maximo
condition and cond is the prefix indicating itJs a Maximo condition" *he
evalation is $ased on in memory filtering of the M$os in M$oSet +0 $ased on
the condition c0 and does not impact the state of the M$oSet on which the filter
is getting applied"
!" #ith a #here $ilter:
*his is a M+A where one or more of the relation tokens has an associated filter
with a where clase" *his amonts to appending an additional where clase to
the existing relation clase" *his definitely wold case the related M$oSet reset
to $e called and while it might work for certain cases it definitely wold reslt is
npredicta$le otpt for interactive ser sessions [ser $rowsing an app]" *he
implementation shold se temporary relations created dynamically to replace
each of the relations associated with sch a filter to evalate this M+A" So for
example if the M+A was +0[where]"+,"+-[where] the implementation shold
replace [transparently] +0 and +- with temporary relation names with the same
relation clase as their original conterparts" *his will work only if all the M$os
referred $y the M+A relation tokens were not toBeSaved12 SL their in memory
state represents their state at the persistent store"
/ne thing to note here is 7 its always recommended to 6st se the predefined
relationships as opposed to dynamically adding filters to the relationship 6st
keeping performance in mind" *he reason is 7 in case we need to access this
varia$le more than one times 7 the evalator will always create a temporary
relationship $etween the src and the target o$6ects" *his however will prevent the
sage of a cached relationship set from the origin m$os"
*he where clase approach will append the where clase condition" *he the
condition approach will filter the M$oSet in memory withot firing a sGl where
clase for the added filter" *his however will take more time to sift than sing the
SPL clase" *he conditions application can $e sed to define the filter confitions"
Launchpoint
Launchpoints are what we call the application cstomi%ation points"
Lanchpoints define which application artifact the ser wants to cstomi%e $y
attaching the script to that point" )n effect the script is exected [launched] in the
context of a lanchpoint" Bor example if the ser wants to cstomi%e the Asset
m$os initiali%ation rotine the key words Asset mbo T initiali%ation routine
defines that lanchpoint" Another example might $e that the ser wants to
cstomi%e the Asset m$oOs prchaseprice attri$teOs field validation rotine" 8ere
the key words that define the lanchpoint are 9 Asset mbo& purchaseprice
attribute and $ield validation routine& So in effect a lanchpoint is a
configration to identify what application point we are trying to cstomi%e" A
script can $e associated with 0 or more lanchpoint at the same time" Bor
example a generic site level validation script can $e associated with all site level
o$6ects in Maximo 7 where each association is defined as an individal
lanchpoint" A script can $e associated with lanchpoints of the one and only
one type" Bor example a script associated with the /$6ect lanch point cannot $e
associated again with another attri$te lanch point" /nce the first association is
done $etween a script and a lanch point 7 all s$seGent lanch points have to
$e of the same type as the first one"
<ow lets take a look at the lanchpoints [aka cstomi%ation points] toched p
$y the scripting framework" Below is the list of the points spported crrently"
0" M$o initiali%ation and save point logic [aka /$6ect lanchpoint]"
," M$o attri$te vale modification 7 validation and action logic [aka /$6ect
attri$te lanchpoint]"
-" Actions 7 which are sed $y a mltitde of other components like
Workflow& @scalation& E) Men& E) Bttons [aka Action lanchpoint]"
D" ?stom conditions 7 sed $y Workflow conditions& ?onditional E) etc
[aka cstom condition lanchpoint]"
Lanchpoints are what yo think of first when yo want to cstomi%e an
application" <o wonder all the wi%ards in the Script app starts with defining the
lanchpoint" <ext lets explore the individal point types to nderstand what they
$ring into the ta$le for cstomi%ers and deployers"
'b(ect Launch "oint
Birst in or list is the ob(ect launch point" *his lanchpoint lets yo invoke
scripts for the M$o events 7 init and save point ones [add& pdate and delete]" A
lanch point can $e configred to listen to one or more of these events at the
same time" *he script will have access to the event M$o [via implicit varia$le
:m$o;]as well as all the related M$os" *he initiali%ation event $ased scripts can
$e sed to set calclated fields& set fields as readonly3reGired3hidden or set
conditional defalts to m$o attri$tes" *he save point event $ased scripts can $e
sed to implement save point o$6ect validations as well as save point actions"
Below is an example that will demonstrate a initiali%ation point script and the next
one wold demonstrate a save point script"
So lets take the se case in mind $efore we 6mp into the code and
configration" Sppose we want to cstomi%e the Asset application to display the
total spare part Gantity in a new non9persistent Asset o$6ect attri$te called
sparepartGty" *his $oils down to the reGirement 9 whenever an Asset m$o gets
initiali%ed the sparepartGty will display the sm of all the spare part Gantities
associated with that asset" So $ased on or knowledge of lanch points we get
that it will $e a 'b(ect Launch "oint for the ob(ect Asset and we need to attach
the script to the initiali%ation event of the Asset o$6ect" *o do this we need to
lanch the :?reate Scripts with /$6ect Lanch Aoint; wi%ard as shown $elow"
/nce the wi%ard is lanched the first thing we do is to create a lanch point as
shown $elow" <ote that the :initiali%e; event is what we want to se for lanching
this script"
So now lets look at the varia$les we might need to do this cstomi%ation" Birst of
corse is a varia$le called sptGt which $inds to the new Asset m$o attri$te
sparepartGty" <ow we only intend to set the vale of this attri$te and hence this
varia$le wold $e of type /E*" <ext we need to get all the Gantities from the
related Sparepart M$os of the Asset" *o do that we se the array varia$le
notation K to get an array of Gantity vales from the related sparepart M$oSet"
Lets say the array varia$le is Gtys and its $ind vale wold $e Nasset to
sparepart relation nameL"Nattri$te nameLK which is sparepart"GantityK" *he K
at the end of9corse indicates the array natre of this varia$le and also instrcts
the framework to form the array sing the specified relationship"
And as mentioned earlier array varia$les are always of type )< and that is perfect
for this as we are not modifying the Gantities 7 we are merely smming that p"
So with these $asic varia$les defined we next wold attempt to write the script as
$elow
if Gtys is not <oneI
sptGt S sm1Gtys2
Basically a , liner which validates if there are infact sparepart M$oOs and if there
is then sm them p and set it to the sptGt varia$le" *he scripting framework
picks that p and sets the vale $ack to the $inding of the sptGt ie sparepartGty"
So the amont of 'ava coding done here is a B)5 U@+/ 7 its a pre 6yhton
script" <ow going $y the natre of the calclated fields 7 the sparepartGty shold
$e always read only" And what $est place to set that to read only other than this
script 7 which em$odies the Asset initiali%ation event" Below is the final script
which adds the code to set the sparepartGty attri$te to read only"
sptGtHreadonlyS*re
if Gtys is not <oneI
sptGt S sm1Gtys2
/nce yo press the create $tton in the last wi%ard step to create the script 7 a
sccessfl creation of the script and the lanch point will generate this response
as shown $elow"
)n case of a compilation error yo wold $e forced to stay $ack on the last page
till yo cancell or fix this script"
8ere yo see the magic of this implicit varia$le concept" When yo $ond sptGt
to sparepartGty attri$te the scripting framework in6ected at rntime not only the
varia$le sptGt $t also some implicit varia$les like sptGtHreadonly& sptGtHreGired
and sptGtHhidden each of which are of type $oolean and caters to the read only&
reGired and hidden flags of the M$o attri$te" Setting a m$o field to readonly
otherwise wold have reGired 6ava coding" A 6ava code to do this same
fnctionality wold look like $elow
m$o"setBieldBlag1:sparepartGty;& M$o?onstants"+@AD/<L=& tre2V
M$oSet+emote sparepartSet S m$o"getM$oSet1:sparepart;2V
int i S MV
M$o+emote sparepartM$o S sparepartSet"getM$o1i2V
do$le totalPty S MV
while1 sparepartM$o WS nll2
X
totalPty YS sparepartM$o"getDo$le1:Gantity;2V
sparepartM$o S sparepartSet"getM$o1YYi2V
Z
m$o"set(ale1:sparepartGty;& totalPty& M$o?onstants"</A??@SS?8@?42V
So $y this time yo mst have figred ot what amont of pain the scripting
framework has saved yoW" Dont 6st think in terms of the lines of code [which is
almost a 0I,] think also a$ot the api knowledge that yo wold need for this
simple task" And this code does not even address the pain that yo will go
throgh to attach this code to the Asset M$oOs initiali%ation rotine" *here yor
choices are even more hairy 7 either yo wold have to extend the Asset m$o
and override the init12 method of that m$o to pt yor code [in which case in the
the a$ove code 6st replace the m$o varia$le with :this; pointer] or yo wold
end p attaching yor code as a listener to the M$oOs event 7 which is a separate
api stack on its ownW" )n the scripting framwork all these are taken care for yo
the moment yo have pressed the :?reate; $tton to end yor wi%ard [ths
s$mitting yor script]" As a script developer yo 6st code the logic 7 the
framework takes care of the $ehind the scenes plm$ing work to manage and
execte yor script" So yes yo will save time and money with this for sre"
By the way the a$ove 6ava code wold work [provided yo do the 6ython syntax
styling on it 7 like removing the V and the crly $races and ""] even inside the
'ython script 7 that is 6st in case yo are an avid 6ava programmerW" 'st donOt
forget to import the following $efore yo s$mit the script 9
from psdi"m$o import M$o+emote
from psdi"m$o import M$o?onstants
from psdi"m$o import M$oSet+emote
which is 6ython way of importing external 6ava li$raries" *his shows that while
scripting framework gives tremendos power to script developers to get their
Maximo cstomi%ation done withot knowing Maximo apis 7 it does not take
away the 'ava coding power from the developers who are sed to that" So
effectively yo can invoke all the Maximo apis [for example make a We$ service
call to fetch some external data sing the )ntegration framework] from inside a
script as long as yo have imported them properly"
<ext lets move onto some save point validations which hopeflly will help
demonstrate more featres of this framework" As $efore lets deal with the se
case first" *he se case here is a need to cstomi%e the Asset m$o to enforce a
naming convention for assets [assetnm] $ased on their types [assettype]" *his
effectively $oils down to the reGirement that #henever #e are creating Assets
we have to follow a naming convention for the assetnm" *he key words here
are in $locks which help s identify the lanchpoint type and the event point in
that type" )ts an o$6ect lanchpoint for the Asset m$os add event" So we se the
/$6ect Lanch point wi%ard to create and deploy this cstom logic" *o start with
we need to figre ot the varia$les and their $indings" Brom the reGirement its
clear we need the , inpt vales from the assetnm and assettype" So there are
, )< varia$les called anm and atype which are $ond to those attri$tes
respectively" *hose are the only , varia$les that we need to do this task" Below
is the script code [in 'ython]
def set@rror1prefix2I
glo$al errorkey&errorgrop&params
errorkeySOinvalidassetprefixO
errorgropSOassetO
paramsS[prefix&assettype]
if atypeHinternalSSOBA?)L)*)@SO and not anm"startswith1OB*O2I
set@rror1OB*O2
elif atypeHinternalSSOBL@@*O and not anm"startswith1OBLO2I
set@rror1OBLO2
elif atypeHinternalSSO)*O and not anm"startswith1O)*O2I
set@rror1O)*O2
elif atypeHinternalSSOA+/DE?*)/<O and not anm"startswith1OA+O2I
set@rror1OA+O2
8ere we define a 6ython fnction called set@rror which is responsi$le for setting
the error flags" We see the se of the Nvaria$le nameLHinternal implicit varia$le
which is applica$le only for attri$tes which ses a synonymdomain" *he
Nvaria$le nameLHinternal provides the internal vale for that attri$te $ased on
its crrent external vale" So this script ses the internal vale of the assettype
attri$te to esta$lish the naming convention" Bor example Assets with assettype
[internal] vale BA?)L)*)@S shold have assetnm starting with :B*; etc"
*his same code in 6ava wold have reGired to know the Maximo api to find the
internal vale of the assettype sing the *ranslator api as $elow"
String domainId =
MXServer.getMXServer().getMaximoDD().getMboSetInfo("asset").getMboValue
Info(assettye!).getDomainId()"
String atyeInternal=
MXServer.getMXServer().getMaximoDD().get#ranslator().
toInternalString(domainId$mbo.getString(assettye!)$ mbo)"
*his is something even an avid Maximo developer wold find difficlt to
remem$er and se and we dont even want to go into the plm$ing work thats
needed to execte this code"
We also see how errors can $e thrown in this framework withot sing Maximo
apis" 'st set the errorgrop& errorkey and params [optional] to the configred
error message grop& key and the params array can $e derived from the script
varia$les" )n this case we have predefined the error grop asset and the error
key :invalidassetprefix; sing the Maximo data$ase configration application"
*he params as yo can make ot are derived at rn9time from the script"
/ne thing to note here is that this way of setting error flag to throw error is not
real9time ie when the script code is execting the exception wold $e thrown only
after the script code has completed exection" At the end of the script exection
the framework wold detect that an error flag is set and it will throw the
corresponding Maximo excpetion for that error grop3key com$ination" So yo
shold consider the fact that even after setting the error flags in the script 7 the
script exection will contine and yo shold have adeGate checks in yor
script code to $ypass that code if the error flag is set" 8opeflly this does not
give yo the wrong impression that yo cannot throw the raw MF@xception from
the script code 7 shown $elow is how yo do it"
from psdi"til import MFApplication@xception
""""
""""
if Nsome conditionLI
params S [prefix&assettype]
raise MFApplication@xception1OassetO&OinvalidassetprefixO& params2
As $efore the scripting framework takes care of all the plm$ing $ehind the
scenes" /nce yo are done s$mitting yor script sing the wi%ard yo can
come to the Asset app and try to save a test asset" =o shold see yor
validation rotine gets exected immediately" )o restart* )o rebuilding ear and
)o redeployment"
Attribute Launch "oint
<ext we cover the Attribute Launch "oint where one can cstomi%e the field
validation and actions sing the scripting framework" As $efore the script will
have access to the event M$o [via implicit varia$le :m$o;] as well as all the
related M$os" )n addition the modified attri$te wold also $e availa$le implicitly
as a varia$le inside the script" *he varia$le name wold $e the lower case vale
of the modified attri$te name" A cople of examples $elow wold help explain
this $etter"
As $efore we contine cstomi%ing the Asset M$o" *he se case this time is to
add cstom $siness logic $ased on the Asset purchase price [attri$te
prchaseprice in Asset] value" Bor example we want to set the vendor field
reGired or not reGired $ased on the prchaseprice attri$te vale and also to
calclate the replacement cost $ased on the prchase price" We also want to
make sre the prchase price does not exceed a maximm allowed vale"
Based on the se case we know that the logic has to in6ected at the modification
of the prchasprice attri$te vale 7 which implies it shold $e modeled as an
Attri$te Lanch Aoint" Below is a way to get to the wi%ard"
/nce we lanch the wi%ard or step 0 is to create the lanch point as shown $e
<ow lets look at the varia$les that we wold need for this task" We definitely
need the prchaseprice varia$le" Bt we donOt need to define that explicitly as
thatOs already availa$le implicitly inside the script as its the attri$te on which the
script is listening on" <ext we need the vendor attri$te to set it reGired or not
$ased on the prchaseprice vale" Say the varia$le for that is vend and its type
is /E*" *he only remaining one is the replacementcost and say we $ind that to
the varia$le named rc with type as /E*&
(aria$le name (aria$le type Binding
vend /E* vendor
rs /E* replacementcost
So now lets look at the script $elow which we enter in the next step of the wi%ard"
if prchaseprice L ,MMI
errorgrop S [something[
errorkeyS[else[
elseI
if prchaseprice LS 0MMI
vendHreGiredS*re
elseI
vendHreGiredSBalse
rc S prchaseprice3,
As we see the - varia$les prchaseprice& errorgrop and errorkey are implicit
varia$les which yo did not have to define" *he only ones that yo had to define
for this script explicitly are vend and rc" And if prchaseprice is L 0MM we set the
vendor as reGired $y setting implicit $oolean varia$le vendHreGired to tre and
false otherwise" As we discssed earlier 7 when a varia$le is $ond to a M$o
attri$te the framework always in6ects implict varia$les that represent the meta
data state of the attri$te 7 like [vendH]readonly& [vendH]reGired and
[vendH]hidden" Binally we calclate the replace cost $y setting the varia$le rc to
prchaseprice3, [$asically rc is a fnction of prchase price]" <ote careflly that
the whole logic is done inside the :elseI; $lock" A falty way to write the script
wold have $een as $elow"
if prchaseprice L ,MMI
errorgrop S [something[
errorkeyS[else[
if prchaseprice LS 0MMI
m$o"setBieldBlag1:vendor;&M$o?onstants"+@PE)+@D& tre2
elseI
m$o"setBieldBlag1:vendor;&M$o?onstants"+@PE)+@D& false2
m$o"set(ale1:replacementcost;&prchaseprice3,2
*his is sing the falty assmption that setting the errorgrop and errorflag will
case the script to stop exection and throw the error [like a real time throw
exception which retrns the control $ack to the caller]" As mentioned earlier this
is not how the error flags work" Enlike throwing an exception its not real time" )t
will throw the exception only after the script exection completes" So in this falty
code case the vendorOs reGired flag will $e affected and the replace cost vale
will $e modified and then the script will throw an exception which will not roll$ack
those changes" *his is $ecase we sed explicit m$o calls to set the vale and
the flag" 8ad we sed the varia$les this wold have still worked as the
framework checks for the error flag right after the script exection end and
$efore setting an /E* and )</E* varia$le vales $ack to the M$oOs" So the
code $elow wold have still worked thogh it wold not $e as reada$le as the
original"
if prchaseprice L ,MMI
errorgrop S [something[
errorkeyS[else[
if prchaseprice LS 0MMI
vendHreGiredS*re
elseI
vendHreGiredSBlase
rc S prchaseprice3,
<ow lets look at another example $efore we move on to the next lanch point
type" *he next se case wold $e to make the calclated field that we created
for the Asset sparepart total Gantity calclation more real9time" Bor example if
we change the Gantities of the related spareparts we shold see the calclated
field [sparepartGty] vale change real9time" Bor that we wold need to create an
script which will $e associated with the sparepart Gantity attri$te" *he explicit
varia$le $indings are shown $elow"
(aria$le name (aria$le type Binding
sptGt )</E* TownerT"sparepartGty
As apparent from the $inding the varia$le sptGt is $ond to the ownerOs [Asset
m$o] sparepartGty attri$te" We do have to set the sptGt varia$le with the <o
Access ?heck as its marked as readonly $y or original [/$6ect lanch point]
script at the initiali%ation of the Asset m$o" As explained $efore the varia$le
Gantity [the attri$te on which the script is listening to] wold $e implicitly
in6ected in the script as thatOs the attri$te on which the script is listening" *he
script will look as $elow"
sptGtSsptGtYGantity9GantityHprevios
8ere we see the se of the implicit varia$le GantityHprevios" *his represents
the vale of the Gantity attri$te prior to the modification ie the vale at the
initiali%ation of the sparepart M$o" And the varia$le Gantity of corse holds the
crrent modified vale of the Gantity attri$te"
So com$ination of this script along with the /$6ect Lanch point script can give
yo a complete calclated field logic implemented sing the scripting framework
with - lines of script and a few clicks in the Script Wi%ardW"
Action Launch point
We all know a$ot the Maximo Actions framework" )n case yo didnOt know 9
Maximo has a $ilt in li$rary of Actions which can $e invoked from Workflows&
@scalations and E) MenOs and E) Bttons and a slew of other components"
More often than less those $ilt in li$rary of Actions are not enogh and
implementers go ot and develop their own cstom Actions and of corse the
langage yo are forced to se is 'A(A" Scripting addresses this concern where
an Action can $e scripted with a scripting langage of yor choice [//*B 7
'ython and 'avaScript]" Lets see how we can se a scripted Action to do some
calclated meters for Assets"
As in $efore lets first stdy the reGirement which is to $e a$le to calclate an
Asset meter vale $ased on some other meters associated with that Asset" Bor
example lets say we want to calclate the vale of the A+@SSE+@ meter $ased
on the )<9A+@SSE+ and /9A+@SSE+ meter sch that the last reading of the
A+@SSE+@ meter is the smmation of the )< and /9A+@SSE+ meters
readings" And lets say we choose to do it in an offline fashion where as opposed
to a real time fashion [for which we wold have needed to se /$6ect Lanch
points to trap meter modification events]" *he simplest way to do offline actions
in a repeated fashion in Maximo is to se @scalations which are nothing $t cron
6o$s which execte a predefined Action in the context of a M$o" <ow instead of
writing the Action 6ava code we will script it p" Shown $elow are the steps to do
this"
Birst we define a relationship called assetmeterip [asset meter inpt pressre]
sing the DB9?onfig application which relates an Asset to the Asset meter
named )<9A+@SSE+" *he where clase is as $elow"
assetnmSIassetnm and siteidSIsiteid and meternameSO)<9A+@SSE+O
Similarly we define the other , relationships namely assetmeterop and
assetmeterp as $elow
assetnmSIassetnm and siteidSIsiteid and meternameSO/9A+@SSE+O
assetnmSIassetnm and siteidSIsiteid and meternameSOA+@SSE+@O
<ext we se the Action Lanch Aoint wi%ard to define the Action Lanch Aoint"
*hogh this wi%ard wold create the Action $ehind the scene 7 its the
responsi$ility of the implementer to attach that Action to the escalation& workflow
or the E) $tton3men" By defalt the lanch point name is sed as the name of
the Action& $t yo can modify the vale to sit yor naming convention" *he
lanch point name need not $e the same as the Action name" )n the first step of
the wi%ard yo wold see that the o$6ect name is optional& which is in9line with
the Maximo Action framework where an Action may or maynot $e associated
with a Maximo o$6ect" )n this case however we do want to specify the o$6ect as
Asset as the Action is specific to the Asset M$o" Since we are defining a new
script we will choose the :<ew Script; option"
*he next page is the $indings page where we are going to define the varia$les
that we intend to se for the script and their $indings" *o do this 6o$ all we need
is the last reading vale of the )<9A+@SSE+ and /9A+@SSE+ meters and set
the calclated vale to the new reading attri$te of the A+@SSE+@ meter" We
however do not want to set the vale if the calclated vale is the same as the
last reading vale of the A+@SSE+@ meter as that wold generate meter
reading history even thogh the reading never got modified" *o check this we
wold need the last reading vale of the A+@SSE+@ meter" So or varia$le
$indings will look like $elow
(aria$le name (aria$le type Binding
iplr )< assetmeterip"lastreading
olr )< assetmeterop"lastreading
plr )< assetmeterp"lastreading
pnr /E* assetmeterp"newreading
*he iplr [)<9A+@SSE+ meters last reading]& olr [/9A+@SSE+ meters last
reading] and plr [A+@SSE+@ meters last reading] are all of type )< as we 6st
need those vales to calclate the pnr [A+@SSE+@ meters last reading]" <ote
the pnr is of type /E* as we are going to set it $ack to the A+@SSE+@ meter
m$o"
<ext page is the script code and it will look as $elow"
ySfloat1iplr2Yfloat1olr2
if yWSfloat1plr2I
pnrSstr1y2
As yo notice here y is a local varia$le to the script"
As yo mst have figred ot 7 the if check in the ,
nd
line takes care of not
pdating the pnr vale if the calclated vale is the same as the plr [A+@SSE+@
meters last reading]" <ote this calclation was implemented as a mere addition
6st as an example" )n real implementations it can $e any complicated
mathematical calclation as needed for yor $siness case and only limited $y
the mathematical spport provided $y the scripting langage of yor choice"
<ow we are not done yet as we need to associate this Action to an @scalation"
/r next step is to create an escalation which will only apply to those Assets
which have all those - meters" We se the escalation condition to implement
that sifting fnctionality" *he SPL condition for the a$ove case will look like
$elow"
exists 1select assetnm from assetmeter where meternameSO)<9A+@SSE+O and
assetnmSasset"assetnm and siteidSasset"siteid2 and exists 1select assetnm from assetmeter
where meternameSO/9A+@SSE+O and assetnmSasset"assetnm and siteidSasset"siteid2 and
exists 1select assetnm from assetmeter where meternameSOA+@SSE+@O and
assetnmSasset"assetnm and siteidSasset"siteid2
<ext we select the Action for this escalation 7 the name of the Action is the same
as the lanch point name [nless yo had modified it in the step 0 of the wi%ard]"
After we activate the escalation or 6o$ is done 7 the escalation exectes the
scripted Action for all those Assets with the - meters and the modified Asset
meter readings are saved and committed $y the escalation framework"
An important thing to note here is if yo had chosen to not attach the Action to a
Maximo o$6ect 7 the step , of the wi%ard [varia$les and $indings] will not let yo
$ind a varia$le to a M$o attri$te" =o can however se the literal& system
property and maxvar varia$le $inding types" A se case for that might arise when
yo write a generic Action that say invokes a service [like a We$ service] which
is not specific to a M$o or yo intend to do the script code $ased on direct sage
of the M$o apis and hence will not need the m$o attri$te $indings"
Condition Launch "oints
We all know a$ot Maximo conditions which are [$ased on the 6avacc parser]
sed in Workflows& ?onditional Eis etc" /ne aspect of cstom conditions lets yo
write p a condition sing 'ava code in case the condition is complicated enogh
to $e encoded sing the 6avacc $ased condition grammar" *his lanch point lets
yo avoid that 'ava coding and ena$les yo to attach a scripted condition to
these Maximo components [Workflows3?onditional E)s]"
Lets take an example to nderstand it $etter" *he se case is to add a condition
to the workflow that wold change the stats of Asset from not ready to
operating if the Asset has spareparts Gantity total as greater than 0M and the
asset vendor is not nll"
As $efore we wold lanch the wi%ard for the condition lanch point from the
Atoscript application [List *a$ C drop down actions C ?reate C ?reate Script
with ?stom ?ondition Lanch Aoint] and like otherOs this is also a - step
process"
Step 0 is ofcorse defining the lanch point" As we can see this is an entirely
new script"
Step , will $e to define and $ind the varia$les" *his script will involve , varia$les
as listed $elow
(aria$le name (aria$le type Binding
vend )< vendor
Gtys )< sparepart"GantityK

Step - wold $e to define the script" *he script wold look like as $elow
if vend is not <one and Gtys is not <one and sm1Gtys2L0MI
evalresltStre
*his evalreslt as explained earlier is an implicit varia$le which carries the
$oolean reslt of the condition evalation" )ts predefined and is always there for
condition lanch points"
At the end of the wi%ard process when we s$mit the design 7 it wold create a
script with the logic as a$ove" Bt the work is not done yet as we now have to
attach the script to the actal condition which nfortnately is still a manal
process" *he steps are listed $elowI
0" create a condition node in the workflow designer"
," Set the title of the condition node to NscriptnameLINlanchpointnameL
where script name and the lanch point name wold point to the
scriptYlanch point pair 6st created"
-" Bring p the the condition node properties dialog [as shown $elow in the
screen shot] to set the condition type as cstom and set the cstom 'ava class
to com"i$m"tivoli"maximo"script"Script?stom?ondition which is the predefined
proxy for the scripted conditions"
D" Save and activate the workflow"
/ne thing to note here is the title field vale" *his vale is mapped to the
WB</D@ M$oOs title attri$te which has a limit of 0M characters" And as yo can
see that the title is holding a pointer to the script lanch point pair $y appending
the script name and the lanch point name with the :I; as separator" @ach of
script name and lanch point name can $e ,M characters [ot of the $ox setting]"
So we do have a length isse here and at this point there is not mch we can do
$t to keep the names of the script and lanch point limited to D characters at
maximm" Also if the script has one and only lanch point we can 6st omit the
lanch point name from the title and 6st do with the script name" )f all these
have made yo wonder why it was done this way as opposed to keeping an entry
in the WB</D@ ta$le for the script name and the lanch point name the answer
is pretty simple 7 we 6st did not want to modify any existing Maximo artifacts"
*he condition in the example was trivial and is meant to demonstrate the :how to
do cstom conditions sing scripting; aspect" As yo mst have figred ot 7 we
can harness all the powers of scripting in this lanch point and do all complicated
evalations needed to come ot with the $oolean reslt [evalreslt] for the
evalation"
Activating and +eactivating scripts
Scripts can $e activated or deactivated from the lanchpoint ta$ of the scripting
application" A script that is deactivated will not $e invoked $y Maximo" Bor
example if a Attri$te Lanch point is deactivated 7 the script for that lanchpoint
will not $e invoked when say the vale of that m$o attri$te changes" *his is a
very sefl tool for de$gging when yo rn into some tro$le with the
application $ehavior and want to take the script ot of the eGation temporarily
6st to test the vanilla application devoid of all the cstomi%ation" /ne thing to
note here is the atoscript stats attri$te vale has no significance as to how
the scripting framework will [or will not] invoke the script" So a script in the draft
state is treated the same as a script in :Active; state"
+ebugging Scripts
By defalt all script related logging is done via the atoscript logger" @very script
can $e configred at different log levels 7 D@BE5&)<B/&@++/+ etc" *he defalt
setp for any script is at @++/+ which can $e changed from management
application or at the time of creation [in the ,
nd
step of the wi%ard]"

)f we were to 6st de$g the script $elow
ySfloat1iplr2Yfloat1olr2
if yWSfloat1plr2I
pnrSstr1y2
We can pt some de$g statements like
print :iplrS;Yiplr
print :olrS;Yolr
ySfloat1iplr2Yfloat1olr2
print :yS;Yy
if yWSfloat1plr2I
pnrSstr1y2
print :pnrS;Ypnr
<ext we need to make sre that the log level for the atoscript logger is set to
the log level of the script" Bor example set $oth of them to )<B/"
*his will reslt in the print statements to show p in yor systemot log" )f
reGired& the log statements prodced $y this logger can $e re9directed to a
dedicated log file holding only script9related log statements" <ote that the syntax
of the print statement depends pon which langage the script is $eing written
with" Also if the OatoscriptO logger is set to @++/+ level logs only& then the print
statements inside the atomation script will not $e written ot to log file"
*he scripting framework logs cover script loading& initiali%ation& exection time
and so forth" *o see the vales $eing passed received $y script varia$les& set the
atoscript logger to OD@BE5O& apply the logging settings and rn the script
configration" (aria$le vales shold $e otpt to the log file or system console"
As a general rle of thm$ we can set the atoscript logger to )<B/ dring script
development3de$gging time and set inidvidal scripts log level to )<B/ too
which will psh the script specific print statements to the log file"
Below is the list of log information atomatically generated at the D@BE5 level
from the scripting framework"
0" Lanch point name and script name that are a$ot to $e exected
," Script exection time 1as time elapsed $etween start and end of script
exection2
-" Application name& logged in se name& MB/ name& MB/ niGe )D
vales always in6ected as implicit data to the script 9 script athor may or may not
se these
D" (aria$le vales passed into the script $ased on varia$le $indings
1varia$les that are sorced from MB/ attri$te& MAF(A+& system property or
literal2
*o redirect yor scripting logs to a separate log file follow the steps $elow"
0" 5o to Logging app"
," ?lick Manage Appenders from the Select Action men"
-" ?lick <ew +ow in the Manage Appenders popp dialog"
D" Bill in Details asI
Appender S Scripting/nly [or any appropriate name yo choose]
Appender )mplementation ?lass S psdi"til"logging"MFBileAppender [yo
can select this from the vale list]
Bile <ame S atoscript"log [or any appropriate file name yo choose]
Accept all other defalts"
#" Save the new appender $y clicking /4"
." Locate OatoscriptO logger in the +oot Loggers section of the application"
!" ?lick the Manage Appenders icon to the right of Appenders field in the
Details section for OatoscriptO logger"
\" Select only the appender yo created earlier 1Scripting/nly2& and de9select
any other appender previosly associated with this logger"
]" ?lick /4 to save the new association" Brom the Select Action men click
OApplyO for the log settings to take effect"

Potrebbero piacerti anche