Skip to main content
ElastiCORE 3.0 is a release candidate: 3.0.261022-rc1 on Maven Central. Projects on the 2.2 line: see the 2.2 documentation.
Version: 3.0

env.yml settings

Each domain folder src/main/resources/blueprint/<domain>/ has an env.yml.

blueprint/petstore/env.yml (the pet store)
elasticore:
enable: true
config:
domainName: petstore
framework: springboot
mode: jpa
j2ee: jakarta
apiPath: "/api" # REST paths: /api/petstore/...
table:
prefix: ps_
referenceColumn: short # references to other aggregates: category_id (default 2.x-style category_category_id)
annotations:
genid: "genid(io.elasticore.springboot3.util.IdUtils.newId)"
namespace:
base: io.elasticore.sample.petstore

config:​

KeyMeans
domainNamethe domain's name - in packages, file names and API paths
framework, mode, j2eespringboot, jpa (also mongo, uml, dsl; comma-separated for several), jakarta
apiPaththe base of the REST paths (default /api): /api/v1 gives /api/v1/<domain>/<entity>
table.prefixa prefix for table names (ps_ gives ps_purchase_order)
table.autoJointrue: JOIN FETCH every reference on findById (otherwise only @fetchjoin fields)
tableSchemathe database schema of every table (an entity's @schema wins)
annotationsnamed annotations for @env:name fields, and the genid generator
testCode: "true"JUnit 5 + Mockito service tests
supportAI: "true"Spring AI @Tool methods on the extension services (Spring Boot)
jsonviewfalse (default), true, auto - Jackson @JsonView visibility
publisher.rules, publisher.suppressthe rule bundle of this domain, rules turned off (The rule engine)
springBoot: 4the Boot version when generating without the plugin
httpPort: springHTTP ports as Spring @HttpExchange clients (Boot 4) (HTTP ports)
contextthe bounded context's boundaries (below)
referenceColumn: shortDDD id references use the field's name as column (customer_id) - for new projects, since it renames existing columns
adminRolethe role @access(admin) checks (default ADMIN)
outbox: truedomain events through a transactional outbox (events)
mapping: xmlJPA mapping in META-INF/orm.xml, no jakarta.persistence in the domain classes
archTest: true<Domain>ArchitectureTest with ArchUnit, generated once (needs com.tngtech.archunit:archunit-junit5:1.3.0)

namespace:​

base lays out the hexagonal packages under one package; any key written next to it wins:

KeyPackage with base: com.acme.erp
entity, enumerationcom.acme.erp.domain.model
event / domainService / domainRepository.domain.event / .domain.service / .domain.repository
service / dto.application / .application.dto
inboundPort / queryPort, port.application.port.in / .application.port.out
control.adapter.in.web
repository, persistence.infrastructure.persistence

Presets for the layered, DDD and hexagonal layouts: Architectures.

Multi-module​

In a multi-module build a namespace can point into another module with module://package, so that, for example, only services and controllers go to an application module:

namespace:
service: app-admin://com.acme.shop.service

The plugin applied to the root finds every subproject with src/main/resources/blueprint (elasticore { modules = ['core-domain', 'app-admin'] } to name them).

Bounded contexts​

A blueprint domain is a bounded context. A domain with context: says what it uses from other contexts (uses) and what others may use of it (publishes), and the build enforces it.

# blueprint/catalog/env.yml
config:
context:
publishes: [ProductDTO, Unit] # what other contexts may use as field types (DTOs, enums, @embeddable)

# blueprint/shop/env.yml
config:
context:
uses: catalog # the upstream contexts this one relies on
publishes: [OrderPlaced] # events too (root name + event name)
SituationResult
a shop field uses catalog's ProductDTO (listed in both)passes
a shop field uses catalog's entity Productbuild fails: another context's entity is no field type - hold its id (productId: long) or use a DTO it publishes
a type of a context not in usesbuild fails (... does not declare it (config.context.uses: catalog))
a type missing from the other context's declared publishesbuild fails (... which catalog does not publish)
a process manager on: [shop:OrderPlaced] in another contextchecked like a type
neither side declares context:as before
[elcore3] context: [shop] Order.product is catalog's entity Product: another context's entity is no field type
- hold its id (productId: long), or use a DTO catalog publishes.

Any context: also generates blueprint/context-map.md, a Mermaid map of the contexts (it shows on GitHub as is). The 2.x generator does not read context:.

Generating one domain​

./gradlew elcore3 -Pdomain=shop

All domains are loaded (so cross-domain references resolve), then only shop is written. Cleaning up files the DSL no longer produces happens only in a run that generated every domain.