cancel
Showing results for 
Search instead for 
Did you mean: 

Starting Workflow on a schedule

srowsell
Champ in-the-making
Champ in-the-making
I have been trying this for a while, and gotten to the point I will describe below.

The following is a script which I intend to have run on a schedule (more on that below).  For debugging purposes I have also set it up as a rule which runs when I want it to run, but the end result is to have it run once per day:

var results=search.luceneSearch("+PATH:\"/app:company_home/st:sites/cm:contract-management/cm:documentLibrary/cm:ActiveContracts//*\" +TYPE:\"{duca.contracts.model}contract\" -ASPECT:\"{duca.contracts.model}inWorkflow\" -ASPECT:\"{duca.contracts.model}suppDoc\"");
var today=new Date();

for (var i=0;i<results.length;i++)
{   
   var expYear=(results.properties["contract:expirationDate"]).getFullYear();
   var expMonth=(results.properties["contract:expirationDate"]).getMonth();
   var expDate=(results.properties["contract:expirationDate"]).getDate();
   
   var startEvaluationPeriod = new Date(expYear,expMonth,expDate);
   startEvaluationPeriod.setDate(-results.properties["contract:noticeDays"]);
   
   if (today>startEvaluationPeriod)
   {
      var contractWorkflow = actions.create("start-workflow");
      contractWorkflow.parameters.workflowName="activiti$alfGroupReview";
      contractWorkflow.parameters["bpm:workflowDescription"] = "The attached contract has entered its review period.  It will expire in "+results.properties["contract:noticeDays"]+" days.";
      contractWorkflow.parameters["bpm:groupAssignee"] = people.getGroup("GROUP_ContractManagement");
      contractWorkflow.parameters["bpm:workflowDueDate"]=results.properties["contract:expirationDate"];
      contractWorkflow.execute(results);
      
      results.addAspect("contract:inWorkflow");
      results.save();   
   }
}

This script runs just fine if I comment out the lines within the if block, but I get the following exception in the alfresco.log if I don't:


11:45:53,159 ERROR [org.springframework.extensions.webscripts.AbstractRuntime] Exception from executeScript - redirecting to status template error: 07232130 Failed to execute script 'workspace://SpacesStore/57803310-97ce-4989-8a2e-ce22834d7615': null
org.alfresco.scripts.ScriptException: 07232130 Failed to execute script 'workspace://SpacesStore/57803310-97ce-4989-8a2e-ce22834d7615': null


This strikes me as a nonsense exception, since it's trying to tell me that the script it's trying to run doesn't exist.  But I am open to the possibility that I'm not interpreting it correctly.  (I can verify that the script is getting into the if block; I tried commenting out the workflow lines and putting in other instructions, and it executed those instructions.)

Once I have that fixed, my intention is to execute it once per day by editing the scheduled-action-services-context.xml as follows:


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
   
        <!–
    Define the model factory used to generate object models suitable for use with freemarker templates.
    –>
    <bean id="templateActionModelFactory" class="org.alfresco.repo.action.scheduled.FreeMarkerWithLuceneExtensionsModelFactory">
    <property name="serviceRegistry">
    <ref bean="ServiceRegistry"/>
    </property>
    </bean>

    <!–Execute the script /Company Home/Data Dictionary/Script/exampleScript.js –>
    <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>

    <!– Note that as of Alfresco 4.0, due to a Spring upgrade, the FreeMarker ${foo} entries must be escaped –>

    <value>\$\{selectSingleNode('workspace://SpacesStore', 'lucene', 'PATH:"/app:company_home/app:dictionary/app:scripts/cm:findExpiringContracts.js"' )\}</value>

    <!– This value tag is for Alfresco 3.x, because the escape of FreeMarker entries will fail otherwise –>

    <!–<value>#{"${"}selectSingleNode('workspace://SpacesStore', 'lucene', 'PATH:"/app:company_home/app:dictionary/app:scripts/cm:exampleScript.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>

    <!– Script execution config –>
    <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/cm:customSpace"</value>
    </property>
    <!–Cron script execution every day at Midnight–>
    <property name="cronExpression">
    <value>0 0/2 * * * ?</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"/> <!– This is name of the action (bean) that gets run –>
    </property>
    <property name="transactionService">
    <ref bean="TransactionService"/>
    </property>
    <property name="runAsUser">
    <value>System</value>
    </property>
    </bean>

    </beans>


Right now it's set to run every two minutes, for testing purposes, but of course it isn't working (if only because the script it's trying to run isn't working).

Can anyone here point out where I've gone wrong?

EDIT:  I have confirmed that it's the line:

contractWorkflow.execute(results);

which is objectionable.  Obviously the node at results exists; the aspect is being applied to it.  So there is somehow a problem in this line which is invisible to me.

EDIT 2:  I have also confirmed that the scheduled action is doing nothing.  I added in some instructions to the now working script – with the above line commented out – which would reveal whether or not the script is being executed, and it isn't.  I copied and modified the scheduled-action-services-context.xml file from several resources, and if it's not working, I really don't understand why.

EDIT 3:  The workflow is now working.  I didn't have the workflow "activiti$alfGroupReview" deployed.  There remains the scheduled action issue problem, if anyone has any hints they would like to share.
1 REPLY 1

srowsell
Champ in-the-making
Champ in-the-making
After trying this for a while, I can re-phrase my problem.

When I give the queryTemplate property a value that exists, such as:

    <property name="queryTemplate">
    <value>PATH:"/app:company_home"</value>
    </property>


the scheduled action runs, or at least tries to run.  I get the following as an error:


13:58:00,638 ERROR [freemarker.runtime] Template processing error: "No nodes selected"

No nodes selected
The problematic instruction:
———-
==> ${selectSingleNode('workspace://SpacesStore', 'lucene', 'PATH:"/app:company_home/app:dictionary/app:scripts/cm:findExpiringContracts.js"' )} [on line 1, column 1 in string://fixed]
———-

Java backtrace for programmers:
———-
freemarker.template.TemplateModelException: No nodes selected
   at org.alfresco.repo.action.scheduled.FreeMarkerWithLuceneExtensionsModelFactory$QueryForSingleNodeFunction.exec(FreeMarkerWithLuceneExtensionsModelFactory.java:180)
   at freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:93)
   at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
   at freemarker.core.Expression.getStringValue(Expression.java:93)
   at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
   at freemarker.core.Environment.visit(Environment.java:221)
   at freemarker.core.Environment.process(Environment.java:199)
   at freemarker.template.Template.process(Template.java:237)
   at org.alfresco.repo.template.FreeMarkerProcessor.processString(FreeMarkerProcessor.java:260)
   at org.alfresco.repo.processor.TemplateServiceImpl.processTemplateString(TemplateServiceImpl.java:208)
   at org.alfresco.repo.processor.TemplateServiceImpl.processTemplateString(TemplateServiceImpl.java:227)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:601)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:34)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:46)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.proceedWithAudit(AuditMethodInterceptor.java:245)
   at org.alfresco.repo.audit.AuditMethodInterceptor.proceed(AuditMethodInterceptor.java:211)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:164)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy110.processTemplateString(Unknown Source)
   at org.alfresco.repo.action.scheduled.SimpleTemplateActionDefinition.getAction(SimpleTemplateActionDefinition.java:196)
   at org.alfresco.repo.action.scheduled.CronScheduledQueryBasedTemplateActionDefinition.getAction(CronScheduledQueryBasedTemplateActionDefinition.java:262)
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1$2.execute(AbstractScheduledAction.java:563)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:259)
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1.runTransactionalAction(AbstractScheduledAction.java:557)
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1.doWork(AbstractScheduledAction.java:426)
   at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:529)
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition.execute(AbstractScheduledAction.java:392)
   at org.quartz.core.JobRunShell.run(JobRunShell.java:216)
   at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:563)


If I look at the following link (from the person who pointed me in this direction in the first place):

http://4lch3mi5t.wordpress.com/2012/07/26/scheduled-custom-action-alfresco/

the advice given is that the problematic instruction isn't finding the node from my javascript file – which definitely exists, and is a javascript file (so sayeth the Node Browser) – because I'm using Solr rather than Lucene.  My production server is using Solr, though, and I'd rather not rebuild the thing just to get this to work.  As it is, I have the following as a workaround:

1. Windows Task Scheduler executes a batch file, which contains the line "start http://blahblahblah/ScheduledAction.aspx"
2. This runs a web application, which runs the following web script: modifyProperty (with a nodeRef passed in the querystring)
3. The web script alters the description of the file associated with that nodeRef by passing in the current date
4. Altering this file triggers a rule which executes a script which does what I want it to do

(At this point the crossbow fires, severing the rope which is holding up the anvil, causing the anvil to plummet onto the seesaw, which will launch a net a the Roadrunner…)

So, am I barking up the right tree with respect to the necessity to use a Solr query rather than a Lucene query?  If so, what would be the right Solr query?