You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@isis.apache.org by Dan Haywood <da...@haywood-associates.co.uk> on 2016/08/23 21:09:55 UTC

Re: Error saving Command after executing scheduled Quartz job

Hi Erik,
sorry for the delay in replying (was on vacation).

Thanks for doing this analysis.  I've raised ISIS-1477 [1], think the
easiest fix is just to do a null guard in BackgroundCommandExecution.

I've created a 1.13.1 maintenance branch, so will do this fix in that
branch.

Cheers
Dan



[1] https://issues.apache.org/jira/browse/ISIS-1477

On 22 July 2016 at 15:33, Erik de Hair <e....@pocos.nl> wrote:

>
> On 07/22/2016 10:16 AM, Erik de Hair wrote:
>
>> Thanks Dan, it works like a charm now!
>>
> At least, that's what I thought...
>
> I was trying to execute an action from an entity in the background. The
> saved command looks like this:
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <cmd:commandDto xmlns:com="http://isis.apache.org/schema/common"
> xmlns:cmd="http://isis.apache.org/schema/cmd">
>     <cmd:majorVersion>1</cmd:majorVersion>
>     <cmd:minorVersion>0</cmd:minorVersion>
> <cmd:transactionId>e9b4e83e-183c-4cf4-9efa-077e8e3c4d32</cmd
> :transactionId>
>     <cmd:targets>
>         <com:oid type="nl.pocos.dom.telephony.sip.porting.FixedOutport"
> id="i_1389"/>
>     </cmd:targets>
>     <cmd:member xsi:type="cmd:actionDto" interactionType="action_invocation"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
> <cmd:memberIdentifier>nl.pocos.dom.telephony.sip.porting.Fix
> edOutport#doPortingPerformedTasks()</cmd:memberIdentifier>
>     </cmd:member>
> </cmd:commandDto>
>
> But executing this command gives a NPE on [1] because the parameters
> element doesn't exist. Adding an empty parameters element to the command in
> the database makes the comand execute right.
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <cmd:commandDto xmlns:com="http://isis.apache.org/schema/common"
> xmlns:cmd="http://isis.apache.org/schema/cmd">
>     <cmd:majorVersion>1</cmd:majorVersion>
>     <cmd:minorVersion>0</cmd:minorVersion>
> <cmd:transactionId>e9b4e83e-183c-4cf4-9efa-077e8e3c4d32</cmd
> :transactionId>
>     <cmd:targets>
>         <com:oid type="nl.pocos.dom.telephony.sip.porting.FixedOutport"
> id="i_1389"/>
>     </cmd:targets>
>     <cmd:member xsi:type="cmd:actionDto" interactionType="action_invocation"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
> <cmd:memberIdentifier>nl.pocos.dom.telephony.sip.porting.Fix
> edOutport#doPortingPerformedTasks()</cmd:memberIdentifier>
> *      <cmd:parameters></cmd:parameters>*
>     </cmd:member>
> </cmd:commandDto>
>
> [1] https://github.com/apache/isis/blob/rel/isis-1.13.0/core/run
> time/src/main/java/org/apache/isis/core/runtime/services/bac
> kground/BackgroundCommandExecution.java#L335
>
>
>
>> On 07/22/2016 12:04 AM, Dan Haywood wrote:
>>
>>> ok, so here's:
>>> -  an improved version of BookmarkService patch: [1]  (this no longer
>>> depends on isis-core-runtime)
>>> - a service to allow background commands to be executed directly [2]
>>> (nb:
>>> this DOES depend on isis-core-runtime)
>>>
>>> I'll factor this stuff back into Isis 1.14.0, but that's a way off yet.
>>> HTH
>>> Dan
>>>
>>> [1] https://gist.github.com/danhaywood/c3b44b06cbdcce5c92327906984dc209
>>> [2] https://gist.github.com/danhaywood/5b3a106ee7c06a53cc33d76f88a04c75
>>>
>>>
>>> On 21 July 2016 at 08:28, Dan Haywood <da...@haywood-associates.co.uk>
>>> wrote:
>>>
>>> Hi Erik,
>>>>
>>>> I've been working on a little service to allow persisted commands to be
>>>> executed manually, not quite there yet.
>>>>
>>>> In the meantime, we can "patch" BookmarkService to support looking up
>>>> domain services, by providing an alternative impl:
>>>>
>>>>
>>>> package todoapp.app.services.directexec;
>>>>
>>>> import java.util.List;
>>>>
>>>> import javax.inject.Inject;
>>>>
>>>> import org.apache.isis.applib.annotation.DomainService;
>>>> import org.apache.isis.applib.annotation.NatureOfService;
>>>> import org.apache.isis.applib.services.bookmark.Bookmark;
>>>> import org.apache.isis.applib.services.registry.ServiceRegistry2;
>>>> import
>>>> org.apache.isis.core.metamodel.services.bookmarks.BookmarkServiceInternalDefault;
>>>>
>>>>
>>>> @DomainService(nature = NatureOfService.DOMAIN, menuOrder = "1")
>>>> public class BookmarkServiceSupportingDomainServices extends
>>>> BookmarkServiceInternalDefault {
>>>>
>>>>      @Override
>>>>      public Object lookup(final Bookmark bookmark) {
>>>>          final String objectType = bookmark.getObjectType();
>>>>          final List<Object> registeredServices =
>>>> serviceRegistry2.getRegisteredServices();
>>>>          for (Object registeredService : registeredServices) {
>>>> if(registeredService.getClass().getName().equals(objectType)) {
>>>>                  return registeredService;
>>>>              }
>>>>          }
>>>>          return super.lookup(bookmark);
>>>>      }
>>>>
>>>>      @Inject
>>>>      ServiceRegistry2 serviceRegistry2;
>>>>
>>>> }
>>>>
>>>>
>>>> You'll need to put this in the app module or somewhere else that has
>>>> access to isis-core-runtime JAR but is also where services get picked
>>>> up.
>>>>
>>>> Will look at more this evening
>>>>
>>>> Thx
>>>> Dan
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On 20 July 2016 at 10:59, Erik de Hair <e....@pocos.nl> wrote:
>>>>
>>>> Hi Dan,
>>>>>
>>>>> On 07/19/2016 04:35 PM, Dan Haywood wrote:
>>>>>
>>>>> Hi Erik,
>>>>>>
>>>>>> yes, I agree, its a similar problem.  Thanks for providing the test
>>>>>> case,
>>>>>> has helped me track down the issue.
>>>>>>
>>>>>> The issue is that regular commands are not being persisted, at all,
>>>>>> under
>>>>>> the RO viewer.  This is because I've made it the responsibility of the
>>>>>> viewer to get hold of the current Command (using
>>>>>> CommandContext#getCommand()) and to update the "Executor" of the
>>>>>> Command
>>>>>> to
>>>>>> be "USER".  And, similarly, in BackgroundCommandExecution adapter the
>>>>>> Executor gets set to "BACKGROUND".
>>>>>>
>>>>>> But in the RO viewer I've not updated this field, so it remains set to
>>>>>> its
>>>>>> default, "OTHER".  This then causes the initialization of the Command
>>>>>> (when
>>>>>> the initial action is invoked) to be skipped, resulting in no
>>>>>> memberIdentifier.
>>>>>>
>>>>>> So, the fix is just for RO viewer to set this field in
>>>>>> DomainObjectResourceServerside and DomainServiceResourceServerside.
>>>>>> I've
>>>>>> raised ISIS-1472 [1]
>>>>>>
>>>>>> ~~~
>>>>>> Meantime, we can work around this in the command module [2], by just
>>>>>> having
>>>>>> it detect an incomplete parent command and unsetting it. This means
>>>>>> that
>>>>>> the background command won't be wired up to its initiating parent
>>>>>> command,
>>>>>> but that's probably no biggy.
>>>>>>
>>>>>> I'll push out a patch release for command immediately. When Isis is
>>>>>> fixed,
>>>>>> then you'll start seeing the parent commands being persisted too.
>>>>>>
>>>>>> Let me know if you see any issues with that.
>>>>>>
>>>>>> Persisting the command works correctly now! But now I've got a problem
>>>>> executing the command in the background. The command refers to a method
>>>>> from a service (not an entity). At some point in the
>>>>> BackgroundCommandExecution [1] no targetObject is found and that
>>>>> results in
>>>>> a NullPointerException [2].
>>>>>
>>>>> In this case I really have to run the background command on a service
>>>>> method because there is no entity involved.
>>>>>
>>>>> Is this clear enough? Is there a way to execute a persisted command
>>>>> 'manually'? I could add the example to the demo-app then.
>>>>>
>>>>> Thanks,
>>>>> Erik
>>>>>
>>>>> [1]
>>>>> https://github.com/apache/isis/blob/rel/isis-1.13.0/core/run
>>>>> time/src/main/java/org/apache/isis/core/runtime/services/bac
>>>>> kground/BackgroundCommandExecution.java#L184
>>>>> [2]
>>>>> https://github.com/apache/isis/blob/rel/isis-1.13.0/core/run
>>>>> time/src/main/java/org/apache/isis/core/runtime/services/bac
>>>>> kground/BackgroundCommandExecution.java#L262
>>>>>
>>>>>
>>>>> Thx
>>>>>> Dan
>>>>>>
>>>>>> [1] https://issues.apache.org/jira/browse/ISIS-1472
>>>>>> [2] https://github.com/isisaddons/isis-module-command/issues/9
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 19 July 2016 at 08:45, Erik de Hair <e....@pocos.nl> wrote:
>>>>>>
>>>>>> Hi Dan,
>>>>>>
>>>>>>> Do you think this problem might have something to do with [1]?
>>>>>>>
>>>>>>> [1]
>>>>>>>
>>>>>>> https://mail-archives.apache.org/mod_mbox/isis-users/201604.
>>>>>>> mbox/%3CCALJOYLGrwBd7ew52m6MxDYq7o2FCU20sKqcspqSUUXH2Y_s7QA@
>>>>>>> mail.gmail.com%3E
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 07/15/2016 04:06 PM, Erik de Hair wrote:
>>>>>>>
>>>>>>> Hi Dan,
>>>>>>>
>>>>>>>> On 06/24/2016 06:02 PM, Dan Haywood wrote:
>>>>>>>>
>>>>>>>> Hi Erik,
>>>>>>>>
>>>>>>>>> So, the good news is that this use case works fine in
>>>>>>>>> 1.13.0-SNAPSHOT.
>>>>>>>>>
>>>>>>>>> I'm still unable to fix this. I created a demo app to reproduce the
>>>>>>>>>
>>>>>>>> issue. [1]
>>>>>>>>
>>>>>>>> I've created a CommandTestService [2]. When I call the
>>>>>>>> requestFixedOutport-method using the restful interface I get the
>>>>>>>> following
>>>>>>>> error:
>>>>>>>>
>>>>>>>> Insert of object "org.isisaddons.module.command
>>>>>>>> .dom.CommandJdo@48d0edd5
>>>>>>>> "
>>>>>>>> using statement "INSERT INTO "isiscommand"."Command"
>>>>>>>>
>>>>>>>> ("arguments","completedAt","exception","executeIn","memberId
>>>>>>>> entifier","memento","parentTransactionId","result","startedA
>>>>>>>> t","targetAction","targetClass","target","timestamp","user","transactionId")
>>>>>>>>
>>>>>>>> VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" failed : integrity
>>>>>>>> constraint
>>>>>>>> violation: NOT NULL check constraint; SYS_CT_10187 table: "Command"
>>>>>>>> column:
>>>>>>>> "memberIdentifier"
>>>>>>>>
>>>>>>>> It feels like I'm missing something here.
>>>>>>>>
>>>>>>>> Thanks for your help.
>>>>>>>>
>>>>>>>> Erik
>>>>>>>>
>>>>>>>> [1] https://github.com/erikdehair/isis-app-todo-app-background
>>>>>>>> [2]
>>>>>>>>
>>>>>>>> https://github.com/erikdehair/isis-app-todo-app-background/b
>>>>>>>> lob/master/dom/src/main/java/todoapp/dom/commandtest/Command
>>>>>>>> TestService.java
>>>>>>>>
>>>>>>>> One wrinkle is that the framework no longer (seems to) persist
>>>>>>>> commands
>>>>>>>>
>>>>>>>>> for
>>>>>>>>> calls to background.execute(x).foo(...) for an ObjectUpdatedEvent.
>>>>>>>>> You
>>>>>>>>> can
>>>>>>>>> make the call in ObjectUpdatingEvent, but not ObjectUpdatedEvent.
>>>>>>>>>
>>>>>>>>> I'm not certain if that's a blocker/I need to revisit, but what I
>>>>>>>>> can
>>>>>>>>> tell
>>>>>>>>> you *does* work perfectly fine is to subscribe to an action domain
>>>>>>>>> event,
>>>>>>>>> and perform the background scheduling in the executed phase.
>>>>>>>>>
>>>>>>>>> The demo app for the isis-command-module has been updated to
>>>>>>>>> demonstrate
>>>>>>>>> this (call changeColor(...) action or changeColorViaMixin).
>>>>>>>>>
>>>>>>>>> Let me know if that works for you.
>>>>>>>>>
>>>>>>>>> Thx
>>>>>>>>> Dan
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> UpdatedEvent is now too late to perform these triggers - no
>>>>>>>>> commands
>>>>>>>>> will
>>>>>>>>> be persisted when calling background.execute(x).foo().  I haven't
>>>>>>>>> trac
>>>>>>>>>
>>>>>>>>> ; I don't
>>>>>>>>>
>>>>>>>>> On 15 June 2016 at 15:24, Erik de Hair <e....@pocos.nl> wrote:
>>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> I have a lot of jobs scheduled with Quartz like described in the
>>>>>>>>>> Apache
>>>>>>>>>> Isis documentation [1] and they work perfectly. But now for a new
>>>>>>>>>> job I
>>>>>>>>>> get
>>>>>>>>>> the following exception when it is finished:
>>>>>>>>>>
>>>>>>>>>> Caused by: javax.jdo.JDODataStoreException: Insert of object
>>>>>>>>>> "org.isisaddons.module.command.dom.CommandJdo@3dd5db8c" using
>>>>>>>>>> statement
>>>>>>>>>> "INSERT INTO Command
>>>>>>>>>>
>>>>>>>>>> (arguments,completedAt,`exception`,executeIn,memberIdentifie
>>>>>>>>>> r,memento,parentTransactionId,`result`,startedAt,targetActio
>>>>>>>>>> n,targetClass,target,`timestamp`,`user`,transactionId)
>>>>>>>>>>
>>>>>>>>>> VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" failed : Column
>>>>>>>>>> 'memberIdentifier'
>>>>>>>>>> cannot be null
>>>>>>>>>> NestedThrowables:
>>>>>>>>>>
>>>>>>>>>> com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Column 'memberIdentifier' cannot be null
>>>>>>>>>>
>>>>>>>>>> The method that is executed by the job is:
>>>>>>>>>>
>>>>>>>>>> public void provisionSIPTrunks(){
>>>>>>>>>>        Query q =
>>>>>>>>>>
>>>>>>>>>> isisJdoSupport.getJdoPersistenceManager().newQuery(SIPSubscription.class);
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>        q.setFilter("begin <= today && sipTrunk.activated == false
>>>>>>>>>> ");
>>>>>>>>>> q.declareParameters(LocalDate.class.getName() +" today");
>>>>>>>>>>        List<SIPSubscription> sipTrunks =
>>>>>>>>>> (List<SIPSubscription>)q.execute(LocalDate.now());
>>>>>>>>>>
>>>>>>>>>>        for (SIPSubscription trunk : sipTrunks) {
>>>>>>>>>>            trunk.startProvisioning();
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> When I create an empty method it works. The
>>>>>>>>>> startProvisioning()-method
>>>>>>>>>> basically sets a boolean and after that an ObjectUpdatedEvent is
>>>>>>>>>> triggered
>>>>>>>>>> and handled by a subscriber. When I disable the
>>>>>>>>>> updatedLifeCycleEvent it
>>>>>>>>>> works and no Command is saved at all.
>>>>>>>>>>
>>>>>>>>>> The subscriber for the ObjectUpdatedEvent creates a command to be
>>>>>>>>>> executed
>>>>>>>>>> the BackgroundCommandService. When I create an empty subscriber
>>>>>>>>>> method
>>>>>>>>>> (so
>>>>>>>>>> no command to be created) it works. But than no background job is
>>>>>>>>>> started.
>>>>>>>>>>
>>>>>>>>>> The following method of domain object SIPTrunk should be executed
>>>>>>>>>> in
>>>>>>>>>> the
>>>>>>>>>> background:
>>>>>>>>>>
>>>>>>>>>> public void updateProvisioning(){
>>>>>>>>>>        // ....
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> At first I implemented this by using the BackgroundService to
>>>>>>>>>> execute it
>>>>>>>>>> like
>>>>>>>>>>
>>>>>>>>>> @Subscribe
>>>>>>>>>> public void on(SIPTrunk.UpdatedEvent ev) throws Exception {
>>>>>>>>>> backgroundService.execute(ev.getSource()).updateProvisioning();
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> This did save the command to be executed with executeIn =
>>>>>>>>>> BACKGROUND
>>>>>>>>>> but
>>>>>>>>>> results in the above exception. Then I tried annotating the method
>>>>>>>>>> with
>>>>>>>>>> @Action like this:
>>>>>>>>>> @Action(command = CommandReification.ENABLED, commandExecuteIn =
>>>>>>>>>> CommandExecuteIn.BACKGROUND)
>>>>>>>>>> public void updateProvisioning(){
>>>>>>>>>>        // ....
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> and triggering it like this
>>>>>>>>>>
>>>>>>>>>> @Subscribe
>>>>>>>>>> public void on(SIPTrunk.UpdatedEvent ev) throws Exception {
>>>>>>>>>>        ev.getSource().updateProvisioning();
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> This doesn't execute the method in the background but immediately
>>>>>>>>>> executes
>>>>>>>>>> it and doesn't save the method as a command.
>>>>>>>>>>
>>>>>>>>>> Any hints for getting this done?
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Erik
>>>>>>>>>>
>>>>>>>>>> [1]
>>>>>>>>>> https://isis.apache.org/guides/ugbtb.html#5.2.1.-background-
>>>>>>>>>> execution
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>
>