quickstart - incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · the quickstart...

46
Quickstart

Upload: others

Post on 28-May-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Quickstart

Table of ContentsPrerequisites 2

Running the archetype 3

Project Structure 4

Addingremoving modules 5

Building (and tests) 6

Tests 6

Metamodel validation 7

Swagger spec 7

Running 9

IDE 9

mvn (jettyrun) 13

Webapp 14

Standalone 14

Docker 15

Using an external database 18

Modules 22

Security 22

Session Logger 23

Commands 25

Auditing 28

Publishing 30

Togglz 34

Quartz 36

FlywayDB 39

Dynamic Reloading 43

Maven Mixins 44

The quickstart is a Maven archetype intended to be used as a template for newapplications

Like the Apache Isis frameworkrsquos own simpleapp archetype the applicationprovides a SimpleObject to adapt and copy along with supporting unit testsintegration tests and BDD (cucumber) specs

The application generated from the archetype is also preconfigured with thedependencies for all of the modules available in the Incode Platform withauditing command profiling security flywaydb and (feature) togglz enabled bydefault The application also configures the Quartz scheduler for backgroundscheduling and the Jolokia servlet allowing consoles such as hawtio to monitorthe internal state of the webapp

1

PrerequisitesThe prerequisite software is

bull Java JDK 8

bull maven 3 (350 or later is recommended)

We also strongly recommend an IDE the Incode Platform developers use JetBrains IntelliJCommunity Edition

2

Running the archetypeUse Maven to generate your application from the quickstart-archetype For example

mvn archetypegenerate -D archetypeGroupId=orgincodeplatformarchetype -D archetypeArtifactId=quickstart-archetype -D archetypeVersion=1162 -D groupId=commycompany -D artifactId=myapp -D version=10-SNAPSHOT -B

Change the groupId and artifactId as required

The application will be generated in a directory named after the artifact (myapp in the exampleabove)

cd myapp

3

Project StructureThe quickstart app consists of five Maven modules a parent module and four submodules Thediagram below shows their dependencies

where

bull quickstart-module-simple is where the business logic resides for an initial simple module

This consists of nothing more than a SimpleObject and supporting menu and repository(basically the same domain as generated by Apache Isis simpleapp archetype)

In your own application we recommend that you clone this module for each discrete modulethat makes up your business domain Doing this from the very beginning will help ensure yourapp doesnrsquot become the proverbial big ball of mud

bull Itrsquos quite common to factor out baseabstract classes to remove boilerplate or to hold utilityclasses The quickstart-module-base module is an ideal place for this intended as a base modulethat all business modules will depend upon It is also where the example togglz feature toggleenum class resides

bull The quickstart-appdefn module holds the applicationrsquos implementation of the AppManifestinterface which defines the modules that make up the application The quickstartrsquosimplementation is domainappappdefnDomainAppAppManifest

Itrsquos also a useful place to define fixtures for demoing prototypes to the business as well assupporting services that might be needed to help configure modules The quickstart includesimplementations of services for both the security spi module and the togglz (feature toggle)module

bull Finally the quickstart-webapp module is what packages up the application as a war file (the WEB-

4

INFwebxml shown in the diagram actually lives in this module) Therersquos very little Java code inthis module the most significant class is DomainAppWicketApplication (extendsIsisWicketApplication) required by the Wicket viewer

Yoursquoll want to load the generated app into an IDE the figure below shows the app as loaded intoIntelliJ

by default the example modules are excluded from the project

See the Apache Isis documentation for further guidance

Addingremoving modulesBy default the DomainAppAppManifest app manifest has dependencies on all of the SPI services all ofthe wicket components the (feature) togglz extension module the settings subdomain (used by thetogglz extension) and the paraname8 metamodel facet

To exclude the modules that you donrsquot require delete or comment entries in the app manifest Tokeep things tidy you should probably also remove the corresponding ltdependencygts from yourapplicationrsquos pomxml files

Conversely the application does not include any of the example subdomains nor libraries Toinclude these take a look at the quickstart with example usage or just read the individualdocumentation for the required module(s) In many cases all thatrsquos required is to update the pomxmlto reference the required module and reference its XxxModule class in your app manifest

5

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 2: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Table of ContentsPrerequisites 2

Running the archetype 3

Project Structure 4

Addingremoving modules 5

Building (and tests) 6

Tests 6

Metamodel validation 7

Swagger spec 7

Running 9

IDE 9

mvn (jettyrun) 13

Webapp 14

Standalone 14

Docker 15

Using an external database 18

Modules 22

Security 22

Session Logger 23

Commands 25

Auditing 28

Publishing 30

Togglz 34

Quartz 36

FlywayDB 39

Dynamic Reloading 43

Maven Mixins 44

The quickstart is a Maven archetype intended to be used as a template for newapplications

Like the Apache Isis frameworkrsquos own simpleapp archetype the applicationprovides a SimpleObject to adapt and copy along with supporting unit testsintegration tests and BDD (cucumber) specs

The application generated from the archetype is also preconfigured with thedependencies for all of the modules available in the Incode Platform withauditing command profiling security flywaydb and (feature) togglz enabled bydefault The application also configures the Quartz scheduler for backgroundscheduling and the Jolokia servlet allowing consoles such as hawtio to monitorthe internal state of the webapp

1

PrerequisitesThe prerequisite software is

bull Java JDK 8

bull maven 3 (350 or later is recommended)

We also strongly recommend an IDE the Incode Platform developers use JetBrains IntelliJCommunity Edition

2

Running the archetypeUse Maven to generate your application from the quickstart-archetype For example

mvn archetypegenerate -D archetypeGroupId=orgincodeplatformarchetype -D archetypeArtifactId=quickstart-archetype -D archetypeVersion=1162 -D groupId=commycompany -D artifactId=myapp -D version=10-SNAPSHOT -B

Change the groupId and artifactId as required

The application will be generated in a directory named after the artifact (myapp in the exampleabove)

cd myapp

3

Project StructureThe quickstart app consists of five Maven modules a parent module and four submodules Thediagram below shows their dependencies

where

bull quickstart-module-simple is where the business logic resides for an initial simple module

This consists of nothing more than a SimpleObject and supporting menu and repository(basically the same domain as generated by Apache Isis simpleapp archetype)

In your own application we recommend that you clone this module for each discrete modulethat makes up your business domain Doing this from the very beginning will help ensure yourapp doesnrsquot become the proverbial big ball of mud

bull Itrsquos quite common to factor out baseabstract classes to remove boilerplate or to hold utilityclasses The quickstart-module-base module is an ideal place for this intended as a base modulethat all business modules will depend upon It is also where the example togglz feature toggleenum class resides

bull The quickstart-appdefn module holds the applicationrsquos implementation of the AppManifestinterface which defines the modules that make up the application The quickstartrsquosimplementation is domainappappdefnDomainAppAppManifest

Itrsquos also a useful place to define fixtures for demoing prototypes to the business as well assupporting services that might be needed to help configure modules The quickstart includesimplementations of services for both the security spi module and the togglz (feature toggle)module

bull Finally the quickstart-webapp module is what packages up the application as a war file (the WEB-

4

INFwebxml shown in the diagram actually lives in this module) Therersquos very little Java code inthis module the most significant class is DomainAppWicketApplication (extendsIsisWicketApplication) required by the Wicket viewer

Yoursquoll want to load the generated app into an IDE the figure below shows the app as loaded intoIntelliJ

by default the example modules are excluded from the project

See the Apache Isis documentation for further guidance

Addingremoving modulesBy default the DomainAppAppManifest app manifest has dependencies on all of the SPI services all ofthe wicket components the (feature) togglz extension module the settings subdomain (used by thetogglz extension) and the paraname8 metamodel facet

To exclude the modules that you donrsquot require delete or comment entries in the app manifest Tokeep things tidy you should probably also remove the corresponding ltdependencygts from yourapplicationrsquos pomxml files

Conversely the application does not include any of the example subdomains nor libraries Toinclude these take a look at the quickstart with example usage or just read the individualdocumentation for the required module(s) In many cases all thatrsquos required is to update the pomxmlto reference the required module and reference its XxxModule class in your app manifest

5

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 3: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

The quickstart is a Maven archetype intended to be used as a template for newapplications

Like the Apache Isis frameworkrsquos own simpleapp archetype the applicationprovides a SimpleObject to adapt and copy along with supporting unit testsintegration tests and BDD (cucumber) specs

The application generated from the archetype is also preconfigured with thedependencies for all of the modules available in the Incode Platform withauditing command profiling security flywaydb and (feature) togglz enabled bydefault The application also configures the Quartz scheduler for backgroundscheduling and the Jolokia servlet allowing consoles such as hawtio to monitorthe internal state of the webapp

1

PrerequisitesThe prerequisite software is

bull Java JDK 8

bull maven 3 (350 or later is recommended)

We also strongly recommend an IDE the Incode Platform developers use JetBrains IntelliJCommunity Edition

2

Running the archetypeUse Maven to generate your application from the quickstart-archetype For example

mvn archetypegenerate -D archetypeGroupId=orgincodeplatformarchetype -D archetypeArtifactId=quickstart-archetype -D archetypeVersion=1162 -D groupId=commycompany -D artifactId=myapp -D version=10-SNAPSHOT -B

Change the groupId and artifactId as required

The application will be generated in a directory named after the artifact (myapp in the exampleabove)

cd myapp

3

Project StructureThe quickstart app consists of five Maven modules a parent module and four submodules Thediagram below shows their dependencies

where

bull quickstart-module-simple is where the business logic resides for an initial simple module

This consists of nothing more than a SimpleObject and supporting menu and repository(basically the same domain as generated by Apache Isis simpleapp archetype)

In your own application we recommend that you clone this module for each discrete modulethat makes up your business domain Doing this from the very beginning will help ensure yourapp doesnrsquot become the proverbial big ball of mud

bull Itrsquos quite common to factor out baseabstract classes to remove boilerplate or to hold utilityclasses The quickstart-module-base module is an ideal place for this intended as a base modulethat all business modules will depend upon It is also where the example togglz feature toggleenum class resides

bull The quickstart-appdefn module holds the applicationrsquos implementation of the AppManifestinterface which defines the modules that make up the application The quickstartrsquosimplementation is domainappappdefnDomainAppAppManifest

Itrsquos also a useful place to define fixtures for demoing prototypes to the business as well assupporting services that might be needed to help configure modules The quickstart includesimplementations of services for both the security spi module and the togglz (feature toggle)module

bull Finally the quickstart-webapp module is what packages up the application as a war file (the WEB-

4

INFwebxml shown in the diagram actually lives in this module) Therersquos very little Java code inthis module the most significant class is DomainAppWicketApplication (extendsIsisWicketApplication) required by the Wicket viewer

Yoursquoll want to load the generated app into an IDE the figure below shows the app as loaded intoIntelliJ

by default the example modules are excluded from the project

See the Apache Isis documentation for further guidance

Addingremoving modulesBy default the DomainAppAppManifest app manifest has dependencies on all of the SPI services all ofthe wicket components the (feature) togglz extension module the settings subdomain (used by thetogglz extension) and the paraname8 metamodel facet

To exclude the modules that you donrsquot require delete or comment entries in the app manifest Tokeep things tidy you should probably also remove the corresponding ltdependencygts from yourapplicationrsquos pomxml files

Conversely the application does not include any of the example subdomains nor libraries Toinclude these take a look at the quickstart with example usage or just read the individualdocumentation for the required module(s) In many cases all thatrsquos required is to update the pomxmlto reference the required module and reference its XxxModule class in your app manifest

5

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 4: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

PrerequisitesThe prerequisite software is

bull Java JDK 8

bull maven 3 (350 or later is recommended)

We also strongly recommend an IDE the Incode Platform developers use JetBrains IntelliJCommunity Edition

2

Running the archetypeUse Maven to generate your application from the quickstart-archetype For example

mvn archetypegenerate -D archetypeGroupId=orgincodeplatformarchetype -D archetypeArtifactId=quickstart-archetype -D archetypeVersion=1162 -D groupId=commycompany -D artifactId=myapp -D version=10-SNAPSHOT -B

Change the groupId and artifactId as required

The application will be generated in a directory named after the artifact (myapp in the exampleabove)

cd myapp

3

Project StructureThe quickstart app consists of five Maven modules a parent module and four submodules Thediagram below shows their dependencies

where

bull quickstart-module-simple is where the business logic resides for an initial simple module

This consists of nothing more than a SimpleObject and supporting menu and repository(basically the same domain as generated by Apache Isis simpleapp archetype)

In your own application we recommend that you clone this module for each discrete modulethat makes up your business domain Doing this from the very beginning will help ensure yourapp doesnrsquot become the proverbial big ball of mud

bull Itrsquos quite common to factor out baseabstract classes to remove boilerplate or to hold utilityclasses The quickstart-module-base module is an ideal place for this intended as a base modulethat all business modules will depend upon It is also where the example togglz feature toggleenum class resides

bull The quickstart-appdefn module holds the applicationrsquos implementation of the AppManifestinterface which defines the modules that make up the application The quickstartrsquosimplementation is domainappappdefnDomainAppAppManifest

Itrsquos also a useful place to define fixtures for demoing prototypes to the business as well assupporting services that might be needed to help configure modules The quickstart includesimplementations of services for both the security spi module and the togglz (feature toggle)module

bull Finally the quickstart-webapp module is what packages up the application as a war file (the WEB-

4

INFwebxml shown in the diagram actually lives in this module) Therersquos very little Java code inthis module the most significant class is DomainAppWicketApplication (extendsIsisWicketApplication) required by the Wicket viewer

Yoursquoll want to load the generated app into an IDE the figure below shows the app as loaded intoIntelliJ

by default the example modules are excluded from the project

See the Apache Isis documentation for further guidance

Addingremoving modulesBy default the DomainAppAppManifest app manifest has dependencies on all of the SPI services all ofthe wicket components the (feature) togglz extension module the settings subdomain (used by thetogglz extension) and the paraname8 metamodel facet

To exclude the modules that you donrsquot require delete or comment entries in the app manifest Tokeep things tidy you should probably also remove the corresponding ltdependencygts from yourapplicationrsquos pomxml files

Conversely the application does not include any of the example subdomains nor libraries Toinclude these take a look at the quickstart with example usage or just read the individualdocumentation for the required module(s) In many cases all thatrsquos required is to update the pomxmlto reference the required module and reference its XxxModule class in your app manifest

5

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 5: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Running the archetypeUse Maven to generate your application from the quickstart-archetype For example

mvn archetypegenerate -D archetypeGroupId=orgincodeplatformarchetype -D archetypeArtifactId=quickstart-archetype -D archetypeVersion=1162 -D groupId=commycompany -D artifactId=myapp -D version=10-SNAPSHOT -B

Change the groupId and artifactId as required

The application will be generated in a directory named after the artifact (myapp in the exampleabove)

cd myapp

3

Project StructureThe quickstart app consists of five Maven modules a parent module and four submodules Thediagram below shows their dependencies

where

bull quickstart-module-simple is where the business logic resides for an initial simple module

This consists of nothing more than a SimpleObject and supporting menu and repository(basically the same domain as generated by Apache Isis simpleapp archetype)

In your own application we recommend that you clone this module for each discrete modulethat makes up your business domain Doing this from the very beginning will help ensure yourapp doesnrsquot become the proverbial big ball of mud

bull Itrsquos quite common to factor out baseabstract classes to remove boilerplate or to hold utilityclasses The quickstart-module-base module is an ideal place for this intended as a base modulethat all business modules will depend upon It is also where the example togglz feature toggleenum class resides

bull The quickstart-appdefn module holds the applicationrsquos implementation of the AppManifestinterface which defines the modules that make up the application The quickstartrsquosimplementation is domainappappdefnDomainAppAppManifest

Itrsquos also a useful place to define fixtures for demoing prototypes to the business as well assupporting services that might be needed to help configure modules The quickstart includesimplementations of services for both the security spi module and the togglz (feature toggle)module

bull Finally the quickstart-webapp module is what packages up the application as a war file (the WEB-

4

INFwebxml shown in the diagram actually lives in this module) Therersquos very little Java code inthis module the most significant class is DomainAppWicketApplication (extendsIsisWicketApplication) required by the Wicket viewer

Yoursquoll want to load the generated app into an IDE the figure below shows the app as loaded intoIntelliJ

by default the example modules are excluded from the project

See the Apache Isis documentation for further guidance

Addingremoving modulesBy default the DomainAppAppManifest app manifest has dependencies on all of the SPI services all ofthe wicket components the (feature) togglz extension module the settings subdomain (used by thetogglz extension) and the paraname8 metamodel facet

To exclude the modules that you donrsquot require delete or comment entries in the app manifest Tokeep things tidy you should probably also remove the corresponding ltdependencygts from yourapplicationrsquos pomxml files

Conversely the application does not include any of the example subdomains nor libraries Toinclude these take a look at the quickstart with example usage or just read the individualdocumentation for the required module(s) In many cases all thatrsquos required is to update the pomxmlto reference the required module and reference its XxxModule class in your app manifest

5

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 6: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Project StructureThe quickstart app consists of five Maven modules a parent module and four submodules Thediagram below shows their dependencies

where

bull quickstart-module-simple is where the business logic resides for an initial simple module

This consists of nothing more than a SimpleObject and supporting menu and repository(basically the same domain as generated by Apache Isis simpleapp archetype)

In your own application we recommend that you clone this module for each discrete modulethat makes up your business domain Doing this from the very beginning will help ensure yourapp doesnrsquot become the proverbial big ball of mud

bull Itrsquos quite common to factor out baseabstract classes to remove boilerplate or to hold utilityclasses The quickstart-module-base module is an ideal place for this intended as a base modulethat all business modules will depend upon It is also where the example togglz feature toggleenum class resides

bull The quickstart-appdefn module holds the applicationrsquos implementation of the AppManifestinterface which defines the modules that make up the application The quickstartrsquosimplementation is domainappappdefnDomainAppAppManifest

Itrsquos also a useful place to define fixtures for demoing prototypes to the business as well assupporting services that might be needed to help configure modules The quickstart includesimplementations of services for both the security spi module and the togglz (feature toggle)module

bull Finally the quickstart-webapp module is what packages up the application as a war file (the WEB-

4

INFwebxml shown in the diagram actually lives in this module) Therersquos very little Java code inthis module the most significant class is DomainAppWicketApplication (extendsIsisWicketApplication) required by the Wicket viewer

Yoursquoll want to load the generated app into an IDE the figure below shows the app as loaded intoIntelliJ

by default the example modules are excluded from the project

See the Apache Isis documentation for further guidance

Addingremoving modulesBy default the DomainAppAppManifest app manifest has dependencies on all of the SPI services all ofthe wicket components the (feature) togglz extension module the settings subdomain (used by thetogglz extension) and the paraname8 metamodel facet

To exclude the modules that you donrsquot require delete or comment entries in the app manifest Tokeep things tidy you should probably also remove the corresponding ltdependencygts from yourapplicationrsquos pomxml files

Conversely the application does not include any of the example subdomains nor libraries Toinclude these take a look at the quickstart with example usage or just read the individualdocumentation for the required module(s) In many cases all thatrsquos required is to update the pomxmlto reference the required module and reference its XxxModule class in your app manifest

5

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 7: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

INFwebxml shown in the diagram actually lives in this module) Therersquos very little Java code inthis module the most significant class is DomainAppWicketApplication (extendsIsisWicketApplication) required by the Wicket viewer

Yoursquoll want to load the generated app into an IDE the figure below shows the app as loaded intoIntelliJ

by default the example modules are excluded from the project

See the Apache Isis documentation for further guidance

Addingremoving modulesBy default the DomainAppAppManifest app manifest has dependencies on all of the SPI services all ofthe wicket components the (feature) togglz extension module the settings subdomain (used by thetogglz extension) and the paraname8 metamodel facet

To exclude the modules that you donrsquot require delete or comment entries in the app manifest Tokeep things tidy you should probably also remove the corresponding ltdependencygts from yourapplicationrsquos pomxml files

Conversely the application does not include any of the example subdomains nor libraries Toinclude these take a look at the quickstart with example usage or just read the individualdocumentation for the required module(s) In many cases all thatrsquos required is to update the pomxmlto reference the required module and reference its XxxModule class in your app manifest

5

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 8: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Building (and tests)To build the generated app

mvn clean install

This will compile the code and automatically run all tests (discussed in more detail below) and italso package up the application as a WAR file (namely webapptargetmyappwar)

TestsThe generated application includes unit tests integration tests and BDD cucumber specificationsAll of these are executed using the surefire plugin which is configured to follow a namingconvention

Table 1 Test configurations

Test typeNaming

convention Used in Module(s) Disabled usingGenerated

Reports

Unit tests _Test module-simple -DskipUT targetsurefire-unittest-reports

Integration tests _IntegTest module-simple appdefn -DskipITtargetsurefire-integtest-reports

BDD specs _IntegBddSpec appdefn -DskipBStargetsurefire-integbddspecs-reports

Itrsquos also possible to disable all tests using the usual -DskipTests flag

The reports are generated relative to the module that contains the tests Such reports can be pickedup by your continuous integration server

In addition the BDD specs also generate a (very simple) website at targetcucumber-html-

reportindexhtml and a (much richer) website at targetcucumber-reportscucumber-html-

reportsoverview-featureshtml

6

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 9: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

One thing to be aware of if a unit test or integration test fails then the build will break Howevernote that if a BDD spec fails (eg due to a missing binding) then the build continues the failure isshown in the generated cucumber report instead

The configuration of tests in the Maven pomxml project files is done using the surefire andcucumberreporting maven mixins discussed below

Metamodel validationThe generated application also configures the Apache Isis maven plugin to validate the domainapplication For example if a supporting method for an action findByName is misspelt then this willbe reported and the build will fail In the quickstart app the metamodel validation plugin isconfigured in the module-simple module

Running metamodel validation does require bootstrapping the application so will lengthen theoverall build time If required the metamodel validation can be skipped using -Dskipisis-validate

The configuration in the Maven pomxml project files is done using the isis-validate mavenmixindiscussed below

Swagger specThe generated application also configures the Apache Isis maven plugin to generate a Swagger specfile This can for example be used to generate stubs in various programming languages

In the quickstart app the plugin is configured to run in the appdefn module (so providing a singlespec for the entire app) The configuration is done using the isis-swagger mavenmixin discussedbelow

Generating the swagger spec does require bootstrapping the application so will lengthen theoverall build time If required the swagger generation can be skipped using -Dskipisis-swagger

7

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 10: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

When run it generates swagger files in targetgenerated-resourcesisis-swagger relative tomodule that configures the plugin

8

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 11: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

RunningThere are a number of ways that you can run your application

IDEWhen developing an Apache Isis application yoursquoll typically want to run the app from within theIDE Not only does this reduce the feedback loop (no need to package and deploy for example) youcan also very easily set up debugging breakpoints and the like

To run the app from the IDE we use Apache Isis orgapacheisisWebServer which runs the app asa command line application This starts up an embedded Jetty instance configured to run thewebapp

For example herersquos the launch configuration to run the generated application from IntelliJ

That is to say

bull main-class orgapacheisisWebServer

bull program args -m domainappappdefnDomainAppAppManifest

using

mvn -Denhance -Dskipdefault datanucleusenhance -T1C -o

run against the parent pom to enhance the JDO domain entities See the Apache Isis documentationfor further guidance

When the application is started this way it runs without any fixtures that is using

9

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 12: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

domainappappdefnDomainAppAppManifest configured in webappWEB-INFisisproperties The onlyuser account that is available therefore is the default superuser provided by the security modulenamely isis-module-security-adminpass

The home page shows only the security modulersquos menu not the domain apprsquos entities(`SimpleObjectrsquos menu etc)

Manually setting up a user and permissions to be able to access the business domain would betedious to say the least So instead we can use an extended version of the app manifest which willalso run some fixtures These set up a user account and also some dummy data

10

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 13: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

For example herersquos the updated launch configuration using the app manifest

That is to say

bull program args -m domainappappdefnDomainAppAppManifestWithFixtures

which supplies additional fixtures using

Overrideprotected void overrideFixtures(final ListltClasslt extends FixtureScriptgtgtfixtureScripts) fixtureScriptsadd(SimpleObject_dataPersistScriptclass) fixtureScriptsadd(SeedSuperAdministratorRoleAndSvenSuperUserclass)

When we run the app again we can now log in using a new svenpass user account

11

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 14: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

The home page now shows a Simple Objects menu

from whence we can access the SimpleObjects also created by the fixture

12

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 15: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Note also the additional menus on the right-hand side to access other modules set up and accessibleto the sven superuser These are discussed in more detail below

mvn (jettyrun)If you want to run the application without even loading it into the IDE then you can do this usingthe maven Jetty plugin

mvn -pl webapp jettyrun

The -pl webapp argument indicates that the command is run in the webappsubdirectorysubmodule

However note that this will run with the standard DomainAppAppManifest as configured in WEB-INFisisproperties the only user account is isis-module-security-admin

More than likely yoursquoll want to override the manifest you can do this using a system property Forexample

mvn -pl webapp jettyrun -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures

The configuration in the Maven pomxml project files for the jetty plugin that provides this feature isdone using the jettywar mavenmixin discussed below

13

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 16: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

WebappThe application can also be run in a servlet container using the war file generated from the usualbuild For example

mvn install -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxxwar (where xxx is the parent projectrsquos artifactId) generated in webapptargetThis can then be deployed to the servlet container in the normal way For example if deploying toApache Tomcat just copy to the $TOMCAT_HOMEwebapps directory

If you want to change any of the configuration properties (eg the app manifest torun on start up) note that it is possible to override the configuration externallySee the Apache Isis docs for further guidance

The configuration in the Maven pomxml project files for mavenrsquos war plugin is done using thejettywar mavenmixin discussed below

StandaloneYet another alternative is to build the webapp to run standalone as a single uber-jar once againusing Jetty as an embedded instance This could be useful for example to distribute standaloneprototype of your application for review

Building the standalone jar is done by setting the -Dmavenmixin-jettyconsole property For example

mvn install -Dmavenmixin-jettyconsole -DskipTests -Dskipisis-validate -Dskipisis-swagger

will result in a xxx-webapp-10-SNAPSHOT-jetty-consolewar (where xxx is the projectrsquos artifactId)generated in webapptarget This can then be running using java for example

java -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar

This displays a Swing UI from which the webapp can be started

14

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 17: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Itrsquos also possible to run headless or to change the port And again the manifest can be changedusing a system property For example

java -DisisappManifest=domainappappdefnDomainAppAppManifestWithFixtures -jar webapptargetmyapp-webapp-10-SNAPSHOT-jetty-consolewar --headless --port 9090

The configuration in the Maven pomxml project files for the jettyconsole plugin that provides thisfeature is done using the jettyconsole mavenmixin discussed below

DockerFinally itrsquos also possible to package up and run the webapp as a Docker container

bull to package the webapp as a Docker image

mvn -pl webapp -o -Dmavenmixin-docker -Ddocker-pluginimageName=mycompanymyapp dockerbuild

where imageName is anything you want

The configuration for the docker plugin is done using the docker mavenmixin discussed below

15

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 18: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

bull and to run it

docker container run -p 80808080 -d mycompanymyapp

On Windows you may need to enable the Docker daemon first otherwise themvn install command above will fail

You might also need to ensure that the Unidentified networks are configured tobe private

This can be done using the Local Security Policy application

This will bootstrap the application docker container ps will show all running containersAlternatively Kitematic provides a simple UI to view and interact with running containers

16

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 19: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

When the application is started this way it runs without any fixtures There are a variety of ways tooverride this but these easiest is probably to use the $ISIS_OPT environment variable a set ofkeyvalue pairs concatenated together

The scriptsrundockersh script is a simple wrapper that reads all properties from an externallyspecified configuration file and starts the docker container correctly For example

pushd scriptsrundockersh mycompanymyapp isis-overridesproperties -p 80808080popd

where

bull mycompanymyapp is the name of the image to be run

bull -p 80808080 is passed through to the docker run command

See the Apache Isis docs for further guidance on deploying with Docker

17

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 20: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Using an external databaseAll of the examples listed above run the application against an in-memory HSQLDB databaseObviously though at some point yoursquoll want to persist your data against an external database

To do so just requires that overriding four configuration properties that specify the JDBC driverJDBC URL user and password It also (of course) requires that the JDBC driver is configured as altdependencygt in the webapprsquos pomxml

For example to run the quickstart application against SQL Server

bull create a new and empty database eg myappdb with corresponding user and passwordmyappdbos3cr3t say

bull edit the webapppomxml to include the sqljdbc4 driver

ltprofilegt ltidgtjdbc-mssqlltidgt ltactivationgt ltpropertygt ltnamegtskipjdbc-mssqlltnamegt ltpropertygt ltactivationgt ltdependenciesgt ltdependencygt ltgroupIdgtcommicrosoftsqlserverltgroupIdgt ltartifactIdgtmssql-jdbcltartifactIdgt ltversiongt640jre8ltversiongt ltdependencygt ltdependenciesgtltprofilegt

bull change (by simply editing in isisproperties) or override (eg by passing in as -D systemproperties) the following configuration properties

isispersistordatanucleusimpljavaxjdooptionConnectionDriverName=commicrosoftsqlserverjdbcSQLServerDriverisispersistordatanucleusimpljavaxjdooptionConnectionURL=jdbcsqlserverlocalhost1433instance=databaseName=myappdbisispersistordatanucleusimpljavaxjdooptionConnectionUserName=myappdboisispersistordatanucleusimpljavaxjdooptionConnectionPassword=s3cr3t

For example an IntelliJ launch configuration can specify system properties

18

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 21: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

where the system properties dialog is

When the application has started the tables should have been automatically created (by virtue ofthe isispersistordatanucleusimpldatanucleusschemaautoCreateAll=true configuration propertyin isisproperties)

19

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 22: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

with 10 SimpleObject instances created through the fixture

20

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 23: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

If running against a persistent datastore then remember that the fixture scriptshould only be run the very first time you run up the application Thereafterswitch to the regular app manifest (domainappappdefnDomainAppAppManifest)otherwise yoursquoll likely get INSERT errors on start up (trying to re-insert the samedummy data)

21

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 24: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

ModulesNow wersquove seen how to run the application letrsquos explore some of the features already configured inthe quickstart

SecurityThe security module provides authentication and authorisation implemented by an Apache ShiroRealm

WEB-INFshiroini file

incodePlatformSpiSecurityRealm = orgisisaddonsmodulesecurityshiroIsisModuleSecurityRealmsecurityManagerrealms = $incodePlatformSpiSecurityRealm

authenticationStrategy = orgisisaddonsmodulesecurityshiroAuthenticationStrategyForIsisModuleSecurityRealmsecurityManagerauthenticatorauthenticationStrategy = $authenticationStrategy

Each logged-in user has a corresponding ApplicationUser account accessible from the me menuitem

which shows the current user

22

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 25: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Other functionality is available from the security menu

Note that the security seed data (defined in the SeedSuperAdministratorRoleAndSvenSuperUser fixture)also sets up a role required by the togglz module also see below

Session LoggerThe session logger module records each user session as the user logs in or logs out (or is timed outautomatically)

23

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 26: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

The session logger menu items are on the Activity menu

Sessions can be searched by datetime and user

returning matching sessions

24

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 27: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

which can be drilled into

CommandsThe session logger module captures actions and property edits as persistent Command objects Thesecommands represent the intention to invoke the actionedit the property rather than the actioninvocationproperty edit itself

The quickstart app (when using the fixtures) disables commands globally in the app manifest

25

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 28: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicescommandactionsnone) configurationPropertiesput(isisservicescommandpropertiesnone)

but the SimpleObject domain object re-enables command reification for both editing of the notesproperty

Property( command = CommandReificationENABLED ) private String notes

and for invoking the updateName action

Action( command = CommandReificationENABLED )public SimpleObject updateName( )

Persisted Command objects can be accessed in several ways One option is to use the Activity menu

26

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 29: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Alternatively recent commands executed by an end-user can be found via their corespondingApplicationUser object

For example invoking the SimpleObjectupdateName() action

27

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 30: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

results in this Command

Using commands itrsquos also possible to defer their invocation to be run in the background eitherusing ActioncommandExecuteIn() or using the BackgroundService The quartz module is configuredin the webapp to run such background commands see below for details

AuditingWhere commands capture the intention of a user to invoke an actionedit a property audit records(as provided by the audit module) capture the effect of performing such an interaction With the

28

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 31: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

quickstart app configuring both commands and audits this provides excellent traceability of cause-and-effect

The quickstart app (when using the fixtures) disables auditing globally in the app manifest

DomainAppAppManifestWithFixtures

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicesauditobjectsnone)

but the SimpleObject re-enables auditing using

DomainObject( auditing = AuditingENABLED)public class SimpleObject

For example invoking the SimpleObjectupdateName() action (the example given above whilediscussing commands) persists a corresponding a Command and which also shows the correspondingaudit entries

In this case there is just one AuditEntry object

29

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 32: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

PublishingPublishing and commands share some similarities both create an XML representation of an actioninvocation or property edit However whereas a Command represents only the intention to invokethe action with publishing the serialized XML also captures the result of the invocation and somebasic metrics

The main use case of publishing is to be able facilitate message exchange between external systemsThe quickstart app uses the publishmq module which bootstraps an in-memory ActiveMQ instanceand publishes to it

In fact the publishmq module allows the location of the ActiveMQ queue to be overridden Thequickstart app configures these properties but leaves them as their defaults (that is connecting toan in-memory ActiveMQ instance)

isisproperties (in webapp module)

isisservicesPublisherServiceUsingActiveMqvmTransportUri=vmbrokerisisservicesPublisherServiceUsingActiveMqmemberInteractionsQueue= memberInteractionsQueue

The quickstart app (when using the fixtures) disables publishing globally in the app manifest

30

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 33: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

DomainAppAppManifestWithFixtures (in the appdefn module)

protected void disableAuditingAndCommandAndPublishGlobally(final MapltString StringgtconfigurationProperties) configurationPropertiesput(isisservicespublishobjectsnone) configurationPropertiesput(isisservicespublishactionsnone) configurationPropertiesput(isisservicespublishpropertiesnone)

but the SimpleObject domain object re-enables publishing for both editing of the notes property

Property( publishing = PublishingENABLED)private String notes

and for invoking the updateName action

Action( publishing = PublishingENABLED)public SimpleObject updateName( )

Using the hawtio console we can monitor the messages sent to the ActiveMQ message Downloadthe hawtio JAR file and start using

java -jar hawtio-app-153jar --port 9090

Then connect to the jolokia servlet (configured in the quickstartrsquos webxml)

31

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 34: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

with the port set to 8080 and the path set to apijolokia

Invoking the updateName action on SimpleObject will result in a message being sent to the ActiveMQqueue

and indeed the details of the message can be inspected

32

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 35: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Note that these are only visible via hawtio because there is nothing consumingthe messages For that you need to configure a consumer The embedded camelextended example does precisely this

The publishmq module also persists all interactions to a database table this is to allow messages tobe resent if required The message can be seen persisted as a PublishedEvent entity (searchablefrom the Activity menu)

33

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 36: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

TogglzFeature toggles are a technique with various use cases one of which is to allow functionality to berolled out partially eg for feedback The togglz module provides support for this (leveraging thesettings module for feature persistence

The quickstart integrates this module and demonstrates its usage in the SimpleObjectMenu

SimpleObjectMenu (in module-simple)

public class SimpleObjectMenu

public ListltSimpleObjectgt listAll()

public ListltSimpleObjectgt findByName( ) public boolean hideFindByName() return TogglzFeaturefindByNameisActive()

public SimpleObject create( ) public boolean hideCreate() return TogglzFeatureSimpleObject_createisActive()

where TogglzFeature is this enum

TogglzFeature (in module-base)

public enum TogglzFeature implements orgtogglzcoreFeature

Label(Enable SimpleObjectcreate) EnabledByDefault SimpleObject_create

Label(Enable SimpleObjectfindByName) SimpleObject_findByName

public boolean isActive() return FeatureContextgetFeatureManager()isActive(this)

Because the SimpleObject_findByName feature toggle is disabled the corresponding action is hidden

34

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 37: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Users with the isis-module-togglz-admin role can change feature toggles dynamically

which brings up the togglz console

With the feature enabled the findByName action become visible

35

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 38: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

QuartzThe quartz extension module provides an in-memory scheduler for running jobs according to aschedule The quickstart app uses this to schedule background commands every 10 seconds Itsconfiguration could of course be extended to perform other tasks

The configuration is contained in quartz-configxml

36

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 39: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

quartz-configxml (in the webapp module)

ltxml version=10 encoding=UTF-8gtltjob-scheduling-data xmlns=httpwwwquartz-schedulerorgxmlJobSchedulingDataxmlnsxsi=httpwwww3org2001XMLSchema-instance xsischemaLocation=httpwwwquartz-schedulerorgxmlJobSchedulingDatahttpwwwquartz-schedulerorgxmljob_scheduling_data_1_8xsd version=18gt

ltschedulegt

ltjobgt ltnamegtRunBackgroundJobsltnamegt ltgroupgtDomainAppltgroupgt ltdescriptiongtRuns all background jobsltdescriptiongt ltjob-classgtorgisisaddonsmodulequartzdomjobsRunBackgroundCommandsJobltjob-classgt ltjob-data-mapgt ltentrygt ltkeygtuserltkeygt ltvaluegtscheduler_userltvaluegt ltentrygt ltentrygt ltkeygtrolesltkeygt ltvaluegtadmin_roleltvaluegt ltentrygt ltjob-data-mapgt ltjobgt

lttriggergt ltcrongt ltnamegtRunBackgroundJobsEvery10Secondsltnamegt ltjob-namegtRunBackgroundJobsltjob-namegt ltjob-groupgtDomainAppltjob-groupgt ltcron-expressiongt010 ltcron-expressiongt ltcrongt lttriggergt

ltschedulegtltjob-scheduling-datagt

where RunBackgroundCommandsJob is provided by the quartz module

To see this in use add the follow mixin

37

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 40: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Mixin(method=act)public class SimpleObject_updateNameInBackground private final SimpleObject simpleObject public SimpleObject_updateNameInBackground(final SimpleObject simpleObject) thissimpleObject = simpleObject

MemberOrder(name = name sequence = 3) public SimpleObject act(final String name) messageServiceinformUser(name will be updated in the next 10 seconds) backgroundService2execute(simpleObject)updateName(name) return simpleObject

public String default0Act() return simpleObjectdefault0UpdateName()

Inject MessageService messageService

Inject BackgroundService2 backgroundService2

which provides a new updateNameInBackground action

which when invoked does not immediately change the objectrsquos name but instead displays amessage

38

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 41: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Keep clicking on the objectrsquos title to reload within 10 seconds the name should change

Listing all commands shows how the updateNameInBackground action is executed immediately(in the foreground) and as a side-effect creates a command for updateName executed in thebackground by the Quartz scheduler

FlywayDBThe flywaydb extension integrates FlywayDB to automatically handle database migrations Theseensure that the schema of the (production) database is in sync with that required by the domain

39

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 42: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

entities

To demonstrate its usage the quickstart app includes theDomainAppAppManifestWithFlywayEnabledForSqlServer manifest This adds a number of configurationproperties the most important of which is

configurationPropertiesput( isispersistordatanucleusimpldatanucleusschemaautoCreateAll false)

This tells DataNucleus to not automatically create the required database schema so that it isinstead created manually by Flyway running the provided SQL scripts

There are a number of other configuration properties also set in that manifest these indicate whichschemas FlywayDB should track and where to locate the migration scripts on the classpath

The migration scripts themselves are in the appdefn module in a subpackage of dbmigration

Before running the app it may be necessary to manually create the schema for FlywayDBrsquos ownschema_version table

CREATE TABLE flywaygo

With this done the app can be run against an (otherwise) empty SQL Server database This resultsin FlywayDB automatically creating the database tables

40

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 43: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

The flywayschema_version table keeps track of the scripts that have been applied

There are a couple of other points worth making

bull First the manifest also uses the following configuration property

configurationPropertiesput( isispersistordatanucleusimpldatanucleusMapping sqlserver)

to instruct DataNucleus to pick up any -sqlserverorm files from the classpath There are twosuch DocumentAbstract-sqlserverorm and CommandJdo-sqlserverorm

41

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 44: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

bull Second the quickstart app also provides a beforeMigratesql script to drop all indexconstraintsand uses the autoCreateConstraints property so that DataNucleus will automatically re-createany indices afterwards

For large databases this would not be practicable in which case the beforeMigratesql scriptshould be removed Any changes to indices would therefore need to be provided in migrationSQL scripts

42

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 45: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Dynamic ReloadingThe module-simple module includes layoutgradle and liveReloadgradle scripts and the Wicketviewer is configured for live reloading

viewer_wicketproperties (in appdefn module)

isisviewerwicketliveReloadUrl=httplocalhost35729livereloadjssnipver=1

The procedure described in the Apache Isis documentation explains that the two scripts should berun together

gradle -t --offline -b layoutsgradle ampgradle -t --offline -b liveReloadgradle amp

43

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins
Page 46: Quickstart - Incodeplatform.incode.org/quickstart/quickstart.pdf · 2019-01-16 · The quickstart is a Maven archetype intended to be used as a template for new applications. Like

Maven MixinsTo minimize boilerplate the Maven pomxml files use the comgithubodavidmavenpluginsmixin-maven-plugin This allows the ltbuildgt definitions of other pomxml files to be mixed in to (that isincluded in) the consuming pomxml

The maven mixins themselves used by the generated application are listed in the table below

groupIdartifactIdgithub repo Description

comdanhaywoodmavenmixincucumberreporting java-mavenmixin-cucumberreporting

Configures the netmasterthoughtmaven-cucumber-reporting plugin to generate HTML reports based onoutputs of BDD specification tests

comdanhaywoodmavenmixindatanucleusenhance java-mavenmixin-datanucleusenhance

Configures the orgdatanucleusdatanucleus-maven-pluginto post-process (enhance) persistent entities according tothe JDO spec

comdanhaywoodmavenmixindocker java-mavenmixin-docker

Configures the comspotifydocker-maven-plugin plugin tocreate Docker images and to upload these to a specifiedregistry

comdanhaywoodmavenmixinenforcerrelaxed java-mavenmixin-enforcerrelaxed

Configures the maven-enforcer-plugin plugin with anumber of pre-defined rules (though not dependencyconvergence checking)

comdanhaywoodmavenmixinjettyconsole java-mavenmixin-jettyconsole

Configures the orgsimplericityjettyconsolejetty-console-maven-plugin to create a console app (withoptional Swing UI) to bootstrap the application from thecommand line using an embedded Jetty instance

comdanhaywoodmavenmixinjettywar java-mavenmixin-jettywar

Configures the maven-war-plugin to build a war (webapparchive) and the ` orgeclipsejettyjetty-maven-pluginto be able to run this from maven (using mvn jettywar)

comdanhaywoodmavenmixinsourceandjavadoc java-mavenmixin-sourceandjavadoc

Configures the maven-javadoc-plugin plugin to createJavadoc website and the maven-jxr-plugin to create asimilar website of the source code (cross-referencing theJavadoc)

comdanhaywoodmavenmixin standardjava-mavenmixin-standard

Configures the standard maven-clean-plugin maven-resources-plugin maven-compiler-plugin maven-jar-plugin` maven-install-plugin maven-deploy-plugin andmaven-site-plugin` plugins (mostly just setting theirversion)

comdanhaywoodmavenmixinstaticanalysis java-mavenmixin-staticanalysis

Configures the maven-checkstyle-plugin maven-pmd-plugin` javancss-maven-plugin and jdepend-maven-pluginplugins The configuration files driving these plugins arespecified as properties

comdanhaywoodmavenmixin surefirejava-mavenmixin-surefire

Configures the maven-surefire-plugin with multipleexecutions to run unit tests integration tests and BDDspecifications testing support is discussed further below

44

  • Quickstart
  • Table of Contents
  • Prerequisites
  • Running the archetype
  • Project Structure
    • Addingremoving modules
      • Building (and tests)
        • Tests
        • Metamodel validation
        • Swagger spec
          • Running
            • IDE
            • mvn (jettyrun)
            • Webapp
            • Standalone
            • Docker
              • Using an external database
              • Modules
                • Security
                • Session Logger
                • Commands
                • Auditing
                • Publishing
                • Togglz
                • Quartz
                • FlywayDB
                  • Dynamic Reloading
                  • Maven Mixins