Publishing and sharing
In one project, the rules module was connected with elasticore project(':ps-rules'). For several of
the team's projects to use the same rules, publish the rules module as a jar and take it by its
coordinates. elasticore is a plain Gradle configuration, so it works the same way as a project
dependency.
1. Publishing the rules module
plugins {
id 'java-library'
id 'maven-publish'
}
group = 'com.example'
version = '1.0.0'
// ... dependencies as they are (compileOnly elasticore-base)
publishing {
publications {
rules(MavenPublication) {
from components.java
}
}
// the company repository (Nexus, Artifactory, GitHub Packages ...)
repositories {
maven {
url = 'https://nexus.example.com/repository/maven-releases/'
credentials {
username = findProperty('nexusUser') // ~/.gradle/gradle.properties - never in the repository
password = findProperty('nexusPassword')
}
}
}
}
./gradlew :ps-rules:publish # to the company repository
./gradlew :ps-rules:publishToMavenLocal # to ~/.m2 on your PC (for trying it out)
The skeletons (src/main/resources/elasticore-template/…) go into the jar with it.
2. Using it in another project
repositories {
maven { url = 'https://nexus.example.com/repository/maven-public/' } // the repository with the ruleset
mavenCentral()
}
elasticore {
architecture = 'hexagonal'
language = 'java'
rules = ['com.example.rules.PetstoreRules']
}
dependencies {
elasticore 'com.example:ps-rules:1.0.0' // the generator's classpath - not in the application
implementation 'org.jmolecules:jmolecules-ddd:1.10.0'
}
The elasticore configuration resolves from the project's repositories. When a copy of the pet store
took the jar made by publishToMavenLocal this way, -PlistRules and the generated output were the same
as with the module connected (PetstoreEventTopics generated as well). Without mavenLocal() among the
repositories it fails like this:
> Could not resolve all files for configuration ':elasticore'.
> Could not find com.example:ps-rules:1.0.0.
Use mavenLocal() only for trying things out, and let it see only that group:
repositories {
mavenLocal { content { includeGroup 'com.example' } }
mavenCentral()
}
Matching versions
| What | Rule |
|---|---|
The rules module's elasticore-base (compileOnly) | the same as the plugin version of the projects that use it |
| The ruleset jar's version | raise it whenever the rules change. Republish the same version and projects keep using their cache (--refresh-dependencies) |
| When upgrading ElastiCORE | rebuild and retest the ruleset against the new version and publish it as a new version - this is when rule tests pay off |
A rules module compiled against an older ElastiCORE and run in a newer generator can fail during
generation with NoSuchMethodError on a changed API. Raise the ruleset version in the same PR that
upgrades ElastiCORE.
Only some domains
The build's rules = [...] applies to every domain. To use it in one domain only, write it in that
domain's env.yml - this replaces the bundle, so write the bundle name too:
elasticore:
config:
publisher:
rules: [hexagonal-springboot, ossie-export, com.example.rules.PetstoreRules]
When a copy of the pet store removed rules from the build and wrote this, the first line of
-PlistRules was [rules] petstore: hexagonal-springboot + ossie-export + com.example.rules.PetstoreRules,
and the generated output was the same. The elasticore '…' dependency (the ruleset jar) must still be
in the build - that is where the generator finds the classes.
What to share with the team
- A ruleset README: the list of rule ids, the DSL words each rule reads, the
env.ymlsetting keys, the dependencies the application needs (jmolecules-dddand so on) - What has to be done by hand in existing developer's files (split root classes, controllers) when a rule is added or changed - the generator points out only the class annotations of split root classes
- The
-PlistRulesoutput - a reviewer sees "what goes on which file" at a glance