You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by bu...@apache.org on 2014/02/09 14:11:05 UTC
svn commit: r897010 - in /websites/staging/isis/trunk: cgi-bin/ content/
content/core/services/command-context.html
content/core/services/scratchpad.html
Author: buildbot
Date: Sun Feb 9 13:11:05 2014
New Revision: 897010
Log:
Staging update by buildbot for isis
Modified:
websites/staging/isis/trunk/cgi-bin/ (props changed)
websites/staging/isis/trunk/content/ (props changed)
websites/staging/isis/trunk/content/core/services/command-context.html
websites/staging/isis/trunk/content/core/services/scratchpad.html
Propchange: websites/staging/isis/trunk/cgi-bin/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Sun Feb 9 13:11:05 2014
@@ -1 +1 @@
-1565682
+1566291
Propchange: websites/staging/isis/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Sun Feb 9 13:11:05 2014
@@ -1 +1 @@
-1565682
+1566291
Modified: websites/staging/isis/trunk/content/core/services/command-context.html
==============================================================================
--- websites/staging/isis/trunk/content/core/services/command-context.html (original)
+++ websites/staging/isis/trunk/content/core/services/command-context.html Sun Feb 9 13:11:05 2014
@@ -277,20 +277,145 @@
</h1>
</div>
-<blockquote>
- <p>this is a stub for <code>CommandContext</code> and <code>CommandService</code> services</p>
-</blockquote>
+<p>The <code>CommandContext</code> service is a <a href="../../applib-guide/domain-services/how-to-09-020-How-to-write-a-typical-domain-service.html">request-scoped</a> service that reifies the invocation of an action on a domain object into an object itself. This reified information is encapsulated within the <code>Command</code> object.</p>
+
+<p>By default, the <code>Command</code> is held in-memory only; once the action invocation has completed, the <code>Command</code> object is gone. The optional
+ supporting <code>CommandService</code> enables the implementation of <code>Command</code> to be pluggable, however, enabling the <code>Command</code> to be persisted.</p>
+
+<p>Persistent <code>Command</code>s support several use cases:</p>
+
+<ul>
+<li>they enable profiling of the running application (which actions are invoked then most often, what is their response time)</li>
+<li>they act as a parent to any background commands that might be invoked through the <a href="./background-service.html">BackgroundService</a></li>
+<li>if <a href="./auditing-service.html">auditing</a> is configured, they provide better audit information as the <code>Command</code> (the 'cause' of an action) can be correlated to the audit records (the "effect" of the action) through the unique <code>transactionId</code> GUID</li>
+<li>if <a href="./publishing-service.html">publishing</a> is configured, they provide better traceability as the <code>Command</code> is also correlated with any published events, again through the unique <code>transactionId</code> GUID</li>
+</ul>
+
+<p>Assuming that the <code>CommandService</code> supports persistent <code>Command</code>s, the associated <a href="../../applib-guide/reference/recognized-annotations/Command.html">@Command</a> annotation also allows action invocations to be performed in the background. In this case the act of invoking the action on an object instead returns the <code>Command</code> to the user.</p>
<h3>API</h3>
+<p>The <code>CommandContext</code> request-scoped service defines the following very simple API:</p>
+
+<pre><code>@RequestScoped
+public class CommandContext {
+
+ @Programmatic
+ public Command getCommand() { ... }
+}
+</code></pre>
+
+<p>where <code>Command</code> is defined in turn as:</p>
+
+<pre><code>public interface Command extends HasTransactionId {
+
+ public abstract String getUser();
+ public abstract Timestamp getTimestamp();
+
+ public abstract Bookmark getTarget();
+ public abstract String getMemberIdentifier();
+ public abstract String getTargetClass();
+ public abstract String getTargetAction();
+ public String getArguments();
+ public String getMemento();
+
+ public ExecuteIn getExecuteIn();
+ public Executor getExecutor();
+ public Persistence getPersistence();
+ public boolean isPersistHint();
+
+ public abstract Timestamp getStartedAt();
+ public abstract Timestamp getCompletedAt();
+ public Command getParent();
+
+ public Bookmark getResult();
+ public String getException();
+
+}
+</code></pre>
+
+<p>and where <code>Command</code> has the members:</p>
+
+<ul>
+<li><code>getUser()</code> - is the user that initiated the action.</li>
+<li><code>getTimestamp()</code> - the date/time at which this action was created.</li>
+<li><code>getTarget()</code> - bookmark of the target object (entity or service) on which this action was performed</li>
+<li><code>getMemberIdentifier()</code> - holds a string representation of the invoked action</li>
+<li><code>getTargetClass()</code> - a human-friendly description of the class of the target object</li>
+<li><code>getTargetAction()</code> - a human-friendly name of the action invoked on the target object</li>
+<li><code>getArguments()</code> - a human-friendly description of the arguments with which the action was invoked</li>
+<li><code>getMemento()</code> - a formal (XML or similar) specification of the action to invoke/being invoked</li>
+<li><code>getExecuteIn()</code> - whether this command is executed in the foreground or background</li>
+<li><code>getExecutor()</code> - the (current) executor of this command, either user, or background service, or other (eg redirect after post).</li>
+<li><code>getPersistence()</code>- the policy controlling whether this command should ultimately be persisted (either "persisted", "if hinted", or "not persisted")</li>
+<li><code>isPersistHint()</code> - whether that the command should be persisted, if persistence policy is "if hinted".</li>
+<li><code>getStartedAt()</code> - the date/time at which this action started (same as <code>timestamp</code> property for foreground commands)</li>
+<li><code>getCompletedAt()</code> - the date/time at which this action completed.</li>
+<li><code>getParent()</code> - for actions created through the <code>BackgroundService</code>, captures the parent action</li>
+<li><code>getResult()</code> - bookmark to object returned by action, if any</li>
+<li><code>getException()</code> - exception stack trace if action threw exception</li>
+</ul>
+
<h3>Implementation</h3>
+<p>The <code>CommandContext</code> implementation is part of the core framework (isis-core), in fact is a concrete class in the applib:</p>
+
+<ul>
+<li><code>org.apache.isis.applib.services.command.CommandContext</code></li>
+</ul>
+
+<p>The <code>CommandService</code> interface - which acts as the factory for different <code>Command</code> implementations - is pluggable. Currently there is only a single implementation, provided by the JDO objectstore, which persists <code>Command</code>s to an RDBMS:</p>
+
+<ul>
+<li><code>org.apache.isis.objectstore.jdo.applib.service.command.CommandServiceJdo</code></li>
+</ul>
+
+<p>There is also a supporting repository to query persisted <code>Command</code>s:</p>
+
+<ul>
+<li><code>org.apache.isis.objectstore.jdo.applib.service.command.CommandServiceJdoRepository</code></li>
+</ul>
+
<h3>Usage</h3>
+<p>Typically the domain objects have little need to interact with the <code>CommandContext</code> and <code>Command</code> directly; what is more useful is that these are persisted in support of the various use cases identified above.</p>
+
+<p>One case however where a domain object might want to obtain the <code>Command</code> is to determine whether it has been invoked in the foreground, or in the background. It can do this using the <code>getExecutedIn()</code> method:</p>
+
+<pre><code>ExecutedIn executedIn = commandContext.getCommand().getExecutedIn();
+</code></pre>
+
+<p>If run in the background, it might then notify the user (eg by email) if all work is done.</p>
+
+<p>This leads us onto a related point, distinguishng the effective user vs the real user. When running in the foreground, the current user can be obtained from the <code>DomainObjectContainer</code>, using:</p>
+
+<pre><code>String user = container.getUser().getName();
+</code></pre>
+
+<p>If running in the background, however, then the current user will be the credentials of the background process, for example as run by a Quartz scheduler job.</p>
+
+<p>The domain object can still obtain the original ("effective") user that caused the job to be created, using:</p>
+
+<pre><code>String user = commandContext.getCommand().getUser();
+</code></pre>
+
<h3>Registering the Services</h3>
+<p>Register like any other service in <code>isis.properties</code>. For example, if using the core <code>CommandContext</code> service along with the <a href="../../components/objectstores/jdo/command-service.html">JDO implementation</a> of the <code>CommandService</code>, then it would be:</p>
+
+<pre><code>isis.services=...,\
+ org.apache.isis.applib.services.command.CommandContext,\
+ org.apache.isis.objectstore.jdo.applib.service.command.CommandServiceJdo,\
+ org.apache.isis.objectstore.jdo.applib.service.command.CommandServiceJdoRepository,\
+ ...
+</code></pre>
+
<h3>Related Services</h3>
+<p>These services are most often used in conjunction with the <code>BackgroundService</code> and <code>BackgroundCommandService</code> (both described <a href="./background-service.html">here</a>). For <code>BackgroundService</code> captures commands for execution in the background, while the [BackgroundCommandService] persists such commands for execution. </p>
+
+<p>The implementations of <code>CommandService</code> and <code>BackgroundCommandService</code> are intended to go together, so that persistent parent <code>Command</code>s can be associated with their child background <code>Command</code>s.</p>
+
</div>
Modified: websites/staging/isis/trunk/content/core/services/scratchpad.html
==============================================================================
--- websites/staging/isis/trunk/content/core/services/scratchpad.html (original)
+++ websites/staging/isis/trunk/content/core/services/scratchpad.html Sun Feb 9 13:11:05 2014
@@ -277,7 +277,7 @@
</h1>
</div>
-<p>The Scratchpad service is a <a href="../../applib-guide/domain-services/how-to-09-020-How-to-write-a-typical-domain-service.html">request-scoped</a> service to allow objects to exchange information even if they do not directly call each other.</p>
+<p>The <code>Scratchpad</code> service is a <a href="../../applib-guide/domain-services/how-to-09-020-How-to-write-a-typical-domain-service.html">request-scoped</a> service to allow objects to exchange information even if they do not directly call each other.</p>
<h3>API & Implementation</h3>