This chapter provides an introduction to the EDQ autorun functionality, which allows EDQ to load projects and run jobs when the application server starts up. It explains how the autorun functionality is configured, introduces the chore types that can be performed by using the autorun facility and provides examples of autorun scripts.
This chapter includes the following sections:
EDQ can be configured to do the following automatically at startup:
Perform a range of tasks when the application server starts up. Each task, which is composed of chores, can be configured to be performed every time the application server is started, or just once the next time the application server is started.
Load and apply purge rules that override the purge settings that are stored in the EDQ server.
To use autorun processing, you place autorun scripts, written in XML, that specify tasks in one of two specific directories in the EDQ installation:
startup
directory: Scripts in the startup
directory are processed every time the EDQ application server starts up.
onceonly
directory: Scripts in the onceonly
directory are processed when the EDQ application server next starts up, and are then moved to the complete
subdirectory within onceonly
. Scripts in the complete
directory are not processed on subsequent start ups.
When the application server starts up, EDQ checks the onceonly
and startup
directories for autorun scripts and processes any that are present.
The startup
and onceonly
directories are located in the EDQ autorun
directory in the local configuration directory of the application server, oedq.local.home
.
Various kinds of autorun chores are available in EDQ, each with a set of XML attributes specific to its function. The chore types and their available attributes are defined by the autorun file XML schema, see Section 1.4, "Understanding the Chore and Rules Schemas" The chores available are listed in the following table:
Chore Type | What the Chore Does |
---|---|
httpget |
Downloads files from a web server. |
package |
Loads a project from a .dxi file into the server, or saves a project on the server into a .dxi file. If no nodes are specified then the contents of the whole file, including system level components, are loaded into the server. |
load |
Loads a file, for example a purge rules configuration file. This chore is valid only in the startup directory. See Example 1-0 for how to use the load chore with the Rules schema to load purge rules. |
runjob |
Runs an existing job from Director. Any run labels in a run profile specified in this chore are ignored. (Use runopsjob to run a job based on a run label.) |
runopsjob |
Runs an existing job from the EDQ Server Console and requires a run label to be set, either in the run profile or with the runlabel attribute. |
dbscript |
Runs a database script against the Director database. This kind of chore must only be used with extreme care, as inappropriately applied scripts may corrupt the underlying database. |
sleep |
Waits for a specified interval before proceeding. |
Autorun scripts are files that contain XML code. The main part of an autorun script consists of a list of chores, each bounded by <chores>
tags. Each chore is of one of the autorun chore types listed in Section 1.2, "Using the Autorun Chores" and includes a set of attributes that specify the chore to be performed. The attributes available depend on the chore type selected.
The XML schema that is used to structure autorun scripts is shown in full in Section 1.4, "Understanding the Chore and Rules Schemas"
This section shows some examples of autorun scripts.
The following XML code shows a sample autorun script that instructs EDQ to:
Download the 23People.dxi
file, overwriting any existing file with the same name.
Import the 23People
project from the 23People.dxi
file, overwriting any existing project with the same name.
Run the 23People Excel.23People
job with the rp1
run profile. Any run label specified in the profile will be ignored, because this is not a runopsjob
chore.
<?xml version="1.0" encoding="UTF-8"?> <chores version="1"> <!-- Get the dxi file --> <httpget overwrite="true" todir="dxiland" tofile="23People.dxi"> <url>http://svn/repos/dev/trunk/benchmark/ benchmark/dxis/23People.dxi</url> </httpget> <!-- Import the project from the dxi --> <package direction="in" dir="dxiland" file="23People.dxi" overwrite="true"> <node type="project" name="23People"/> </package> <!-- Run the jobs --> <runjob project="23People" job="23People Excel.23People" runprofile="rp1" waitforcompletion="true"/> </chores>
The following XML code shows a sample autorun script that shows four different ways to use a runjob
or runopsjob
chore to run a job.
<?xml version="1.0" encoding="UTF-8"?> <chores version="1"> <!-- runs a director job with no runlabel --> <runjob project="merge" job="tester" waitforlocks="false" waitforcompletion="false" runprofile="x"/> <!-- runs an ops job with the runlabel from the runprofile --> <runopsjob project="merge" job="tester" waitforlocks="false" waitforcompletion="false" runprofile="x" /> <!-- runs an ops job with the runlabel from the runlabel attribute--> <runopsjob project="merge" job="tester" waitforlocks="false" waitforcompletion="false" runprofile="x" runlabel="chooseme" /> <!-- runs an ops job with the runlabel from the runlabel attribute--> <runopsjob project="merge" job="tester" waitforlocks="false" waitforcompletion="false" runlabel="onlychoice" /> </chores>
The following XML code shows how to use a load chore to load purge rules.
<?xml version="1.0" encoding="UTF-8" ?> <chores version="1"> <load file="purgerules.xml" dir="autorun" type="purgeRules" /> </chores>
The following are the purge rules in the purgerules.xml
file that is loaded in the chore specification:
<?xml version="1.0" encoding="UTF-8" ?> - <rules> - <rule displayName="testa" enabled="true"> <purgePeriod period="1" unit="HOURS" /> <project>aa</project> <job>12345</job> <runlabelMatcher regex="false" runlabel="ABCD" /> </rule> - <rule displayName="testb" enabled="true"> <purgePeriod period="1" unit="HOURS" /> <project>aa</project> <job>ABCD</job> <runlabelMatcher regex="true" runlabel="^\d{5}$" /> </rule> - <rule displayName="testc" enabled="true"> <purgePeriod period="2" unit="HOURS" /> <project /> <job /> <runlabelMatcher regex="true" runlabel="TEST" /> </rule> - <rule displayName="testd" enabled="true"> <purgePeriod period="3" unit="WEEKS" /> <project /> <job /> <runlabelMatcher regex="true" runlabel="TEST" /> </rule> - <rule displayName="teste" enabled="false"> <purgePeriod period="999" unit="MONTHS" /> <project /> <job /> <runlabelMatcher regex="true" runlabel="^\d{5}$" /> </rule> - <rule displayName="testf" enabled="true"> <purgePeriod period="1" unit="HOURS" /> <project /> <job /> <runlabelMatcher regex="true" runlabel="^\d{5}$" /> </rule> - <rule displayName="testg" enabled="true"> <purgePeriod period="1" unit="DAYS" /> <project /> <job /> <runlabelMatcher regex="false" runlabel="ABCD" /> </rule> </rules>
This section shows the Chores and Rules XML schemas.
This schema explains the chores listed in Section 1.2.
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- Chores --> <xs:element name="chores"> <xs:complexType> <!-- List of chores that need to be performed. The chores will be performed in the order specified in the xml file --> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="httpget" type="httpgetType"/> <xs:element name="package" type="packageType"/> <xs:element name="runjob" type="runjobType"/> <xs:element name="runopsjob" type="runopsjobType"/> <xs:element name="dumpdb" type="dumpdbType"/> <xs:element name="dbscript" type="dbScriptType"/> <xs:element name="sleep" type="sleepType"/> <xs:element name="load" type="loadType"/> </xs:choice> <!-- Schema version number --> <xs:attribute name="version" type="xs:positiveInteger" use="required"/> </xs:complexType> </xs:element> <!-- Base type for chores --> <xs:complexType name="choreType"> <!-- Flag indicating whether we should wait for completion before moving on to the next chore. --> <xs:attribute name="waitforcompletion" type="xs:boolean" use="optional" default="true"/> </xs:complexType> <!-- HTTP Get chore. Download the specified urls. --> <xs:complexType name="httpgetType"> <xs:complexContent> <xs:extension base="choreType"> <xs:sequence minOccurs="1" maxOccurs="1"> <!-- URL to download. --> <xs:element name="url" type="xs:string"/> </xs:sequence> <!-- Filename to download to. --> <xs:attribute name="tofile" type="xs:string" use="required"/> <!-- Directory to download the files to. - relative path is relative to the config dir - absolute path is used as is - no path indicates the config dir --> <xs:attribute name="todir" type="xs:string" use="optional"/> <!-- If true existing files are overwritten, otherwise download is not performed. --> <xs:attribute name="overwrite" type="xs:boolean" use="optional" default="true"/> </xs:extension> </xs:complexContent> </xs:complexType> <!-- dxi file control chore. Import or export to/from a dxi file. --> <xs:complexType name="packageType"> <xs:complexContent> <xs:extension base="choreType"> <!-- List of root level nodes to import/export. An empty list indicates 'all'. --> <xs:sequence minOccurs="0" maxOccurs="unbounded"> <xs:element name="node" type="packageNodeType"/> </xs:sequence> <!-- dxi filename. --> <xs:attribute name="file" type="xs:string" use="required"/> <!-- Directory that the dxi is in. - relative path is relative to the config dir - absolute path is used as is - no path indicates the config dir --> <xs:attribute name="dir" type="xs:string" use="optional"/> <!-- If true existing files/nodes are overwritten, otherwise no operation. --> <xs:attribute name="overwrite" type="xs:boolean" use="optional" default="true"/> <!-- Direction: in=import out=export --> <xs:attribute name="direction" type="packageDirectionEnum" use="required"/> </xs:extension> </xs:complexContent> </xs:complexType> <!-- Package node for import or export from/to a dxi. --> <xs:complexType name="packageNodeType"> <!-- the type of the node to process --> <xs:attribute name="type" type="nodeTypeEnum" use="required"/> <!-- the name of the node to process --> <xs:attribute name="name" type="xs:string" use="required"/> </xs:complexType> <!-- db script control chore. Runs db script against the configuration database. --> <xs:complexType name="dbScriptType"> <xs:complexContent> <xs:extension base="choreType"> <!-- db script filename. --> <xs:attribute name="file" type="xs:string" use="required"/> <!-- Directory that the db script is in. - relative path is relative to the config dir - absolute path is used as is - no path indicates the config dir --> <xs:attribute name="dir" type="xs:string" use="optional"/> <!-- The database to run the script against --> <xs:attribute name="database" type="databaseEnum" use="required"/> </xs:extension> </xs:complexContent> </xs:complexType> <!-- Invoke named job chore. Run a named job --> <xs:complexType name="runjobType"> <xs:complexContent> <xs:extension base="choreType"> <!-- Project name --> <xs:attribute name="project" type="xs:string" use="required"/> <!-- Job name --> <xs:attribute name="job" type="xs:string" use="required"/> <!-- Wait for locks flag - default to true --> <xs:attribute name="waitforlocks" type="xs:boolean" use="optional" default="true"/> <!-- Optional run profile --> <xs:attribute name="runprofile" type="xs:string" use="optional"/> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="runopsjobType"> <xs:complexContent> <xs:extension base="runjobType"> <!-- Optional run label (will override run profile run label if set) --> <xs:attribute name="runlabel" type="xs:string" use="optional"/> </xs:extension> </xs:complexContent> </xs:complexType> <!-- Dump the database. --> <xs:complexType name="dumpdbType"> <xs:complexContent> <xs:extension base="choreType"> <!-- Output JMP file for config database --> <xs:attribute name="configout" type="xs:string" use="required"/> <!-- Output JMP file for results database --> <xs:attribute name="resultsout" type="xs:string" use="required"/> <!-- Directory that the JMP files are written to - relative path is relative to the config dir - absolute path is used as is - no path indicates the config dir --> <xs:attribute name="dir" type="xs:string" use="optional"/> <!-- TODO: Add some filtering to allow dumping of categories of data e.g. staged data, results data, case management data, etc. --> </xs:extension> </xs:complexContent> </xs:complexType> <!-- Load a certain file to do a certain thing. Eg change purge rules. --> <xs:complexType name="loadType"> <xs:complexContent> <xs:extension base="choreType"> <!-- type of action to run with file --> <xs:attribute name="type" type="loadTypeEnum" use="required"/> <!-- filename --> <xs:attribute name="file" type="xs:string" use="required"/> <!-- Directory that the file is in. - relative path is relative to the config dir - absolute path is used as is - no path indicates the config dir --> <xs:attribute name="dir" type="xs:string" use="optional"/> </xs:extension> </xs:complexContent> </xs:complexType> <!-- Enumeration of databases --> <xs:simpleType name="databaseEnum"> <xs:restriction base="xs:string"> <xs:enumeration value="director"/> <xs:enumeration value="results"/> </xs:restriction> </xs:simpleType> <!-- Enumeration of valid node types --> <xs:simpleType name="nodeTypeEnum"> <xs:restriction base="xs:string"> <xs:enumeration value="project"/> <!-- Probably need to do these sometime <xs:enumeration value="resource"/> <xs:enumeration value="datastore"/> --> </xs:restriction> </xs:simpleType> <!-- Enumeration of packaging direction. --> <xs:simpleType name="packageDirectionEnum"> <xs:restriction base="xs:string"> <xs:enumeration value="in"/> <xs:enumeration value="out"/> </xs:restriction> </xs:simpleType> <!-- Enumeration of types of things that can be loaded. --> <xs:simpleType name="loadTypeEnum"> <xs:restriction base="xs:string"> <xs:enumeration value="purgeRules"/> <!-- <xs:enumeration value="schedule"/> --> </xs:restriction> </xs:simpleType> <!-- Sleep chore. Wait for a while before doing other autorun stuff --> <xs:complexType name="sleepType"> <xs:complexContent> <xs:extension base="choreType"> <!-- seconds to wait. --> <xs:attribute name="time" type="xs:integer" use="required"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:schema>
This section describes the Rules schema, which provides the basis for structuring an XML script that specifies EDQ server purge rules. Use the load
chore to load the script at EDQ startup.
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- Common types --> <!-- ============ --> <xs:include schemaLocation="urn:commontypes.xsd"/> <xs:element name="rules" type="rulesType"> <!-- Rule name must be unique --> <xs:key name="rule.name"> <xs:selector xpath="rules/rule"/> <xs:field xpath="@name"/> </xs:key> </xs:element> <!-- Rules --> <xs:complexType name="rulesType"> <xs:sequence> <xs:element name="rule" type="ruleType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="schemaversion" type="xs:positiveInteger" use="optional" default="1"/> </xs:complexType> <xs:complexType name="ruleType"> <xs:sequence> <xs:element name="purgePeriod" type="periodType" minOccurs="1" maxOccurs="1"/> <xs:element name="project" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="job" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="runlabelMatcher" type="runlabelType" minOccurs="0" maxOccurs="1"/> </xs:sequence> <!-- name --> <xs:attribute name="displayName" type="xs:string" use="required"/> <!-- whether this rule should be applied --> <xs:attribute name="enabled" type="xs:boolean" use="required"/> </xs:complexType> <!-- Runlabel --> <xs:complexType name="runlabelType"> <xs:attribute name="regex" type="xs:boolean" use="required"/> <xs:attribute name="runlabel" type="xs:string" use="required"/> </xs:complexType> <!-- Purge Period --> <xs:complexType name="periodType"> <xs:attribute name="period" type="xs:int" use="optional"/> <xs:attribute name="unit" type="periodUnitType" use="required"/> </xs:complexType> <!-- Purge Unit types --> <xs:simpleType name="periodUnitType"> <xs:restriction base="xs:string"> <xs:enumeration value="IMMEDIATE"/> <xs:enumeration value="HOURS"/> <xs:enumeration value="DAYS"/> <xs:enumeration value="WEEKS"/> <xs:enumeration value="MONTHS"/> <xs:enumeration value="NEVER"/> </xs:restriction> </xs:simpleType> </xs:schema>