AnsweredAssumed Answered

Compensation action is not executed

Question asked by stijndereede on Mar 4, 2008
Latest reply on Oct 28, 2008 by togomez
I've got a scheduled composite action that runs on all files in a specific folder every minute. This is an upload folder, and the incoming files should be processed and moved accordingly.
This is my composite action:

    <bean id="compositeAction" class="org.alfresco.repo.action.scheduled.CompositeTemplateActionDefinition">
        <property name="actionService">
            <ref bean="ActionService"/>
        </property>
        <property name="templateService">
            <ref bean="TemplateService"/>
        </property>
        <property name="templateActionDefinitions">
            <list>
                <ref bean="cayman_guess-mimetypeScheduledAction" />
                <ref bean="cayman_addHashableAspectScheduledAction" />
                <ref bean="cayman_calculate-contenthashScheduledAction" />
                <ref bean="cayman_extract-languageScheduledAction"/>
                <ref bean="cayman_match-versionScheduledAction"/>
            </list>
        </property>
        <property name="compensatingTemplateCompositeActionDefinition">
            <ref bean="cayman_failed-match-versionScheduledAction"/>
        </property>       
    </bean>
The last action in the list moves the node to a different folder. However, if one of the actions (most importantly the last) fails, I want to node to be moved to a "failed" folder, for human inspection. This is what the cayman_failed-match-versionScheduledAction action does.
My CronScheduledQueryBasedTemplateActionDefinition has transactionMode set to ISOLATED_TRANSACTIONS and compensatingActionMode set to RUN_COMPENSATING_ACTIONS_ON_FAILURE.

Now, when (in the last of the composite actions) I for example get an iterator from an ResultSet, and try to do i.remove(), I get this in my log:

10:59:04,238 ERROR [org.alfresco.repo.action.scheduled.AbstractScheduledAction] Error in scheduled action executed in isolated transactions (other actions will continue
java.lang.ClassCastException: java.lang.UnsupportedOperationException cannot be cast to org.alfresco.repo.action.scheduled.CompensatingActionException
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1.doCompensation(AbstractScheduledAction.java:529)
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1.runTransactionalAction(AbstractScheduledAction.java:599)
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1.doWork(AbstractScheduledAction.java:432)
   at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:299)
   at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition.execute(AbstractScheduledAction.java:398)
   at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
   at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)

The UnsupportedOperationException makes sence, but I think casting the thrown exception to CompensatingActionException isn't logical. Maybe the exception should be caught, and a new CompensatingActionException exception should be thrown.

I think the "(other actions will continue" statement means that the composite action will still be run on the other nodes in the folder (which is correct according to the ISOLATED_TRANSACTIONS setting).

But the main problem is: my compensating action is never run! Allthough I think it should, since one of the composite actions threw an exception. For me, this means that the node remains in the incoming folder, and the composite action is run on this node every minute, failing every time.

On the side, I think there is either an error in the code, or an error in the Wiki documentation:
The AbstractTemplateActionDefinition class has a field compensatingTemplateActionDefinition but it's setters and getters are *CompensatingTemplateCompositeActionDefinition. No field compensatingTemplateCompositeActionDefinition exists in any of the repo.action.scheduled.* classes.
However, the Wiki mentions a field compensatingTemplateActionDefinition for both the SimpleTemplateActionDefinition and CompositeTemplateActionDefinition (which is in fact correct) with of course the implicit setters and getters *compensatingTemplateActionDefinition used by the beans (which is incorrect).

Outcomes