| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width,initial-scale=1"> |
| <title>Command Log :: causeway</title> |
| <link rel="canonical" href="https://causeway.apache.org/userguide/latest/commandlog/about.html"> |
| <meta name="generator" content="Antora 3.1.1"> |
| <link rel="stylesheet" href="../../../_/css/site.css"> |
| <link rel="stylesheet" href="../../../_/css/site-custom.css"> |
| <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i|Raleway:300,400,500,700,800|Montserrat:300,400,700" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"/> |
| <link rel="home" href="https://causeway.apache.org" title="causeway"> |
| </head> |
| <body class="article"> |
| <header class="header"> |
| <nav class="navbar"> |
| <div class="navbar-brand"> |
| <a class="navbar-item" href="https://causeway.apache.org"> |
| <span class="icon"> |
| <img src="../../../_/img/causeway-logo-no-words-65x48.png"></img> |
| </span> |
| <span class="navbar-title">causeway</span> |
| </a> |
| <button class="navbar-burger" data-target="topbar-nav"> |
| <span></span> |
| <span></span> |
| <span></span> |
| </button> |
| </div> |
| <div id="topbar-nav" class="navbar-menu"> |
| <a class="navbar-end"> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Quick Start</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Starter Apps</span> |
| <a class="navbar-item" href="../../../docs/latest/starters/helloworld.html">Hello World</a> |
| <a class="navbar-item" href="../../../docs/latest/starters/simpleapp.html">Simple App</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Learning & Tutorials</span> |
| <a class="navbar-item" href="../../../docs/latest/reference/about.html">Reference App</a> |
| <a class="navbar-item" href="https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html">Petclinic</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Resources</span> |
| <a class="navbar-item" href="../../../docs/latest/resources/cheatsheet.html">Cheatsheet</a> |
| <a class="navbar-item" href="../../../docs/latest/resources/icons.html">Icons</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Guides</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Core</span> |
| <a class="navbar-item" href="../../../userguide/latest/about.html">User Guide</a> |
| <a class="navbar-item" href="../../../refguide/latest/about.html">Reference Guide</a> |
| <a class="navbar-item" href="../../../testing/latest/about.html">Testing Guide</a> |
| <a class="navbar-item" href="../../../security/latest/about.html">Security Guide</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">For use in apps</span> |
| <a class="navbar-item" href="../../../valuetypes/latest/about.html">Value Types</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Development</span> |
| <a class="navbar-item" href="../../../setupguide/latest/about.html">Setup Guide</a> |
| <a class="navbar-item" href="../../../conguide/latest/about.html">Contributors' Guide</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Components</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Security</span> |
| <a class="navbar-item" href="../../../security/latest/bypass/about.html">Bypass</a> |
| <a class="navbar-item" href="../../../security/latest/simple/about.html">Simple</a> |
| <a class="navbar-item" href="../../../security/latest/shiro/about.html">Shiro</a> |
| <a class="navbar-item" href="../../../security/latest/spring/about.html">Spring</a> |
| <a class="navbar-item" href="../../../security/latest/keycloak/about.html">Keycloak</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Viewers</span> |
| <a class="navbar-item" href="../../../vw/latest/about.html">Web UI (Wicket)</a> |
| <a class="navbar-item" href="../../../gqlv/latest/about.html">GraphQL API</a> |
| <a class="navbar-item" href="../../../vro/latest/about.html">REST API (Restful Objects)</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Persistence</span> |
| <a class="navbar-item" href="../../../pjpa/latest/about.html">JPA (EclipseLink)</a> |
| <a class="navbar-item" href="../../../pjdo/latest/about.html">JDO (DataNucleus)</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Extensions</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Core</span> |
| <a class="navbar-item" href="../../../userguide/latest/commandlog/about.html">Command Log</a> |
| <a class="navbar-item" href="../../../userguide/latest/docgen/about.html">Doc Gen</a> |
| <a class="navbar-item" href="../../../userguide/latest/executionlog/about.html">Execution Log</a> |
| <a class="navbar-item" href="../../../userguide/latest/executionoutbox/about.html">Execution Outbox</a> |
| <a class="navbar-item" href="../../../userguide/latest/executionrepublisher/about.html">Execution Republisher</a> |
| <a class="navbar-item" href="../../../userguide/latest/excel/about.html">Excel</a> |
| <a class="navbar-item" href="../../../userguide/latest/flyway/about.html">Flyway</a> |
| <a class="navbar-item" href="../../../userguide/latest/layoutloaders/about.html">Layout Loaders</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Security</span> |
| <a class="navbar-item" href="../../../security/latest/secman/about.html">Secman</a> |
| <a class="navbar-item" href="../../../security/latest/audittrail/about.html">Audit Trail</a> |
| <a class="navbar-item" href="../../../security/latest/spring-oauth2/about.html">Spring OAuth2 Integration</a> |
| <a class="navbar-item" href="../../../security/latest/shiro-realm-ldap/about.html">LDAP Realm for Shiro</a> |
| <a class="navbar-item" href="../../../security/latest/sessionlog/about.html">Session Log</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Web UI (Wicket)</span> |
| <a class="navbar-item" href="../../../vw/latest/fullcalendar/about.html">Full Calendar</a> |
| <a class="navbar-item" href="../../../vw/latest/pdfjs/about.html">pdf.js</a> |
| <a class="navbar-item" href="../../../vw/latest/sse/about.html">Server Side Events</a> |
| <a class="navbar-item" href="../../../vw/latest/tabular/about.html">Tabular Download</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">REST API (Restful Objects)</span> |
| <a class="navbar-item" href="../../../vro/latest/cors/about.html">CORS</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Support</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Contact</span> |
| <a class="navbar-item" href="../../../docs/latest/support/slack-channel.html">Slack</a> |
| <a class="navbar-item" href="../../../docs/latest/support/mailing-list.html">Mailing Lists</a> |
| <a class="navbar-item" href="https://issues.apache.org/jira/browse/CAUSEWAY">JIRA</a> |
| <a class="navbar-item" href="https://stackoverflow.com/questions/tagged/causeway">Stack Overflow</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Releases</span> |
| <a class="navbar-item" href="../../../docs/latest/downloads/how-to.html">Downloads</a> |
| <a class="navbar-item" href="../../../relnotes/latest/about.html">Release Notes</a> |
| <hr class="navbar-divider"/> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Framework</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Process</span> |
| <a class="navbar-item" href="../../../comguide/latest/about.html">Committers' Guide</a> |
| <a class="navbar-item" href="../../../tooling/latest/about.html">Tooling</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Automated Analysis</span> |
| <a class="navbar-item" href="https://sonarcloud.io/dashboard?id=apache_causeway">SonarCloud.io</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Interim Builds</span> |
| <a class="navbar-item" href="../../../comguide/latest/nightly-builds.html">Nightly builds</a> |
| <a class="navbar-item" href="../../../comguide/latest/weekly-builds.html">Weekly builds</a> |
| <a class="navbar-item" href="https://apache-causeway-committers.github.io/causeway-nightly">Website Preview (not ASF hosted)</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Development</span> |
| <a class="navbar-item" href="../../../core/latest/about.html">Internal Design Docs</a> |
| <a class="navbar-item" href="../../../regressiontests/latest/about.html">Regression Tests</a> |
| <a class="navbar-item" href="../../../incubator/latest/about.html">Incubator</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Thanks</span> |
| <a class="navbar-item" href="../../../more-thanks/latest/more-thanks.html">Acknowledgements</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">ASF</a> |
| <div class="navbar-dropdown"> |
| <a class="navbar-item" href="http://www.apache.org/">Apache Homepage</a> |
| <a class="navbar-item" href="https://www.apache.org/events/current-event">Events</a> |
| <a class="navbar-item" href="https://www.apache.org/licenses/">License</a> |
| <a class="navbar-item" href="https://www.apache.org/security/">Security</a> |
| <a class="navbar-item" href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy</a> |
| <a class="navbar-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a> |
| <a class="navbar-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a> |
| <hr class="navbar-divider"/> |
| <a class="navbar-item" href="https://whimsy.apache.org/board/minutes/Causeway.html">PMC board minutes</a> |
| </div> |
| </div> |
| <a class="navbar-item" href="../../../docs/latest/about.html"> |
| <span class="icon"> |
| <img src="../../../_/img/home.png"></img> |
| </span> |
| </a> |
| </div> |
| </div> |
| </nav> |
| </header> |
| <div class="body "> |
| <div class="nav-container" data-component="userguide" data-version="2.0.0"> |
| <aside class="nav"> |
| <div class="panels"> |
| <div class="nav-panel-search hide-for-print"> |
| <input id="algolia-search-input" placeholder="Search"></span> |
| </div> |
| <div class="nav-panel-pagination"> |
| <a class="page-previous disabled" rel="prev" href="" title=""><span></span></a> |
| <a class="page-next disabled" rel="next" |
| href="" title=""><span></span></a> |
| <!-- |
| page.parent doesn't seem to be set... |
| <a class="page-parent disabled" rel="prev" href="" title=""><span></span></a> |
| --> |
| </div> |
| <div class="nav-panel-menu is-active" data-panel="menu"> |
| <nav class="nav-menu"> |
| <h3 class="title"><a href="../about.html">User Guide</a></h3> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="0"> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/overview.html">10,000ft overview</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/domain-entities.html">Domain Entities</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/domain-services.html">Domain Services</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/properties-collections-actions.html">Properties, Collections & Actions</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/ui-layout-and-hints.html">UI Layout & Hints</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/business-rules.html">Business Rules</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/drop-downs-and-defaults.html">Drop downs & Defaults</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/view-models.html">View Models</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/mixins.html">Mixins</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/events.html">Events</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/modules.html">Modules</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/value-types.html">Value types</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/meta-annotations.html">Meta-annotations</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../latest/background-context-and-theory.html">Background, Context & Theory</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../latest/btb/about.html">Beyond the Basics</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/btb/headless-access.html">Headless Access</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/btb/programming-model.html">Programming Model</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/btb/hints-and-tips.html">Hints-n-Tips</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/btb/i18n.html">Internationalization (i18n)</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Extensions</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/commandlog/about.html">Command Log</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/docgen/about.html">DocGen</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/executionlog/about.html">Execution Log</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/executionoutbox/about.html">Execution Outbox</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/executionrepublisher/about.html">Execution Republisher</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/excel/about.html">Excel Library</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/flyway/about.html">Flyway</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../latest/layoutloaders/about.html">Layout Loaders</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </nav> |
| </div> |
| <div class="nav-panel-explore" data-panel="explore"> |
| <div class="context"> |
| <span class="title">User Guide</span> |
| <span class="version">2.0.0</span> |
| </div> |
| <ul class="components"> |
| <li class="component"> |
| <span class="title"> </span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../docs/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../docs/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Committers' Guide</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../comguide/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../comguide/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Contributors' Guide</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../conguide/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../conguide/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Design Docs</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../core/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../core/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Extensions</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../extensions/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../extensions/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">GraphQL Viewer</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../gqlv/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../gqlv/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Incubator Catalog</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../incubator/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../incubator/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">JDO/DataNucleus</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../pjdo/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../pjdo/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">JPA</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../pjpa/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../pjpa/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Reference Guide</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../refguide/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../refguide/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">regressiontests</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../regressiontests/latest/index.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../regressiontests/2.0.0/index.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Release Notes</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../relnotes/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../relnotes/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">REST API (Restful Objects Viewer)</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../vro/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../vro/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Security Guide</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../security/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../security/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Setup Guide</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../setupguide/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../setupguide/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Testing Guide</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../testing/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../testing/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Tooling</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../tooling/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../tooling/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Tutorials</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../tutorials/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../tutorials/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component is-current"> |
| <span class="title">User Guide</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../latest/about.html">3.0.0</a> |
| </li> |
| <li class="version is-current"> |
| <a href="../about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Value Types Catalog</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../valuetypes/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../valuetypes/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Web UI (Wicket Viewer)</span> |
| <ul class="versions"> |
| <li class="version"> |
| <a href="../../../vw/latest/about.html">3.0.0</a> |
| </li> |
| <li class="version"> |
| <a href="../../../vw/2.0.0/about.html">2.0.0</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </aside> |
| </div> |
| <main role="main"> |
| <div class="toolbar" role="navigation"> |
| <button class="nav-toggle"></button> |
| <a href="../../../docs/latest/about.html" class="home-link"></a> |
| <nav class="breadcrumbs" aria-label="breadcrumbs"> |
| <ul> |
| <li><a href="../about.html">User Guide</a></li> |
| <li><a href="about.html">Command Log</a></li> |
| </ul> |
| </nav> |
| <div class="page-versions"> |
| <button class="version-menu-toggle" title="Show other versions of page">2.0.0</button> |
| <div class="version-menu"> |
| <a class="version" href="../../latest/commandlog/about.html">3.0.0</a> |
| <a class="version is-current" href="about.html">2.0.0</a> |
| </div> |
| </div> |
| <div class="edit-this-page"><a href="https://github.com/apache/causeway/edit/2.0.0/extensions/core/commandlog/adoc/modules/commandlog/pages/about.adoc">Edit</a></div> |
| </div> |
| <article class="doc"> |
| <a name="section-top"></a> |
| <h1 class="page">Command Log</h1> |
| <div id="preamble"> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>The <em>Command Log</em> module provides an implementation of <a href="../../../refguide/latest/applib/index/services/publishing/spi/CommandSubscriber.html" class="xref page">CommandSubscriber</a> SPI that persists <a href="../../../refguide/latest/applib/index/services/command/Command.html" class="xref page">Command</a>s using either the <a href="../../../pjpa/latest/about.html" class="xref page">JPA/EclipseLink</a> or <a href="../../../pjdo/latest/about.html" class="xref page">JDO/DataNucleus</a> object store.</p> |
| </div> |
| <div class="paragraph"> |
| <p>One use case is to combine with the <a href="../../../security/latest/audittrail/about.html" class="xref page">Audit Trail</a> extension. |
| The <em>Command Log</em> module logs the action invocations or property edits that the end-user makes, while the <em>audit trail</em> logs the resultant changes in state to domain objects. |
| The two logs are correlated using the <a href="../../../refguide/latest/applib/index/services/iactn/Interaction.html#getInteractionId_" class="xref page">interactionId</a> of the owning <a href="../../../refguide/latest/applib/index/services/iactn/Interaction.html" class="xref page">interaction</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Another use case is to support (persisted) background commands, whereby actions are not invoked immediately but instead persisted and invoked by a background thread; this is described in the <a href="#background-commands">background commands</a> section below.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Sometimes the <a href="../executionlog/about.html" class="xref page">Execution Log</a> extension is also configured with or instead of this extension; see the <a href="#notes">notes</a> below to compare and contrast.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="setup"><a class="anchor" href="#setup"></a>Setup</h2> |
| <div class="sectionbody"> |
| <div class="sect2"> |
| <h3 id="dependency-management"><a class="anchor" href="#dependency-management"></a>Dependency Management</h3> |
| <div class="paragraph"> |
| <p>Add an entry for the <em>Command Log</em> module’s own BOM:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">pom.xml</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencyManagement> |
| <dependencies> |
| <dependency> |
| <groupId>org.apache.causeway.extensions</groupId> |
| <artifactId>causeway-extensions-commandlog</artifactId> |
| <scope>import</scope> |
| <type>pom</type> |
| <version>2.0.0</version> |
| </dependency> |
| </dependencies> |
| </dependencyManagement></code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="dependencies"><a class="anchor" href="#dependencies"></a>Dependencies / Imports</h3> |
| <div class="paragraph"> |
| <p>In the webapp module of your application, add the following dependency:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">pom.xml</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencies> |
| <dependency> |
| <groupId>org.apache.causeway.extensions</groupId> |
| <artifactId>causeway-extensions-commandlog-persistence-XXX</artifactId> <i class="conum" data-value="1"></i><b>(1)</b> |
| </dependency> |
| </dependencies></code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>either: |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><code>causeway-extensions-commandlog-persistence-jpa</code> (<a href="../../../pjpa/latest/about.html" class="xref page">JPA/Eclipselink</a>), or</p> |
| </li> |
| <li> |
| <p><code>causeway-extensions-commandlog-persistence-jdo</code> (<a href="../../../pjdo/latest/about.html" class="xref page">JDO/DataNucleus</a>).</p> |
| </li> |
| </ul> |
| </div></td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>In your application’s <a href="../../latest/modules.html#appmanifest" class="xref page">App Manifest</a>, import the CommandLog modules. |
| The exact modules to use will depend upon the persistence mechanism in use:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">AppManifest.java</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Configuration |
| @Import({ |
| ... |
| CausewayModuleExtCommandLogPersistenceXxx.class, <i class="conum" data-value="1"></i><b>(1)</b> |
| ... |
| }) |
| public class AppManifest { |
| }</code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>either |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><code>CausewayModuleExtCommandLogPersistenceJpa</code> (<a href="../../../pjpa/latest/about.html" class="xref page">JPA/Eclipselink</a>),or</p> |
| </li> |
| <li> |
| <p><code>CausewayModuleExtCommandLogPersistenceJdo</code>, (<a href="../../../pjdo/latest/about.html" class="xref page">JDO/DataNucleus</a>)</p> |
| </li> |
| </ul> |
| </div></td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>If using <a href="../../../security/latest/secman/about.html" class="xref page">SecMan</a>, you will also need to import the <a href="../../../testing/latest/fixtures/about.html" class="xref page">Fixture</a> module; SecMan uses fixture scripts to seed its entities.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="configure-properties"><a class="anchor" href="#configure-properties"></a>Configuration Properties</h3> |
| <div class="paragraph"> |
| <p>Add the database schema used by the <em>Command Log</em> entities to the configuration file:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">application.yml</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">causeway: |
| persistence: |
| schema: |
| auto-create-schemas: causewayExtCommandLog</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Optionally, modify the configuration properties for the <em>Command Log</em> module itself:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">application.yml</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">causeway: |
| extensions: |
| command-log: |
| publish-policy: "always" <i class="conum" data-value="1"></i><b>(1)</b></code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>the alternative is <code>"only-if-system-changed"</code>, which suppresses the persisting of `CommandLogEntry`s for commands where no other system state was changed (for example a finder action with safe semantics). |
| <div class="paragraph"> |
| <p>See <a href="../../../refguide/latest/config/sections/causeway.extensions.html#causeway.extensions.command-log.publish-policy" class="xref page">causeway.extensions.command-log.publish-policy</a> configuration property for more details.</p> |
| </div></td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="menubar-layout-xml"><a class="anchor" href="#menubar-layout-xml"></a>menubar.layout.xml</h3> |
| <div class="paragraph"> |
| <p>Once configured, the extension provides a number of menu actions. |
| You can use <code>menubars.layout.xml</code> to arrange these as you see fit. |
| To get you started, the following fragment adds all of the actions to an "Activity" secondary menu:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">menubars.layout.xml</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><mb:secondary> |
| ... |
| <mb:menu> |
| <mb:named>Activity</mb:named> |
| ... |
| <mb:section> |
| <mb:named>Commands</mb:named> |
| <mb:serviceAction id="activeCommands" objectType="causeway.ext.commandLog.CommandLogMenu"/> |
| <mb:serviceAction id="findMostRecent" objectType="causeway.ext.commandLog.CommandLogMenu"/> |
| <mb:serviceAction id="findCommands" objectType="causeway.ext.commandLog.CommandLogMenu"/> |
| <mb:serviceAction id="findAll" objectType="causeway.ext.commandLog.CommandLogMenu"/> |
| </mb:section> |
| ... |
| </mb:menu> |
| </mb:secondary></code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="secman-security-roles"><a class="anchor" href="#secman-security-roles"></a>SecMan Security Roles</h3> |
| <div class="paragraph"> |
| <p>If <a href="../../../security/latest/secman/about.html" class="xref page">SecMan</a> extension is configured, then permissions must be granted to access the menu actions.</p> |
| </div> |
| <div class="paragraph"> |
| <p>This can be done by granting the role set up by the <a href="../../../refguide/latest/extensions/index/secman/applib/role/seed/CausewayExtCommandLogRoleAndPermissions.html" class="xref page">CausewayExtCommandLogRoleAndPermissions</a> seed fixture script (see its <code>ROLE_NAME</code> constant).</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="user-interface"><a class="anchor" href="#user-interface"></a>User Interface</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>The extension provides a number of menu actions and contributions.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The menu actions are as listed in <a href="#menubar-layout-xml">menubar.layout.xml</a>, above. |
| They allow the administrator to query the persisted commands. |
| Typically access to these actions would be restricted, see <a href="#secman-security-roles">security roles</a> above.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The extension also provides these mixins:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="../../../refguide/latest/extensions/index/commandlog/applib/contributions/Object_recentCommands.html" class="xref page">Object_recentCommands</a></p> |
| <div class="paragraph"> |
| <p>This contributes a <code>recentCommands</code> collection to each and every domain object.</p> |
| </div> |
| <div class="paragraph"> |
| <p>This can be explicit positioned through the domain class' own <a href="../../latest/ui-layout-and-hints.html#object-layout" class="xref page">layout file</a>, but this is generally not necessary: it will slot into the tab group in the layout file indicated for unreferenced collections using <code><tabGroup unreferencedCollections="true"></code>.</p> |
| </div> |
| </li> |
| <li> |
| <p><a href="../../../refguide/latest/extensions/index/commandlog/applib/contributions/HasUsername_recentCommandsByUser.html" class="xref page">HasUsername_recentCommandsByUser</a></p> |
| <div class="paragraph"> |
| <p>This contributes the <code>recentCommandsByUser</code> collection to any domain object that implements the <a href="../../../refguide/latest/applib/index/mixins/security/HasUsername.html" class="xref page">HasUsername</a> interface.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Most notably, this is <a href="../../../security/latest/secman/about.html" class="xref page">SecMan</a> extension’s <a href="../../../refguide/latest/extensions/index/secman/applib/user/dom/ApplicationUser.html" class="xref page">ApplicationUser</a> entity that represents a logged-on user. |
| It is also supported by xref:security:sessionlog:about.adoc</p> |
| </div> |
| </li> |
| <li> |
| <p><a href="../../../refguide/latest/extensions/index/commandlog/applib/contributions/HasInteractionId_commandLogEntry.html" class="xref page">HasInteractionId_commandLogEntry</a></p> |
| <div class="paragraph"> |
| <p>This contributes the <code>commandLogEntry</code> property to any object implementing <a href="../../../refguide/latest/applib/index/mixins/system/HasInteractionId.html" class="xref page">HasInteractionId</a> interface. |
| Typically these are the entities persisted by the <a href="../executionlog/about.html" class="xref page">Execution Log</a> or <a href="../../../security/latest/audittrail/about.html" class="xref page">Audit Trail</a> extensions, making it easy to traverse between these logs.</p> |
| </div> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="background-commands"><a class="anchor" href="#background-commands"></a>Background Commands</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Sometimes we might want to execute an action not immediately in the current users’s thread of control, but instead to perform it in the background; for example any long-running process.</p> |
| </div> |
| <div class="paragraph"> |
| <p>One way to accomplish this is to use <a href="../../../refguide/latest/applib/index/services/wrapper/WrapperFactory.html#asyncWrap_T_AsyncControl" class="xref page">WrapperFactory#asyncWrap(…​)</a>, where the command is executed by another thread obtained from a thread pool (<code>ForkJoinPool.commonPool()</code>). |
| This works well, but has the slight risk that it is not transactionally safe - the async thread executes in its own interaction/transaction, and so might fail even though the initiating command succeeds; or vice versa.</p> |
| </div> |
| <div class="paragraph"> |
| <p>An alternative approach is to use the <a href="../../../refguide/latest/extensions/index/commandlog/applib/dom/BackgroundService.html" class="xref page">BackgroundService</a>. |
| This persists the command as an <code>CommandLogEntry</code> instance, indicating that it is to be executed in the background. |
| Then, a separate thread - eg scheduling using Quartz - can pick up the queued <code>CommandLogEntry</code> and execute it.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="submitting-actions"><a class="anchor" href="#submitting-actions"></a>Submitting Actions</h3> |
| <div class="paragraph"> |
| <p>For example, suppose we have a long-running action to export all the invoices we have received from a supplier, perhaps to be sent to some other system. |
| Assuming that the <code>exportInvoices()</code> action is a regular action on the <code>Supplier</code> domain class, we would use:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">example usage of <code>BackgroundService</code> to invoke a regular action</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Action |
| public void exportInvoices(Supplier supplier) { |
| backgroundService.execute(supplier).exportInvoices(); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>If instead this functionality is implemented as a mixin, we would use something like:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">example usage of <code>BackgroundService</code> to invoke a mixin action:</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Action |
| public void exportInvoices(Supplier supplier) { |
| backgroundService.executeMixin(Supplier_exportInvoices.class, supplier).act(); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The action being invoked must be part of the Causeway metamodel, in other words it cannot be marked uses |
| <a href="../../../refguide/latest/applib/index/annotation/Programmatic.html" class="xref page">@Programmatic</a> or <a href="../../../refguide/latest/applib/index/annotation/Domain_Exclude.html" class="xref page">@Domain.Exclude</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>By default all the usual hide/disable/validate rules will be checked, but there are also methods to allow these rules to be skipped.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Behind the scenes this service uses <a href="../../../refguide/latest/applib/index/services/wrapper/WrapperFactory.html#asyncWrap_T_AsyncControl" class="xref page">WrapperFactory#asyncWrap(…​)</a> using <a href="../../../refguide/latest/applib/index/services/wrapper/control/AsyncControl.html#with_ExecutorService" class="xref page">AsyncControl#with(ExecutorService)</a> to pass an implementation of <code>ExecutorService</code> that persists the command as a <code>CommandLogEntry</code> instance.</p> |
| </div> |
| <div class="paragraph"> |
| <p>If you require more fine-grained control, you can always just use the <a href="../../../refguide/latest/applib/index/services/wrapper/WrapperFactory.html" class="xref page">WrapperFactory</a> async method yourself. |
| The <code>ExecutorService</code> to use is <a href="../../../refguide/latest/extensions/index/commandlog/applib/dom/BackgroundService_PersistCommandExecutorService.html" class="xref page">BackgroundService.PersistCommandExecutorService</a>. |
| This is a Spring <code>@Service</code> and so can be obtained through injection.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="executing-actions-using-the-quartz-scheduler"><a class="anchor" href="#executing-actions-using-the-quartz-scheduler"></a>Executing Actions using the Quartz scheduler</h3> |
| <div class="paragraph"> |
| <p>Once a command has been persisted as a <code>CommandLogEntry</code>, we require some other process to actually execute the command. |
| The <em>Command Log</em> module includes the <code>RunBackgroundCommandsJob</code>, a <a href="https://www.quartz-scheduler.org/">Quartz</a> job that does exactly this. |
| Each time it is called it will query for any background commands that have not been started, and will execute each (using the <a href="../../../refguide/latest/applib/index/services/command/CommandExecutorService.html" class="xref page">CommandExecutorService</a>).</p> |
| </div> |
| <div class="paragraph"> |
| <p>The job is marked as non re-entrant, so it doesn’t matter how often it is called; we recommend a 10 second delay usually works fine.</p> |
| </div> |
| <div class="paragraph"> |
| <p>To configure Quartz, add the following to your <code>AppManifest</code>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">AppManifest.java</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class AppManifest { |
| |
| @Bean(name = "RunBackgroundCommandsJob") <i class="conum" data-value="1"></i><b>(1)</b> |
| public JobDetailFactoryBean jobDetail() { |
| val jobDetailFactory = new JobDetailFactoryBean(); |
| jobDetailFactory.setJobClass(RunBackgroundCommandsJob.class); |
| jobDetailFactory.setDurability(true); |
| return jobDetailFactory; |
| } |
| |
| @Bean |
| public SimpleTriggerFactoryBean trigger( |
| final @Qualifier("RunBackgroundCommandsJob") JobDetail job) { <i class="conum" data-value="1"></i><b>(1)</b> |
| val trigger = new SimpleTriggerFactoryBean(); |
| trigger.setJobDetail(job); |
| trigger.setStartDelay(60_000); <i class="conum" data-value="2"></i><b>(2)</b> |
| trigger.setRepeatInterval(10_000); <i class="conum" data-value="3"></i><b>(3)</b> |
| trigger.setRepeatCount(REPEAT_INDEFINITELY); |
| return trigger; |
| } |
| |
| // ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>name and qualify the job (so will not interfere with any other Quartz jobs you may have defined)</td> |
| </tr> |
| <tr> |
| <td><i class="conum" data-value="2"></i><b>2</b></td> |
| <td>60 secs to wait for the app to be ready</td> |
| </tr> |
| <tr> |
| <td><i class="conum" data-value="3"></i><b>3</b></td> |
| <td>check every 10 seconds</td> |
| </tr> |
| </table> |
| </div> |
| <div class="sect3"> |
| <h4 id="disabling-quartz"><a class="anchor" href="#disabling-quartz"></a>Disabling Quartz</h4> |
| <div class="paragraph"> |
| <p>The <em>Command Log</em> module automatically references the <a href="https://www.quartz-scheduler.org/">Quartz</a> library. |
| If you don’t want to use this functionality and want to exclude quartz, then add an explicit dependency on the <em>Command Log</em> applib but exclude the quartz dependency within it:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">pom.xml</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencies> |
| <dependency> |
| <groupId>org.apache.causeway.extensions</groupId> |
| <artifactId>causeway-extensions-commandlog-applib</artifactId> |
| <exclusions> |
| <exclusion> |
| <groupId>org.quartz-scheduler</groupId> <i class="conum" data-value="1"></i><b>(1)</b> |
| <artifactId>quartz</artifactId> |
| </exclusion> |
| </exclusions> |
| </dependency> |
| </dependencies></code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>exclude reference to quartz</td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="notes"><a class="anchor" href="#notes"></a>Notes</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Conceptually a <strong>command</strong> represents the <em>intention</em> to execute an action or to edit a property ("before" the change), while an <strong>interaction execution</strong> represents the actual execution itself ("after" the change).</p> |
| </div> |
| <div class="paragraph"> |
| <p>The <a href="../../../refguide/latest/applib/index/services/publishing/spi/CommandSubscriber.html" class="xref page">CommandSubscriber</a> SPI and <a href="../../../refguide/latest/applib/index/services/publishing/spi/ExecutionSubscriber.html" class="xref page">ExecutionSubscriber</a> SPI allow either to be subscribed to. |
| From an auditing perspective, their behaviour is quite similar:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>even though a command represents the <em>intention</em> to invoke an action, its <a href="../../../refguide/latest/applib/index/services/publishing/spi/CommandSubscriber.html" class="xref page">CommandSubscriber</a> SPI is only called once the action/property edit has been completed.</p> |
| </li> |
| <li> |
| <p>the <a href="../../../refguide/latest/applib/index/services/publishing/spi/ExecutionSubscriber.html" class="xref page">ExecutionSubscriber</a> is called as soon as the action has completed. |
| In most interactions there will only be a single action called within the interaction, hence these two subscribers will be called at almost the same time with very similar payloads.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>However, there can be some subtle differences:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>the <a href="../../../refguide/latest/applib/index/services/wrapper/WrapperFactory.html" class="xref page">WrapperFactory</a> service allows actions to be invoked "as if" through the user interface. |
| Therefore one action can execute another can execute another, creating a nested call graph of executions.</p> |
| <div class="paragraph"> |
| <p>The <a href="../../../refguide/latest/applib/index/services/publishing/spi/ExecutionSubscriber.html" class="xref page">ExecutionSubscriber</a> is called after each and every execution as it completes, so will be called several times.</p> |
| </div> |
| </li> |
| <li> |
| <p>In contrast, the <a href="../../../refguide/latest/applib/index/services/publishing/spi/CommandSubscriber.html" class="xref page">CommandSubscriber</a> is called only once, for the top-level (outermost) action.</p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="see-also"><a class="anchor" href="#see-also"></a>See also</h2> |
| <div class="sectionbody"> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="../../../refguide/latest/applib/index/services/iactn/Interaction.html" class="xref page">interaction</a></p> |
| </li> |
| <li> |
| <p><a href="../../../refguide/latest/applib/index/services/iactnlayer/InteractionService.html" class="xref page">InteractionService</a>.</p> |
| </li> |
| <li> |
| <p><a href="../../../refguide/latest/applib/index/services/wrapper/WrapperFactory.html" class="xref page">WrapperFactory</a> service</p> |
| </li> |
| <li> |
| <p><a href="../../../refguide/latest/extensions/index/commandlog/applib/dom/BackgroundService.html" class="xref page">BackgroundService</a> service</p> |
| </li> |
| <li> |
| <p><a href="../../../refguide/latest/applib/index/services/publishing/spi/CommandSubscriber.html" class="xref page">CommandSubscriber</a> SPI</p> |
| </li> |
| <li> |
| <p><a href="../../../refguide/latest/applib/index/services/publishing/spi/ExecutionSubscriber.html" class="xref page">ExecutionSubscriber</a> SPI</p> |
| </li> |
| <li> |
| <p><a href="../executionlog/about.html" class="xref page">Execution Log</a> extension</p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| </article> |
| <aside class="article-aside toc hide-for-print" role="navigation"> |
| <p class="toc-title">On this page</p> |
| <div id="article-toc"></div> |
| </aside> |
| </main> |
| </div> |
| <footer class="footer"> |
| <div class="content"> |
| <div class="copyright"> |
| <p> |
| Copyright © 2010~2023 The Apache Software Foundation, licensed under the Apache License, v2.0. |
| <br/> |
| Apache, the Apache feather logo, Apache Causeway, and the Apache Causeway project logo are all trademarks of The Apache Software Foundation. |
| </p> |
| </div> |
| <div class="revision"> |
| <p>Revision: website.20240325-2342</p> |
| </div> |
| </div> |
| </footer> |
| <script src="../../../_/js/site.js"></script> |
| <script async src="../../../_/js/vendor/highlight.js"></script> |
| <script src="../../../_/js/vendor/jquery-3.4.1.min.js"></script> |
| <script src="../../../_/js/vendor/jquery-ui-1.12.1.custom.widget-only.min.js"></script> |
| <script src="../../../_/js/vendor/jquery.tocify.min.js"></script> |
| |
| <script> |
| $(function() { |
| $("#article-toc").tocify( { |
| showEffect: "slideDown", |
| hashGenerator: "pretty", |
| hideEffect: "slideUp", |
| selectors: "h2, h3", |
| scrollTo: 120, |
| smoothScroll: true, |
| theme: "jqueryui", |
| highlightOnScroll: true |
| } ); |
| }); |
| </script> |
| |
| <script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script> |
| <script> |
| function focusSearchInput () { document.querySelector('#algolia-search-input').focus() } |
| var search = docsearch({ |
| appId: '5ISP5TFAEN', |
| apiKey: '0fc51c28b4ad46e7318e96d4e97fab7c', |
| indexName: 'causeway-apache-org', |
| inputSelector: '#algolia-search-input', |
| autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] }, |
| debug: false, |
| }).autocomplete |
| search.on('autocomplete:closed', function () { search.autocomplete.setVal() }) |
| focusSearchInput() |
| window.addEventListener('load', focusSearchInput); |
| </script> |
| |
| <!-- |
| docsearch options: |
| https://docsearch.algolia.com/docs/behavior/ |
| --> |
| <!-- |
| https://www.algolia.com/doc/api-reference/api-parameters/ |
| algoliaOptions: { hitsPerPage: 6 }, |
| --> |
| </body> |
| </html> |