Scheduled Actions

Document created by resplin Employee on Jun 6, 2015
Version 1Show Document
  • View in full screen mode

Obsolete Pages{{Obsolete}}

The official documentation is at: http://docs.alfresco.com



Content ModelingActionsScheduled Processes


Introduction to Scheduled Actions


A scheduled action is made up of three parts:


  • a cron expression;
  • a query template; and
  • an action template.



At the times specified by the cron expression, the query template is used to generate a query. Any supported query language can be used. The query is run to select a set of nodes. For each of the nodes in the set, the action template is converted into an action and then the action is applied to the node.



The use of query templates allows the query to generate entries for dates and date ranges such as 'today' and 'the last four years'. The use of templates for actions allows properties of each node found by the query to be used to parameterise the action instance. The parameters defined in the action template can be defined as FreeMarker templates. When the action is built from the action template its parameters are generated from the FreeMarker templates  using a template model with the current node defined. So you can use properties of the node to set the properties on the action.



Currently definitions of scheduled actions are made in XML.



The action templates can be composite action templates or single actions.



Currently an action applies to a single node (it can not take the whole set of selected nodes)



The query can be something like:


  • has aspect;
  • does not have aspect;
  • was created in the last month;
  • is due in the next month;
  • is in category;

...



And the action any one of the built in:


  • AddFeaturesAction
  • CheckInAction
  • CheckOutAction
  • CompositeAction
  • ContentMetadata
  • CopyAction
  • CounterIncrementAction
  • CreateVersionAction
  • ExecuteAllRulesAction
  • ExporterAction
  • ImageTransformAction
  • ImporterAction
  • LinkCategoryAction
  • MailAction
  • MoveAction
  • RemoveFeaturesAction
  • RepositoryExporterAction
  • ScriptAction
  • SetPropertyValueAction
  • SimpleWorkflowAction
  • SpecialiseTypeAction
  • TransformAction




A simple Example


This example finds files without the general classifiable aspect and adds it with a default classification.



The examples shown all refer to a bean templateActionModelFactory but do not define it. The docs here show that the only known implementing class of TemplateActionModelFactory interface is FreeMarkerWithLuceneExtensionsModelFactory and the example scheduled-action-services-context.xml.sample defines the bean as such:

   <bean id='templateActionModelFactory' class='org.alfresco.repo.action.scheduled.FreeMarkerWithLuceneExtensionsModelFactory'>
       <property name='serviceRegistry'>
           <ref bean='ServiceRegistry'/>
       </property>
   </bean>

You should define this bean within your override, perhaps at alfresco/extension/scheduled-action-services-context.xml


The Action definition




    <bean id='addClassifiableAspectAction' class='org.alfresco.repo.action.scheduled.SimpleTemplateActionDefinition'>



        <property name='actionName'>
            <value>add-features</value>
        </property>
        <property name='parameterTemplates'>
            <map>


                <entry>
                    <key>

                        <value>aspect-name</value>
                    </key>
                    <value>{http://www.alfresco.org/model/content/1.0}generalclassifiable</value>
                </entry>
               
                <entry>
                    <key>
                        <value>{http://www.alfresco.org/model/content/1.0}categories</value>
                    </key>



                    <value>\$\{selectSingleNode('workspace://SpacesStore', 'lucene', 'PATH:'/cm:generalclassifiable/cm:Languages/cm:English'' )\}</value>
                </entry>
            </map>
        </property>
        <property name='templateActionModelFactory'>
            <ref bean='templateActionModelFactory'/>
        </property>
        <property name='dictionaryService'>
            <ref bean='DictionaryService'/>
        </property>
        <property name='actionService'>
            <ref bean='ActionService'/>
        </property>
        <property name='templateService'>
            <ref bean='TemplateService'/>
        </property>
    </bean>

The query and scheduler definition



    <bean id='addClassifiableAspectEveryTenMinutes' class='org.alfresco.repo.action.scheduled.CronScheduledQueryBasedTemplateActionDefinition'>
        <property name='transactionMode'>
            <value>UNTIL_FIRST_FAILURE</value>
        </property>
        <property name='compensatingActionMode'>
            <value>IGNORE</value>
        </property>
        <property name='searchService'>
            <ref bean='SearchService'/>
        </property>
        <property name='templateService'>
            <ref bean='TemplateService'/>
        </property>
        <property name='queryLanguage'>
            <value>lucene</value>
        </property>
        <property name='stores'>
            <list>
                <value>workspace://SpacesStore</value>
            </list>
        </property>
        <property name='queryTemplate'>
            <value>PATH:'//\*' -ASPECT:'{http://www.alfresco.org/model/content/1.0}generalclassifiable'</value>
        </property>
        <property name='cronExpression'>
            <value>0 50 * * * ?</value>
        </property>
        <property name='jobName'>
            <value>jobA</value>
        </property>
        <property name='jobGroup'>
            <value>jobGroup</value>
        </property>
        <property name='triggerName'>
            <value>triggerA</value>
        </property>
        <property name='triggerGroup'>
            <value>triggerGroup</value>
        </property>
        <property name='scheduler'>
            <ref bean='schedulerFactory'/>
        </property>
        <property name='actionService'>
            <ref bean='ActionService'/>
        </property>
        <property name='templateActionModelFactory'>
            <ref bean='templateActionModelFactory'/>
        </property>
        <property name='templateActionDefinition'>
            <ref bean='addClassifiableAspectAction'/>
        </property>
        <property name='transactionService'>
            <ref bean='TransactionService'/>
        </property>
        <property name='runAsUser'>
            <value>System</value>
        </property>
    </bean>

Available options for SimpleTemplateActionDefinition


actionName
the name of the action (the bean name for the implementation)

parameterTemplates
a map of names and valueTemplates
these are action specific

compensatingTemplateActionDefinition
an optional compensating action (simple or composite)

Available options for CompositeTemplateActionDefinition


compensatingTemplateActionDefinition
an optional compensating action template (simple or composite)

templateActionDefinitions
A list of other template definition beans (simple or composite)





Those properties not mentioned explicitly are required services and should be set as the above example.


Available properties for a CronScheduledQueryBasedTemplateActionDefinition bean


transactionMode
ISOLATED_TRANSACTIONS - for each node the action is run in an isolated transaction. Failures are logged.
UNTIL_FIRST_FAILURE - for each node the action is run in a isolated transacgtion. The first failure stops this.
ONE_TRANSACTION- the actions for all nodes are run in one transaction. One failure will roll back all;

compensatingActionMode
RUN_COMPENSATING_ACTIONS_ON_FAILURE
IGNORE

queryLanguage
The query language to use

stores
A list of stores to query (currently only one store is supported)

queryTemplate
The template string to build the query

cronExpression
The cron expression to define when the query runs

jobName
The name of the scheduled job

jobGroup
The group for the scheduled job

triggerName
The name for the trigger

triggerGroup
The group for the trigger

runAsUser
The user which who identity the action will run

templateActionDefinition
The bean that defines the action



Those properties not mentioned explicitly are required services and should be set as the above example.


Query Templates


The FreeMarker template is extended with some support to build Lucene query strings.
This is mostly around dates.














Template expression Meaning
${luceneDateRange(\'2000-01-01T00:00:00.000Z\', \'P4D\')} [2000-01-01T00:00:00.000Z TO 2000-01-05T00:00:00.000Z]
${luceneDateRange(today, \'P4D\')}' a range of the form [X TO Y] where X is today and Y is Today + 4 days
${luceneDateRange(today, \'-P4D\')} a range of the form [X TO Y] where X is today and Y is Today - 4 days
${luceneDateRange(today, today)} a range of the form [X TO Y] where X is today and Y is today



Date ranges are expressed as XML durations.

Note that as of Alfresco 4.0, due to a Spring upgrade, the FreeMarker ${foo} entries must be escaped in the Context XML. A
FreeMarker expression such as ${today} much be written in the XML as \$\{today\}


Examples


PATH:'//\*' -ASPECT:'{http://www.alfresco.org/model/content/1.0}generalclassifiable'

Find all nodes that do not have the general classifiable aspect




ASPECT:'{http://www.alfresco.org/model/content/1.0}generalclassifiable'

Find all nodes that do have the general classifiable aspect




+PATH:'/app:company_home/*//*' +TEXT:'tutorial'

Find all nodes under company home that also contain tutorial in the content.




@cm\:created:\$\{luceneDateRange(yesterday, '-P10Y')\}

Find all nodes created yesterday or in the 10 years before




Cron Explained


A cron expression is 6 or 7 text fields that are separated by whitespace.




















Cron Fields
Field Name Position Mandatory Allowed Values Special Characters
Seconds
1 Yes 0-59             , - * /
Minutes
2 Yes 0-59             , - * /
Hours
3 Yes 1-23             , - * /
Day of Month
4 Yes 1-31             , - * ? / L W C
Month
5 Yes 1-12 or JAN-DEC  , - * /
Day of Week
6 Yes 1-7 or SUN-SAT   , - * ? / L C #
Year
7 No  empty, 1970-2099 , - * /




Special characters


*
All values
This matches all available values for this field. In the second field, it means 'every second'; in the minutes fields, 'every minute'; in the hours field 'every hour'; etc.

 ?
No specific value
A value can not be specified in both the day of the month and day of the week fields, one must contain ?.
This is used when specifying a day of the month or a day of the week. If you want the first day of the week but do not care on which day of the month this falls then you would have a 1 for the day of the week and ? for day of the month. Likewise, if you want the 5th day of the month and do not care about the day of the week, then you would have 5 in the day of the month and ? in the day of the week. If you have 1 for the day of the week and 5 for day of the month you would expect this to mean 'it must be the first day of the week and the 5th day of the month': this is not supported.

-
This is used to specify a range
1-5 in day of the week field would mean 'on days 1, 2, 3, 4 and 5'. 0-11 in the hours field would mean 'each hour in the morning'.

,
A list of values
In the minutes field 0,15,30,45 would mean 'when the minute is 0, 15, 30 OR 45'.  In the day field, MON,TUES would mean 'on Mondays and Tuesdays'

/
After a value specifies increments
In the minutes field, 0/15 is equivalent to 0,15,30,45; */15 is equivalent to */15; and 10/15 is equivalent to 10,25,40,55. In the day of the month field 3/7 means 'every seven days starting on the third of the month'; 3,10,17,24, ...

L
Last
Incompatible with lists and ranges (, and -), if used it will give confusing results.
The meaning depends on context. Used in the day of the month field, L alone means 'the last day of the month' - day 31 for January, day 28 for February in non leap years, day 29 for Feb in leap years, day 31 for march, etc. Used in the day of the week field, L alone means the last day of the week, 7 or SAT.  Used in the day of the week field an L after a numeric value, such as 6L means 'the last Friday of the month'.

W
The nearest week day
Incompatible with a list or range of days.
Only used in the day of the month to specify the nearest week day (Monday - Friday). 5W would mean 'the week day nearest the 5th of the month'. If the 5th falls on Mon-Friday it would execute as expected, if it falls on a Saturday then Friday will be used, if it falls on a Sunday then the following Monday will be used. The expression must refer to a day of the month and will not execute in the month before or after. For 1W with the first on a Saturday, then Monday the 3rd would be used. (TODO: Confirm the after behaviour)

LW
The last week day of the month

#
The nth
Only used in the day of the month to specify the nth day of the week on the month. So, 2#1 means 'the first Monday of the month', 6#3 means 'the third Friday of the month' and 6#5 means 'the fifth Friday of the month'. If there is no match for the month, say there is no 5th Friday, then nothing happens.

C
Meaningless in Alfresco
It could mean 'the first day on or after the given day included by some calendar'. Support is not complete in the implementation and there is no way to define a calendar in the current configuration. If available it is not tested.

Examples






























Expression Meaning Notes
0 0 12 * * ?         At 12pm (noon) every day Note that the day of the month is specified as all (*) and the day of the week as unspecified (?).
0 0 12 * * ? *       At 12pm (noon) every day  
0 0 12 ? * *         At 12pm (noon) every day  
0 0 12 ? * * *       At 12pm (noon) every day  
0 30 2 * * ?         At 2:30 am every day  
0 30 2 * * ? 2006    At 2:30 am every day during 2006  
0 10 * * * ?         Every hour at ten past the hour  
0 * 8 * * ?          Every minute from 8.00am until 8.59 every day  
0 0,30 8-18 * * ?    Every half hour from 8.00am until 18.00  
0 0/15 * * * ?       Every 15 minutes at 0, 15, 30, 45 minutes past the hour  
0 0 2,14 ? * FRI     At 2.00am and 2pm every Friday  
0 0 4 LW 3,6,9,12 ?  At 4.00am on the last week day of each quarter  
0 0 2 * * 6#1        At 2.00am on the first friday of every month  




Tips


  • Using cron expression in the first hour after midnight can lead to unexpected results when daylight savings are applied and removed. Triggers can fire twice or may be skipped if the time moves backwards or forwards respectively.
  • The names of days and months are case insensitive. You can use MON, Mon or mon.




Script Action Example



    <bean id='runScriptAction' class='org.alfresco.repo.action.scheduled.SimpleTemplateActionDefinition'>
        <property name='actionName'>
            <value>script</value>
        </property>
        <property name='parameterTemplates'>
            <map>
                <entry>
                    <key>
                        <value>script-ref</value>
                    </key>
                    <value>\$\{selectSingleNode('workspace://SpacesStore', 'lucene', 'PATH:'/app:company_home/cm:Record_x0020_Management/cm:testscript.js'' )\}</value>
                </entry>
            </map>
        </property>
        <property name='templateActionModelFactory'>
            <ref bean='templateActionModelFactory'/>
        </property>
        <property name='dictionaryService'>
            <ref bean='DictionaryService'/>
        </property>
        <property name='actionService'>
            <ref bean='ActionService'/>
        </property>
        <property name='templateService'>
            <ref bean='TemplateService'/>
        </property>
    </bean>
   
    <bean id='runScript' class='org.alfresco.repo.action.scheduled.CronScheduledQueryBasedTemplateActionDefinition'>
        <property name='transactionMode'>
            <value>UNTIL_FIRST_FAILURE</value>
        </property>
        <property name='compensatingActionMode'>
            <value>IGNORE</value>
        </property>
        <property name='searchService'>
            <ref bean='SearchService'/>
        </property>
        <property name='templateService'>
            <ref bean='TemplateService'/>
        </property>
        <property name='queryLanguage'>
            <value>lucene</value>
        </property>
        <property name='stores'>
            <list>
                <value>workspace://SpacesStore</value>
            </list>
        </property>
        <property name='queryTemplate'>
            <value>PATH:'/app:company_home'</value>
        </property>
        <property name='cronExpression'>
            <value>0 0/1 * * * ?</value>
        </property>
        <property name='jobName'>
            <value>jobD</value>
        </property>
        <property name='jobGroup'>
            <value>jobGroup</value>
        </property>
        <property name='triggerName'>
            <value>triggerD</value>
        </property>
        <property name='triggerGroup'>
            <value>triggerGroup</value>
        </property>
        <property name='scheduler'>
            <ref bean='schedulerFactory'/>
        </property>
        <property name='actionService'>
            <ref bean='ActionService'/>
        </property>
        <property name='templateActionModelFactory'>
            <ref bean='templateActionModelFactory'/>
        </property>
        <property name='templateActionDefinition'>
            <ref bean='runScriptAction'/>
        </property>
        <property name='transactionService'>
            <ref bean='TransactionService'/>
        </property>
        <property name='runAsUser'>
            <value>System</value>
        </property>
    </bean>

More Examples


More examples can be found in config\alfresco\extension\scheduled-action-services-context.xml.sample.

Attachments

    Outcomes