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/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java#L184 >> [2] >> https://github.com/apache/isis/blob/rel/isis-1.13.0/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/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_s...@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","memberIdentifier","memento","parentTransactionId","result","startedAt","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/blob/master/dom/src/main/java/todoapp/dom/commandtest/CommandTestService.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,memberIdentifier,memento,parentTransactionId,`result`,startedAt,targetAction,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 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >> >
