1 Using Autorun to Execute Startup Tasks
This chapter includes the following sections:
1.1 Understanding Autorun
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 thestartup
directory are processed every time the EDQ application server starts up. -
onceonly
directory: Scripts in theonceonly
directory are processed when the EDQ application server next starts up, and are then moved to thecomplete
subdirectory withinonceonly
. Scripts in thecomplete
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
.
1.2 Using the Autorun Chores
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 Understanding the Chore and Rules Schemas. The chores available are listed in the following table:
Chore Type | What the Chore Does |
---|---|
|
Downloads files from a web server. |
|
Loads a project from a |
|
Loads a file, for example a purge rules configuration file. This chore is valid only in the |
|
(EDQ 14.1.2 and later) Imports a package file that is created using the packaging export REST API. The chore XML includes the package import definition, as inline JSON or as a file name. JSON is assumed if the contents of the manifest element starts with "{" after the leading and trailing whitespace is removed. File names that are not absolute are located relative to the EDQ local configuration directory. See the Examples section, to know how to use the |
|
Runs an existing job from Director. Any run labels in a run profile specified in this chore are ignored. (Use |
|
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 |
|
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. |
|
Waits for a specified interval before proceeding. |
1.3 Using the Autorun Scripts
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 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 Understanding the Chore and Rules Schemas.
1.3.1 Examples
This section shows some examples of autorun scripts.
- Example 1
-
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 the23People.dxi
file, overwriting any existing project with the same name. -
Run the
23People Excel.23People
job with therp1
run profile. Any run label specified in the profile will be ignored, because this is not arunopsjob
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>
-
- Example 2
-
The following XML code shows a sample autorun script that shows four different ways to use a
runjob
orrunopsjob
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>
- Example 3
-
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>
- Example 4
-
The following XML code shows a sample autorun script that shows import definition provided using absolute file name to import a package file.
<?xml version="1.0" encoding="UTF-8"?> <chores version="1"> <import> <manifest>/opt/pkg/pkg2.json</manifest> </import> </chores>
- Example 5
-
The following XML code shows a sample autorun script that shows import definition provided as inline JSON to import a package file.
<?xml version="1.0" encoding="UTF-8"?> <chores version="1"> <import> <manifest> { "label": "Import project imptest", "password": "pass2", "destination": { "location": "/opt/stuff/testdata/imptest.zip" }, "projects": { "include": ["imptest"] } } </manifest> </import> </chores>
- Example 6
-
The following XML code shows a sample autorun script that shows import definition provided using the relative file name to import a package file.
<?xml version="1.0" encoding="UTF-8"?> <chores version="1"> <import> <manifest>imports/pkg2.json</manifest> </import> </chores>
1.4 Understanding the Chore and Rules Schemas
This section shows the Chores and Rules XML schemas.
1.4.1 Understanding the Chores Schema
This schema explains the chores listed in Using the Autorun Chores.
<?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>
1.4.2 Understanding the Rules 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>