본문으로 건너뛰기
ElastiCORE 3.0 은 릴리스 후보(RC)입니다: Maven Central 의 3.0.261022-rc1. 2.2 라인 프로젝트는 2.2 문서를 보세요.
버전: 3.0

DSL 단어와 모델 검사

팀만의 DSL 단어​

ElastiCORE 는 모르는 단어를 오류로 보지 않고 보관만 합니다. 생성 코드에는 아무것도 나오지 않고, 규칙이 읽을 수 있습니다. 그래서 팀의 개념을 YAML 에 그대로 적게 할 수 있습니다.

model/entity.yml
  Category:
meta: entity @root @editable @expose(20) @access(read=public) @nodelete # 엔티티 단어
Customer:
fields:
email: string(100) @email @pii # 필드 단어
PurchaseOrder:
meta: entity @root @expose(20) @event(Placed(total), Shipped, Cancelled) @topic(petstore.order) # 값이 있는 단어
어디에있나값
엔티티 meta:e.hasMeta("nodelete")e.metaValue("topic") → "petstore.order"
필드f.hasDsl("pii")f.dslValue("search") → "like"
같은 단어 여러 번e.metaValues("x")
이름 붙은 속성 @x(a=1, b=2)f.dslProperty("x", "a"), e.metaText("x") (원문)

필드 단어는 대소문자를 가리지 않습니다(@PII 도 hasDsl("pii")).

지을 때:

  • ElastiCORE 에 이미 있는지 먼저 - @readonly, @restExclude, @example, @label 처럼 이미 있는 기능을 다시 만들지 마세요. 규칙을 지워 보고 결과가 그대로면 이미 있는 것입니다. 목록: DSL 레퍼런스.
  • 이미 쓰는 단어와 겹치지 않게 - @event, @search, @label … 걱정되면 팀 접두사(@psTopic).
  • 철자가 틀려도 조용합니다 - @pi 는 그냥 무시됩니다. 중요한 단어라면 아래처럼 검사 규칙을 두세요.

모델 검사 - ModelCheck​

규칙은 코드를 쓰지 않고 모델만 검사할 수도 있습니다.

호출결과
ModelCheck.warn(msg)경고만 출력. 같은 메시지는 한 번. 빌드는 계속
ModelCheck.fail(msg)생성은 끝까지 하고(모든 문제를 한 번에 보이도록) 마지막에 모아 보여 준 뒤 빌드 실패
    @Rule("ps-model-check")
void check(EntitySpec e) {
if (!e.aggregateRoot()) return;

if (!e.commands().isEmpty() && e.events().isEmpty()) {
ModelCheck.warn(String.format(
"[ps] %s takes commands but declares no @event: nothing outside the aggregate hears what happened.",
e.getName()));
}

// A team setting in env.yml: elasticore.config.ps.maxPageSize
String max = e.config("ps.maxPageSize");
String expose = e.metaValue("expose");
if (max != null && expose != null && expose.trim().matches("\\d+")
&& Integer.parseInt(expose.trim()) > Integer.parseInt(max.trim())) {
ModelCheck.fail(String.format(
"[ps] %s pages %s rows at a time (@expose(%s)); the team maximum is ps.maxPageSize=%s.",
e.getName(), expose.trim(), expose.trim(), max.trim()));
}
}

팀 설정값 - config(...)​

검사 기준처럼 프로젝트마다 다를 수 있는 값은 규칙에 박지 말고 env.yml 의 config: 아래에 둡니다.

blueprint/petstore/env.yml
elasticore:
config:
domainName: petstore
…
ps:
maxPageSize: 500 # team rule ps-model-check: no @expose(n) above this
코드읽는 값
e.config("ps.maxPageSize")그 엔티티 도메인의 elasticore.config.ps.maxPageSize - 없으면 null
d.config("…"), d.isOn("…")도메인 규칙에서 / "true" 인가

펫스토어의 Country 는 @expose(300) 입니다. maxPageSize 를 100 으로 내리면:

[elcore3] the model check failed (1) - fix these and build again:
[ps] Country pages 300 rows at a time (@expose(300)); the team maximum is ps.maxPageSize=100.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':elcore3'.
> Process 'command '…\java.exe'' finished with non-zero exit value 1

500 으로 두면 통과합니다. 실패해도 생성은 끝까지 돌기 때문에, 여러 엔티티의 문제가 한 번에 보입니다. 이미 만들어진 파일 중 DSL 이 더 이상 만들지 않는 것은 검사가 통과할 때까지 지우지 않습니다.

예외를 던지지 마세요​

규칙 안에서 예외가 나면 그 규칙이 쓰던 파일 하나만 실패(ERROR)로 남고 나머지는 생성된 뒤 종료 코드 1 로 끝납니다. 어느 파일이 왜 빠졌는지 찾기 어렵습니다. 모델의 문제는 ModelCheck.fail 로, 규칙이 다룰 수 없는 경우는 return 으로.

테스트에서​

    @Test
void aPageAboveTheTeamMaximumFails() {
EntitySpec country = new EntitySpec("Country").domain("petstore", "Petstore").meta("root", "")
.meta("expose", "300").config("ps.maxPageSize", "100")
.field("isoCode", "string(2) @id");
engine().run(country, "entity");
assertEquals(1, ModelCheck.failures().size());
}

@AfterEach
void forget() {
ModelCheck.reset(); // failures are kept per JVM: reset between tests
}

ModelCheck.failures() 는 실패만 모읍니다. 경고는 콘솔에 출력되므로, 경고를 테스트하려면 System.out 을 잡아서 봅니다. 자세한 것은 테스트.