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 <[email protected]> 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 <[email protected]> >>> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >> >
