refactor: extract shared Texts, Jsons, and SqlBindings helpers
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,18 +8,12 @@ public record ActionExecution(String id, String instanceId, String stepId, Strin
|
|||||||
ActionExecutionStatus status, String errorMessage, Instant startedAt,
|
ActionExecutionStatus status, String errorMessage, Instant startedAt,
|
||||||
Instant finishedAt) {
|
Instant finishedAt) {
|
||||||
public ActionExecution {
|
public ActionExecution {
|
||||||
requireText(id, "id");
|
Texts.requireText(id, "id");
|
||||||
requireText(instanceId, "instanceId");
|
Texts.requireText(instanceId, "instanceId");
|
||||||
requireText(stepId, "stepId");
|
Texts.requireText(stepId, "stepId");
|
||||||
requireText(actionKey, "actionKey");
|
Texts.requireText(actionKey, "actionKey");
|
||||||
Objects.requireNonNull(status, "status must not be null");
|
Objects.requireNonNull(status, "status must not be null");
|
||||||
Objects.requireNonNull(startedAt, "startedAt must not be null");
|
Objects.requireNonNull(startedAt, "startedAt must not be null");
|
||||||
errorMessage = errorMessage == null || errorMessage.isBlank() ? null : errorMessage.strip();
|
errorMessage = Texts.blankToNull(errorMessage);
|
||||||
}
|
|
||||||
|
|
||||||
private static void requireText(String value, String name) {
|
|
||||||
if (value == null || value.isBlank()) {
|
|
||||||
throw new IllegalArgumentException(name + " must not be blank");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import java.util.Set;
|
|||||||
public record ApprovalStep(String id, String name, List<String> candidates, ApprovalPolicy policy, StepKind kind,
|
public record ApprovalStep(String id, String name, List<String> candidates, ApprovalPolicy policy, StepKind kind,
|
||||||
String actionKey, StepDue due) {
|
String actionKey, StepDue due) {
|
||||||
public ApprovalStep {
|
public ApprovalStep {
|
||||||
requireText(id, "step id");
|
Texts.requireText(id, "step id");
|
||||||
requireText(name, "step name");
|
Texts.requireText(name, "step name");
|
||||||
kind = kind == null ? StepKind.APPROVAL : kind;
|
kind = kind == null ? StepKind.APPROVAL : kind;
|
||||||
Objects.requireNonNull(policy, "policy must not be null");
|
Objects.requireNonNull(policy, "policy must not be null");
|
||||||
Objects.requireNonNull(candidates, "candidates must not be null");
|
Objects.requireNonNull(candidates, "candidates must not be null");
|
||||||
@@ -22,7 +22,7 @@ public record ApprovalStep(String id, String name, List<String> candidates, Appr
|
|||||||
if (!candidates.isEmpty()) {
|
if (!candidates.isEmpty()) {
|
||||||
throw new IllegalArgumentException("an action step must not have candidates");
|
throw new IllegalArgumentException("an action step must not have candidates");
|
||||||
}
|
}
|
||||||
requireText(actionKey, "action key");
|
Texts.requireText(actionKey, "action key");
|
||||||
actionKey = actionKey.strip();
|
actionKey = actionKey.strip();
|
||||||
if (due != null) {
|
if (due != null) {
|
||||||
throw new IllegalArgumentException("an action step must not have due");
|
throw new IllegalArgumentException("an action step must not have due");
|
||||||
@@ -37,7 +37,7 @@ public record ApprovalStep(String id, String name, List<String> candidates, Appr
|
|||||||
}
|
}
|
||||||
Set<String> distinct = new HashSet<>();
|
Set<String> distinct = new HashSet<>();
|
||||||
for (String candidate : candidates) {
|
for (String candidate : candidates) {
|
||||||
requireText(candidate, "candidate");
|
Texts.requireText(candidate, "candidate");
|
||||||
if (!distinct.add(candidate)) {
|
if (!distinct.add(candidate)) {
|
||||||
throw new IllegalArgumentException("duplicate candidate in step " + id + ": " + candidate);
|
throw new IllegalArgumentException("duplicate candidate in step " + id + ": " + candidate);
|
||||||
}
|
}
|
||||||
@@ -62,10 +62,4 @@ public record ApprovalStep(String id, String name, List<String> candidates, Appr
|
|||||||
public static ApprovalStep action(String id, String name, String actionKey) {
|
public static ApprovalStep action(String id, String name, String actionKey) {
|
||||||
return new ApprovalStep(id, name, List.of(), ApprovalPolicy.ANY, StepKind.ACTION, actionKey);
|
return new ApprovalStep(id, name, List.of(), ApprovalPolicy.ANY, StepKind.ACTION, actionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void requireText(String value, String field) {
|
|
||||||
if (value == null || value.isBlank()) {
|
|
||||||
throw new IllegalArgumentException(field + " must not be blank");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.jetlumen.ordo.api;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
/** Shared Jackson mappers. */
|
||||||
|
public final class Jsons {
|
||||||
|
public static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
public static final ObjectMapper NON_NULL = new ObjectMapper()
|
||||||
|
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
|
|
||||||
|
private Jsons() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,9 +29,9 @@ public interface OrdoCatalog {
|
|||||||
|
|
||||||
record Param(String name, String type, String label) {
|
record Param(String name, String type, String label) {
|
||||||
public Param {
|
public Param {
|
||||||
ApprovalStep.requireText(name, "param name");
|
Texts.requireText(name, "param name");
|
||||||
ApprovalStep.requireText(type, "param type");
|
Texts.requireText(type, "param type");
|
||||||
ApprovalStep.requireText(label, "param label");
|
Texts.requireText(label, "param label");
|
||||||
type = type.strip().toLowerCase(Locale.ROOT);
|
type = type.strip().toLowerCase(Locale.ROOT);
|
||||||
if (!PARAM_TYPES.contains(type)) {
|
if (!PARAM_TYPES.contains(type)) {
|
||||||
throw new IllegalArgumentException("param type must be number, string or boolean");
|
throw new IllegalArgumentException("param type must be number, string or boolean");
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import java.util.Set;
|
|||||||
public record ProcessDefinition(String id, int version, String name, List<ApprovalStep> steps,
|
public record ProcessDefinition(String id, int version, String name, List<ApprovalStep> steps,
|
||||||
List<StepTransition> transitions) {
|
List<StepTransition> transitions) {
|
||||||
public ProcessDefinition {
|
public ProcessDefinition {
|
||||||
ApprovalStep.requireText(id, "definition id");
|
Texts.requireText(id, "definition id");
|
||||||
if (version < 0) {
|
if (version < 0) {
|
||||||
throw new IllegalArgumentException("definition version must not be negative");
|
throw new IllegalArgumentException("definition version must not be negative");
|
||||||
}
|
}
|
||||||
ApprovalStep.requireText(name, "definition name");
|
Texts.requireText(name, "definition name");
|
||||||
steps = List.copyOf(steps);
|
steps = List.copyOf(steps);
|
||||||
if (steps.isEmpty()) {
|
if (steps.isEmpty()) {
|
||||||
throw new IllegalArgumentException("a definition must contain at least one step");
|
throw new IllegalArgumentException("a definition must contain at least one step");
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.jetlumen.ordo.api;
|
package com.jetlumen.ordo.api;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
@@ -17,8 +16,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
/** Parses a structural JSON process graph into a {@link ProcessDefinition}. */
|
/** Parses a structural JSON process graph into a {@link ProcessDefinition}. */
|
||||||
public final class ProcessDefinitionParser {
|
public final class ProcessDefinitionParser {
|
||||||
private static final ObjectMapper MAPPER = new ObjectMapper()
|
private static final ObjectMapper MAPPER = Jsons.NON_NULL;
|
||||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
|
||||||
|
|
||||||
private ProcessDefinitionParser() {
|
private ProcessDefinitionParser() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,23 +7,13 @@ import java.util.Objects;
|
|||||||
public record ProcessEvent(String id, String instanceId, String taskId, String stepId, ProcessEventType type,
|
public record ProcessEvent(String id, String instanceId, String taskId, String stepId, ProcessEventType type,
|
||||||
String actor, String detail, Instant occurredAt) {
|
String actor, String detail, Instant occurredAt) {
|
||||||
public ProcessEvent {
|
public ProcessEvent {
|
||||||
requireText(id, "id");
|
Texts.requireText(id, "id");
|
||||||
requireText(instanceId, "instanceId");
|
Texts.requireText(instanceId, "instanceId");
|
||||||
Objects.requireNonNull(type, "type must not be null");
|
Objects.requireNonNull(type, "type must not be null");
|
||||||
Objects.requireNonNull(occurredAt, "occurredAt must not be null");
|
Objects.requireNonNull(occurredAt, "occurredAt must not be null");
|
||||||
taskId = blankToNull(taskId);
|
taskId = Texts.blankToNull(taskId);
|
||||||
stepId = blankToNull(stepId);
|
stepId = Texts.blankToNull(stepId);
|
||||||
actor = blankToNull(actor);
|
actor = Texts.blankToNull(actor);
|
||||||
detail = blankToNull(detail);
|
detail = Texts.blankToNull(detail);
|
||||||
}
|
|
||||||
|
|
||||||
private static String blankToNull(String value) {
|
|
||||||
return value == null || value.isBlank() ? null : value.strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void requireText(String value, String name) {
|
|
||||||
if (value == null || value.isBlank()) {
|
|
||||||
throw new IllegalArgumentException(name + " must not be blank");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ public sealed interface RoutingPredicate permits RoutingPredicate.Compare, Routi
|
|||||||
record Compare(Op op, String var, Object value) implements RoutingPredicate {
|
record Compare(Op op, String var, Object value) implements RoutingPredicate {
|
||||||
public Compare {
|
public Compare {
|
||||||
Objects.requireNonNull(op, "op must not be null");
|
Objects.requireNonNull(op, "op must not be null");
|
||||||
ApprovalStep.requireText(var, "var");
|
Texts.requireText(var, "var");
|
||||||
value = requireLiteral(value, "value");
|
value = requireLiteral(value, "value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record In(String var, List<Object> values) implements RoutingPredicate {
|
record In(String var, List<Object> values) implements RoutingPredicate {
|
||||||
public In {
|
public In {
|
||||||
ApprovalStep.requireText(var, "var");
|
Texts.requireText(var, "var");
|
||||||
Objects.requireNonNull(values, "values must not be null");
|
Objects.requireNonNull(values, "values must not be null");
|
||||||
if (values.isEmpty()) {
|
if (values.isEmpty()) {
|
||||||
throw new IllegalArgumentException("in values must not be empty");
|
throw new IllegalArgumentException("in values must not be empty");
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.Objects;
|
|||||||
* {@link RoutingCondition} reference with arguments.
|
* {@link RoutingCondition} reference with arguments.
|
||||||
*/
|
*/
|
||||||
public sealed interface RoutingWhen permits RoutingWhen.Predicate, RoutingWhen.Ref {
|
public sealed interface RoutingWhen permits RoutingWhen.Predicate, RoutingWhen.Ref {
|
||||||
ObjectMapper MAPPER = new ObjectMapper();
|
ObjectMapper MAPPER = Jsons.MAPPER;
|
||||||
|
|
||||||
record Predicate(RoutingPredicate tree) implements RoutingWhen {
|
record Predicate(RoutingPredicate tree) implements RoutingWhen {
|
||||||
public Predicate {
|
public Predicate {
|
||||||
@@ -25,7 +25,7 @@ public sealed interface RoutingWhen permits RoutingWhen.Predicate, RoutingWhen.R
|
|||||||
|
|
||||||
record Ref(String key, Map<String, Object> args) implements RoutingWhen {
|
record Ref(String key, Map<String, Object> args) implements RoutingWhen {
|
||||||
public Ref {
|
public Ref {
|
||||||
ApprovalStep.requireText(key, "ref");
|
Texts.requireText(key, "ref");
|
||||||
args = Map.copyOf(args == null ? Map.of() : args);
|
args = Map.copyOf(args == null ? Map.of() : args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ public record StepDue(Duration after, DueThen then, String to, String action) {
|
|||||||
throw new IllegalArgumentException("due after must be positive");
|
throw new IllegalArgumentException("due after must be positive");
|
||||||
}
|
}
|
||||||
Objects.requireNonNull(then, "due then must not be null");
|
Objects.requireNonNull(then, "due then must not be null");
|
||||||
to = blankToNull(to);
|
to = Texts.blankToNull(to);
|
||||||
action = blankToNull(action);
|
action = Texts.blankToNull(action);
|
||||||
switch (then) {
|
switch (then) {
|
||||||
case REASSIGN -> {
|
case REASSIGN -> {
|
||||||
if (to == null) {
|
if (to == null) {
|
||||||
@@ -50,7 +50,4 @@ public record StepDue(Duration after, DueThen then, String to, String action) {
|
|||||||
return new StepDue(after, DueThen.GOTO, stepId, null);
|
return new StepDue(after, DueThen.GOTO, stepId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String blankToNull(String value) {
|
|
||||||
return value == null || value.isBlank() ? null : value.strip();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package com.jetlumen.ordo.api;
|
|||||||
*/
|
*/
|
||||||
public record StepTransition(String fromStepId, String toStepId, RoutingWhen when, int priority) {
|
public record StepTransition(String fromStepId, String toStepId, RoutingWhen when, int priority) {
|
||||||
public StepTransition {
|
public StepTransition {
|
||||||
ApprovalStep.requireText(fromStepId, "fromStepId");
|
Texts.requireText(fromStepId, "fromStepId");
|
||||||
if (toStepId != null && toStepId.isBlank()) {
|
if (toStepId != null && toStepId.isBlank()) {
|
||||||
throw new IllegalArgumentException("toStepId must not be blank when present");
|
throw new IllegalArgumentException("toStepId must not be blank when present");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ import java.util.Objects;
|
|||||||
/** Immutable audit record created when an approval task is completed. */
|
/** Immutable audit record created when an approval task is completed. */
|
||||||
public record TaskAction(String actor, String comment, Instant operatedAt) {
|
public record TaskAction(String actor, String comment, Instant operatedAt) {
|
||||||
public TaskAction {
|
public TaskAction {
|
||||||
if (actor == null || actor.isBlank()) {
|
Texts.requireText(actor, "actor");
|
||||||
throw new IllegalArgumentException("actor must not be blank");
|
comment = Texts.blankToNull(comment);
|
||||||
}
|
|
||||||
comment = comment == null || comment.isBlank() ? null : comment.strip();
|
|
||||||
Objects.requireNonNull(operatedAt, "operatedAt must not be null");
|
Objects.requireNonNull(operatedAt, "operatedAt must not be null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.jetlumen.ordo.api;
|
||||||
|
|
||||||
|
/** Shared blank-string checks used by domain records and the engine. */
|
||||||
|
public final class Texts {
|
||||||
|
private Texts() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void requireText(String value, String name) {
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
throw new IllegalArgumentException(name + " must not be blank");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String blankToNull(String value) {
|
||||||
|
return value == null || value.isBlank() ? null : value.strip();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,6 +53,7 @@ import java.util.Optional;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import static com.jetlumen.ordo.api.Texts.requireText;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository-backed implementation of the approval runtime with explicit step transitions.
|
* Repository-backed implementation of the approval runtime with explicit step transitions.
|
||||||
@@ -653,12 +654,6 @@ public final class DefaultOrdoEngine implements OrdoEngine {
|
|||||||
return UUID.randomUUID().toString();
|
return UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void requireText(String value, String name) {
|
|
||||||
if (value == null || value.isBlank()) {
|
|
||||||
throw new IllegalArgumentException(name + " must not be blank");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private record PendingAction(String executionId, String actionKey, String instanceId, String stepId,
|
private record PendingAction(String executionId, String actionKey, String instanceId, String stepId,
|
||||||
ProcessContext context) {
|
ProcessContext context) {
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -2,14 +2,13 @@ package com.jetlumen.ordo.spring.rest;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.jetlumen.ordo.api.Jsons;
|
||||||
import com.jetlumen.ordo.api.ProcessDefinition;
|
import com.jetlumen.ordo.api.ProcessDefinition;
|
||||||
import com.jetlumen.ordo.api.ProcessDefinitionParser;
|
import com.jetlumen.ordo.api.ProcessDefinitionParser;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
final class DefinitionJson {
|
final class DefinitionJson {
|
||||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
||||||
private static final TypeReference<Map<String, Object>> MAP = new TypeReference<>() {
|
private static final TypeReference<Map<String, Object>> MAP = new TypeReference<>() {
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ final class DefinitionJson {
|
|||||||
|
|
||||||
static Map<String, Object> map(ProcessDefinition definition) {
|
static Map<String, Object> map(ProcessDefinition definition) {
|
||||||
try {
|
try {
|
||||||
return MAPPER.readValue(ProcessDefinitionParser.toJson(definition), MAP);
|
return Jsons.MAPPER.readValue(ProcessDefinitionParser.toJson(definition), MAP);
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
@@ -26,7 +25,7 @@ final class DefinitionJson {
|
|||||||
|
|
||||||
static String write(Map<String, Object> body) {
|
static String write(Map<String, Object> body) {
|
||||||
try {
|
try {
|
||||||
return MAPPER.writeValueAsString(body);
|
return Jsons.MAPPER.writeValueAsString(body);
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new IllegalArgumentException("invalid process definition json", e);
|
throw new IllegalArgumentException("invalid process definition json", e);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-9
@@ -10,6 +10,7 @@ import com.jetlumen.ordo.storage.jdbc.dialect.SqlDialect;
|
|||||||
import com.jetlumen.ordo.storage.jdbc.dialect.SqlDialects;
|
import com.jetlumen.ordo.storage.jdbc.dialect.SqlDialects;
|
||||||
import com.jetlumen.ordo.storage.jdbc.mapper.ApprovalStepMapper;
|
import com.jetlumen.ordo.storage.jdbc.mapper.ApprovalStepMapper;
|
||||||
import com.jetlumen.ordo.storage.jdbc.mapper.ApprovalStepMapper.StepRow;
|
import com.jetlumen.ordo.storage.jdbc.mapper.ApprovalStepMapper.StepRow;
|
||||||
|
import com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings;
|
||||||
import com.jetlumen.ordo.storage.jdbc.mapper.StepTransitionMapper;
|
import com.jetlumen.ordo.storage.jdbc.mapper.StepTransitionMapper;
|
||||||
import com.jetlumen.ordo.storage.jdbc.mapper.StepTransitionMapper.TransitionRow;
|
import com.jetlumen.ordo.storage.jdbc.mapper.StepTransitionMapper.TransitionRow;
|
||||||
|
|
||||||
@@ -345,17 +346,17 @@ public final class JdbcProcessDefinitionRepository implements ProcessDefinitionR
|
|||||||
insertStep.setString(5, step.policy().name());
|
insertStep.setString(5, step.policy().name());
|
||||||
insertStep.setInt(6, stepOrder++);
|
insertStep.setInt(6, stepOrder++);
|
||||||
insertStep.setString(7, step.kind().name());
|
insertStep.setString(7, step.kind().name());
|
||||||
insertStep.setString(8, step.actionKey());
|
SqlBindings.setString(insertStep, 8, step.actionKey());
|
||||||
if (step.due() == null) {
|
if (step.due() == null) {
|
||||||
insertStep.setString(9, null);
|
SqlBindings.setString(insertStep, 9, null);
|
||||||
insertStep.setString(10, null);
|
SqlBindings.setString(insertStep, 10, null);
|
||||||
insertStep.setString(11, null);
|
SqlBindings.setString(insertStep, 11, null);
|
||||||
insertStep.setString(12, null);
|
SqlBindings.setString(insertStep, 12, null);
|
||||||
} else {
|
} else {
|
||||||
insertStep.setString(9, step.due().after().toString());
|
insertStep.setString(9, step.due().after().toString());
|
||||||
insertStep.setString(10, step.due().then().name());
|
insertStep.setString(10, step.due().then().name());
|
||||||
insertStep.setString(11, step.due().to());
|
SqlBindings.setString(insertStep, 11, step.due().to());
|
||||||
insertStep.setString(12, step.due().action());
|
SqlBindings.setString(insertStep, 12, step.due().action());
|
||||||
}
|
}
|
||||||
insertStep.executeUpdate();
|
insertStep.executeUpdate();
|
||||||
}
|
}
|
||||||
@@ -376,8 +377,8 @@ public final class JdbcProcessDefinitionRepository implements ProcessDefinitionR
|
|||||||
insertTransition.setString(1, definition.id());
|
insertTransition.setString(1, definition.id());
|
||||||
insertTransition.setInt(2, definition.version());
|
insertTransition.setInt(2, definition.version());
|
||||||
insertTransition.setString(3, transition.fromStepId());
|
insertTransition.setString(3, transition.fromStepId());
|
||||||
insertTransition.setString(4, transition.toStepId());
|
SqlBindings.setString(insertTransition, 4, transition.toStepId());
|
||||||
insertTransition.setString(5, transition.when() == null ? null : transition.when().toJson());
|
SqlBindings.setString(insertTransition, 5, transition.when() == null ? null : transition.when().toJson());
|
||||||
insertTransition.setInt(6, transition.priority());
|
insertTransition.setInt(6, transition.priority());
|
||||||
insertTransition.executeUpdate();
|
insertTransition.executeUpdate();
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-13
@@ -6,8 +6,11 @@ import com.jetlumen.ordo.api.ActionExecutionStatus;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.time.Instant;
|
||||||
import java.sql.Types;
|
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.getInstant;
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.setBlankAsNull;
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.setInstant;
|
||||||
|
|
||||||
/** Maps rows of {@code ordo_action_execution} to {@link ActionExecution} objects and back. */
|
/** Maps rows of {@code ordo_action_execution} to {@link ActionExecution} objects and back. */
|
||||||
public final class ActionExecutionMapper {
|
public final class ActionExecutionMapper {
|
||||||
@@ -20,11 +23,10 @@ public final class ActionExecutionMapper {
|
|||||||
statement.setString(3, execution.stepId());
|
statement.setString(3, execution.stepId());
|
||||||
statement.setString(4, execution.actionKey());
|
statement.setString(4, execution.actionKey());
|
||||||
statement.setString(5, execution.status().name());
|
statement.setString(5, execution.status().name());
|
||||||
statement.setTimestamp(6, Timestamp.from(execution.startedAt()));
|
setInstant(statement, 6, execution.startedAt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ActionExecution read(ResultSet resultSet) throws SQLException {
|
public static ActionExecution read(ResultSet resultSet) throws SQLException {
|
||||||
Timestamp finishedAt = resultSet.getTimestamp("finished_at");
|
|
||||||
return new ActionExecution(
|
return new ActionExecution(
|
||||||
resultSet.getString("id"),
|
resultSet.getString("id"),
|
||||||
resultSet.getString("instance_id"),
|
resultSet.getString("instance_id"),
|
||||||
@@ -32,19 +34,15 @@ public final class ActionExecutionMapper {
|
|||||||
resultSet.getString("action_key"),
|
resultSet.getString("action_key"),
|
||||||
ActionExecutionStatus.valueOf(resultSet.getString("status")),
|
ActionExecutionStatus.valueOf(resultSet.getString("status")),
|
||||||
resultSet.getString("error_message"),
|
resultSet.getString("error_message"),
|
||||||
resultSet.getTimestamp("started_at").toInstant(),
|
getInstant(resultSet, "started_at"),
|
||||||
finishedAt == null ? null : finishedAt.toInstant());
|
getInstant(resultSet, "finished_at"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bindComplete(PreparedStatement statement, String executionId, ActionExecutionStatus status,
|
public static void bindComplete(PreparedStatement statement, String executionId, ActionExecutionStatus status,
|
||||||
String errorMessage, java.time.Instant finishedAt) throws SQLException {
|
String errorMessage, Instant finishedAt) throws SQLException {
|
||||||
statement.setString(1, status.name());
|
statement.setString(1, status.name());
|
||||||
if (errorMessage == null || errorMessage.isBlank()) {
|
setBlankAsNull(statement, 2, errorMessage);
|
||||||
statement.setNull(2, Types.VARCHAR);
|
setInstant(statement, 3, finishedAt);
|
||||||
} else {
|
|
||||||
statement.setString(2, errorMessage);
|
|
||||||
}
|
|
||||||
statement.setTimestamp(3, Timestamp.from(finishedAt));
|
|
||||||
statement.setString(4, executionId);
|
statement.setString(4, executionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-21
@@ -7,8 +7,10 @@ import com.jetlumen.ordo.api.TaskStatus;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.sql.Types;
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.getInstant;
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.setInstant;
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.setString;
|
||||||
|
|
||||||
/** Maps rows of {@code ordo_approval_task} to {@link ApprovalTask} objects and back. */
|
/** Maps rows of {@code ordo_approval_task} to {@link ApprovalTask} objects and back. */
|
||||||
public final class ApprovalTaskMapper {
|
public final class ApprovalTaskMapper {
|
||||||
@@ -22,27 +24,23 @@ public final class ApprovalTaskMapper {
|
|||||||
statement.setString(4, task.name());
|
statement.setString(4, task.name());
|
||||||
statement.setString(5, task.assignee());
|
statement.setString(5, task.assignee());
|
||||||
statement.setString(6, task.status().name());
|
statement.setString(6, task.status().name());
|
||||||
statement.setTimestamp(7, Timestamp.from(task.createdAt()));
|
setInstant(statement, 7, task.createdAt());
|
||||||
if (task.dueAt() == null) {
|
setInstant(statement, 8, task.dueAt());
|
||||||
statement.setNull(8, Types.TIMESTAMP);
|
|
||||||
} else {
|
|
||||||
statement.setTimestamp(8, Timestamp.from(task.dueAt()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bindComplete(PreparedStatement statement, ApprovalTask completedTask) throws SQLException {
|
public static void bindComplete(PreparedStatement statement, ApprovalTask completedTask) throws SQLException {
|
||||||
TaskAction action = completedTask.action();
|
TaskAction action = completedTask.action();
|
||||||
statement.setString(1, completedTask.status().name());
|
statement.setString(1, completedTask.status().name());
|
||||||
statement.setTimestamp(2, Timestamp.from(completedTask.completedAt()));
|
setInstant(statement, 2, completedTask.completedAt());
|
||||||
if (action == null) {
|
if (action == null) {
|
||||||
// SKIPPED tasks have no actor - a sibling candidate's decision already settled the step.
|
// SKIPPED tasks have no actor - a sibling candidate's decision already settled the step.
|
||||||
statement.setNull(3, Types.VARCHAR);
|
setString(statement, 3, null);
|
||||||
statement.setNull(4, Types.VARCHAR);
|
setString(statement, 4, null);
|
||||||
statement.setNull(5, Types.TIMESTAMP);
|
setInstant(statement, 5, null);
|
||||||
} else {
|
} else {
|
||||||
statement.setString(3, action.actor());
|
statement.setString(3, action.actor());
|
||||||
statement.setString(4, action.comment());
|
setString(statement, 4, action.comment());
|
||||||
statement.setTimestamp(5, Timestamp.from(action.operatedAt()));
|
setInstant(statement, 5, action.operatedAt());
|
||||||
}
|
}
|
||||||
statement.setString(6, completedTask.id());
|
statement.setString(6, completedTask.id());
|
||||||
statement.setString(7, completedTask.assignee());
|
statement.setString(7, completedTask.assignee());
|
||||||
@@ -50,11 +48,8 @@ public final class ApprovalTaskMapper {
|
|||||||
|
|
||||||
public static ApprovalTask read(ResultSet resultSet) throws SQLException {
|
public static ApprovalTask read(ResultSet resultSet) throws SQLException {
|
||||||
String actionActor = resultSet.getString("action_actor");
|
String actionActor = resultSet.getString("action_actor");
|
||||||
Timestamp actionAt = resultSet.getTimestamp("action_at");
|
|
||||||
TaskAction action = actionActor == null ? null
|
TaskAction action = actionActor == null ? null
|
||||||
: new TaskAction(actionActor, resultSet.getString("action_comment"), actionAt.toInstant());
|
: new TaskAction(actionActor, resultSet.getString("action_comment"), getInstant(resultSet, "action_at"));
|
||||||
Timestamp completedAt = resultSet.getTimestamp("completed_at");
|
|
||||||
Timestamp dueAt = resultSet.getTimestamp("due_at");
|
|
||||||
return new ApprovalTask(
|
return new ApprovalTask(
|
||||||
resultSet.getString("id"),
|
resultSet.getString("id"),
|
||||||
resultSet.getString("instance_id"),
|
resultSet.getString("instance_id"),
|
||||||
@@ -62,9 +57,9 @@ public final class ApprovalTaskMapper {
|
|||||||
resultSet.getString("task_name"),
|
resultSet.getString("task_name"),
|
||||||
resultSet.getString("assignee"),
|
resultSet.getString("assignee"),
|
||||||
TaskStatus.valueOf(resultSet.getString("status")),
|
TaskStatus.valueOf(resultSet.getString("status")),
|
||||||
resultSet.getTimestamp("created_at").toInstant(),
|
getInstant(resultSet, "created_at"),
|
||||||
completedAt == null ? null : completedAt.toInstant(),
|
getInstant(resultSet, "completed_at"),
|
||||||
action,
|
action,
|
||||||
dueAt == null ? null : dueAt.toInstant());
|
getInstant(resultSet, "due_at"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-5
@@ -2,7 +2,7 @@ package com.jetlumen.ordo.storage.jdbc.mapper;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.jetlumen.ordo.api.Jsons;
|
||||||
import com.jetlumen.ordo.api.ProcessContext;
|
import com.jetlumen.ordo.api.ProcessContext;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -13,14 +13,12 @@ import java.util.Map;
|
|||||||
* booleans, lists and nested maps.
|
* booleans, lists and nested maps.
|
||||||
*/
|
*/
|
||||||
public final class ProcessContextCodec {
|
public final class ProcessContextCodec {
|
||||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
|
||||||
|
|
||||||
private ProcessContextCodec() {
|
private ProcessContextCodec() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String encode(ProcessContext context) {
|
public static String encode(ProcessContext context) {
|
||||||
try {
|
try {
|
||||||
return OBJECT_MAPPER.writeValueAsString(context.variables());
|
return Jsons.MAPPER.writeValueAsString(context.variables());
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new IllegalStateException("failed to serialize process context to JSON", e);
|
throw new IllegalStateException("failed to serialize process context to JSON", e);
|
||||||
}
|
}
|
||||||
@@ -28,7 +26,7 @@ public final class ProcessContextCodec {
|
|||||||
|
|
||||||
public static ProcessContext decode(String json) {
|
public static ProcessContext decode(String json) {
|
||||||
try {
|
try {
|
||||||
Map<String, Object> variables = OBJECT_MAPPER.readValue(json, new TypeReference<>() {
|
Map<String, Object> variables = Jsons.MAPPER.readValue(json, new TypeReference<>() {
|
||||||
});
|
});
|
||||||
return new ProcessContext(variables);
|
return new ProcessContext(variables);
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
|
|||||||
+10
-16
@@ -6,8 +6,10 @@ import com.jetlumen.ordo.api.ProcessEventType;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.sql.Types;
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.getInstant;
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.setInstant;
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.setString;
|
||||||
|
|
||||||
/** Maps rows of {@code ordo_process_event} to {@link ProcessEvent} objects and back. */
|
/** Maps rows of {@code ordo_process_event} to {@link ProcessEvent} objects and back. */
|
||||||
public final class ProcessEventMapper {
|
public final class ProcessEventMapper {
|
||||||
@@ -17,12 +19,12 @@ public final class ProcessEventMapper {
|
|||||||
public static void bindInsert(PreparedStatement statement, ProcessEvent event) throws SQLException {
|
public static void bindInsert(PreparedStatement statement, ProcessEvent event) throws SQLException {
|
||||||
statement.setString(1, event.id());
|
statement.setString(1, event.id());
|
||||||
statement.setString(2, event.instanceId());
|
statement.setString(2, event.instanceId());
|
||||||
setNullableString(statement, 3, event.taskId());
|
setString(statement, 3, event.taskId());
|
||||||
setNullableString(statement, 4, event.stepId());
|
setString(statement, 4, event.stepId());
|
||||||
statement.setString(5, event.type().name());
|
statement.setString(5, event.type().name());
|
||||||
setNullableString(statement, 6, event.actor());
|
setString(statement, 6, event.actor());
|
||||||
setNullableString(statement, 7, event.detail());
|
setString(statement, 7, event.detail());
|
||||||
statement.setTimestamp(8, Timestamp.from(event.occurredAt()));
|
setInstant(statement, 8, event.occurredAt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProcessEvent read(ResultSet resultSet) throws SQLException {
|
public static ProcessEvent read(ResultSet resultSet) throws SQLException {
|
||||||
@@ -34,14 +36,6 @@ public final class ProcessEventMapper {
|
|||||||
ProcessEventType.valueOf(resultSet.getString("event_type")),
|
ProcessEventType.valueOf(resultSet.getString("event_type")),
|
||||||
resultSet.getString("actor"),
|
resultSet.getString("actor"),
|
||||||
resultSet.getString("detail"),
|
resultSet.getString("detail"),
|
||||||
resultSet.getTimestamp("occurred_at").toInstant());
|
getInstant(resultSet, "occurred_at"));
|
||||||
}
|
|
||||||
|
|
||||||
private static void setNullableString(PreparedStatement statement, int index, String value) throws SQLException {
|
|
||||||
if (value == null) {
|
|
||||||
statement.setNull(index, Types.VARCHAR);
|
|
||||||
} else {
|
|
||||||
statement.setString(index, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -6,7 +6,9 @@ import com.jetlumen.ordo.api.ProcessStatus;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.getInstant;
|
||||||
|
import static com.jetlumen.ordo.storage.jdbc.mapper.SqlBindings.setInstant;
|
||||||
|
|
||||||
/** Maps rows of {@code ordo_process_instance} to {@link ProcessInstance} objects and back. */
|
/** Maps rows of {@code ordo_process_instance} to {@link ProcessInstance} objects and back. */
|
||||||
public final class ProcessInstanceMapper {
|
public final class ProcessInstanceMapper {
|
||||||
@@ -20,27 +22,25 @@ public final class ProcessInstanceMapper {
|
|||||||
statement.setString(4, instance.initiator());
|
statement.setString(4, instance.initiator());
|
||||||
statement.setString(5, instance.status().name());
|
statement.setString(5, instance.status().name());
|
||||||
statement.setString(6, ProcessContextCodec.encode(instance.context()));
|
statement.setString(6, ProcessContextCodec.encode(instance.context()));
|
||||||
statement.setTimestamp(7, Timestamp.from(instance.startedAt()));
|
setInstant(statement, 7, instance.startedAt());
|
||||||
statement.setTimestamp(8, instance.finishedAt() == null ? null : Timestamp.from(instance.finishedAt()));
|
setInstant(statement, 8, instance.finishedAt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bindUpdate(PreparedStatement statement, ProcessInstance instance) throws SQLException {
|
public static void bindUpdate(PreparedStatement statement, ProcessInstance instance) throws SQLException {
|
||||||
statement.setString(1, instance.status().name());
|
statement.setString(1, instance.status().name());
|
||||||
statement.setTimestamp(2, instance.finishedAt() == null ? null : Timestamp.from(instance.finishedAt()));
|
setInstant(statement, 2, instance.finishedAt());
|
||||||
statement.setString(3, instance.id());
|
statement.setString(3, instance.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProcessInstance read(ResultSet resultSet) throws SQLException {
|
public static ProcessInstance read(ResultSet resultSet) throws SQLException {
|
||||||
Timestamp startedAt = resultSet.getTimestamp("started_at");
|
|
||||||
Timestamp finishedAt = resultSet.getTimestamp("finished_at");
|
|
||||||
return new ProcessInstance(
|
return new ProcessInstance(
|
||||||
resultSet.getString("id"),
|
resultSet.getString("id"),
|
||||||
resultSet.getString("definition_id"),
|
resultSet.getString("definition_id"),
|
||||||
resultSet.getInt("definition_version"),
|
resultSet.getInt("definition_version"),
|
||||||
resultSet.getString("initiator"),
|
resultSet.getString("initiator"),
|
||||||
ProcessStatus.valueOf(resultSet.getString("status")),
|
ProcessStatus.valueOf(resultSet.getString("status")),
|
||||||
startedAt.toInstant(),
|
getInstant(resultSet, "started_at"),
|
||||||
finishedAt == null ? null : finishedAt.toInstant(),
|
getInstant(resultSet, "finished_at"),
|
||||||
ProcessContextCodec.decode(resultSet.getString("context_json")));
|
ProcessContextCodec.decode(resultSet.getString("context_json")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package com.jetlumen.ordo.storage.jdbc.mapper;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
/** Nullable JDBC parameter and column helpers. */
|
||||||
|
public final class SqlBindings {
|
||||||
|
private SqlBindings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setString(PreparedStatement statement, int index, String value) throws SQLException {
|
||||||
|
if (value == null) {
|
||||||
|
statement.setNull(index, Types.VARCHAR);
|
||||||
|
} else {
|
||||||
|
statement.setString(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBlankAsNull(PreparedStatement statement, int index, String value) throws SQLException {
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
statement.setNull(index, Types.VARCHAR);
|
||||||
|
} else {
|
||||||
|
statement.setString(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setInstant(PreparedStatement statement, int index, Instant value) throws SQLException {
|
||||||
|
if (value == null) {
|
||||||
|
statement.setNull(index, Types.TIMESTAMP);
|
||||||
|
} else {
|
||||||
|
statement.setTimestamp(index, Timestamp.from(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instant getInstant(ResultSet resultSet, String column) throws SQLException {
|
||||||
|
Timestamp timestamp = resultSet.getTimestamp(column);
|
||||||
|
return timestamp == null ? null : timestamp.toInstant();
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-18
@@ -66,8 +66,8 @@ class JdbcMysqlIntegrationTest {
|
|||||||
reachabilityProblem = e.getMessage();
|
reachabilityProblem = e.getMessage();
|
||||||
}
|
}
|
||||||
Assumptions.assumeTrue(reachabilityProblem == null,
|
Assumptions.assumeTrue(reachabilityProblem == null,
|
||||||
"MySQL not reachable at " + config("ordo.test.mysql.host", "ORDO_TEST_MYSQL_HOST", "localhost")
|
"MySQL not reachable at " + JdbcTestSupport.config("ordo.test.mysql.host", "ORDO_TEST_MYSQL_HOST", "localhost")
|
||||||
+ ":" + config("ordo.test.mysql.port", "ORDO_TEST_MYSQL_PORT", "3306")
|
+ ":" + JdbcTestSupport.config("ordo.test.mysql.port", "ORDO_TEST_MYSQL_PORT", "3306")
|
||||||
+ " — skipping MySQL integration tests (" + reachabilityProblem + ")");
|
+ " — skipping MySQL integration tests (" + reachabilityProblem + ")");
|
||||||
|
|
||||||
try (Connection connection = rootDataSource.getConnection(); Statement statement = connection.createStatement()) {
|
try (Connection connection = rootDataSource.getConnection(); Statement statement = connection.createStatement()) {
|
||||||
@@ -238,28 +238,16 @@ class JdbcMysqlIntegrationTest {
|
|||||||
|
|
||||||
private static MysqlDataSource newDataSource(String database) {
|
private static MysqlDataSource newDataSource(String database) {
|
||||||
MysqlDataSource mysqlDataSource = new MysqlDataSource();
|
MysqlDataSource mysqlDataSource = new MysqlDataSource();
|
||||||
String host = config("ordo.test.mysql.host", "ORDO_TEST_MYSQL_HOST", "localhost");
|
String host = JdbcTestSupport.config("ordo.test.mysql.host", "ORDO_TEST_MYSQL_HOST", "localhost");
|
||||||
String port = config("ordo.test.mysql.port", "ORDO_TEST_MYSQL_PORT", "3306");
|
String port = JdbcTestSupport.config("ordo.test.mysql.port", "ORDO_TEST_MYSQL_PORT", "3306");
|
||||||
String databasePath = database.isEmpty() ? "/" : "/" + database;
|
String databasePath = database.isEmpty() ? "/" : "/" + database;
|
||||||
mysqlDataSource.setUrl("jdbc:mysql://" + host + ":" + port + databasePath
|
mysqlDataSource.setUrl("jdbc:mysql://" + host + ":" + port + databasePath
|
||||||
+ "?allowPublicKeyRetrieval=true&sslMode=DISABLED&characterEncoding=utf8");
|
+ "?allowPublicKeyRetrieval=true&sslMode=DISABLED&characterEncoding=utf8");
|
||||||
mysqlDataSource.setUser(config("ordo.test.mysql.user", "ORDO_TEST_MYSQL_USER", "root"));
|
mysqlDataSource.setUser(JdbcTestSupport.config("ordo.test.mysql.user", "ORDO_TEST_MYSQL_USER", "root"));
|
||||||
mysqlDataSource.setPassword(config("ordo.test.mysql.password", "ORDO_TEST_MYSQL_PASSWORD", "root"));
|
mysqlDataSource.setPassword(JdbcTestSupport.config("ordo.test.mysql.password", "ORDO_TEST_MYSQL_PASSWORD", "root"));
|
||||||
return mysqlDataSource;
|
return mysqlDataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String config(String property, String env, String defaultValue) {
|
|
||||||
String fromProperty = System.getProperty(property);
|
|
||||||
if (fromProperty != null && !fromProperty.isBlank()) {
|
|
||||||
return fromProperty;
|
|
||||||
}
|
|
||||||
String fromEnv = System.getenv(env);
|
|
||||||
if (fromEnv != null && !fromEnv.isBlank()) {
|
|
||||||
return fromEnv;
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void attempt(CountDownLatch start, CountDownLatch done, AtomicInteger wins,
|
private static void attempt(CountDownLatch start, CountDownLatch done, AtomicInteger wins,
|
||||||
ApprovalTask completed, JdbcApprovalTaskRepository repository) {
|
ApprovalTask completed, JdbcApprovalTaskRepository repository) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
+5
-17
@@ -234,29 +234,17 @@ class JdbcPostgresIntegrationTest {
|
|||||||
|
|
||||||
private static PGSimpleDataSource newDataSource(String currentSchema) {
|
private static PGSimpleDataSource newDataSource(String currentSchema) {
|
||||||
PGSimpleDataSource pgDataSource = new PGSimpleDataSource();
|
PGSimpleDataSource pgDataSource = new PGSimpleDataSource();
|
||||||
pgDataSource.setServerNames(new String[]{config("ordo.test.pg.host", "ORDO_TEST_PG_HOST", "localhost")});
|
pgDataSource.setServerNames(new String[]{JdbcTestSupport.config("ordo.test.pg.host", "ORDO_TEST_PG_HOST", "localhost")});
|
||||||
pgDataSource.setPortNumbers(new int[]{Integer.parseInt(config("ordo.test.pg.port", "ORDO_TEST_PG_PORT", "5432"))});
|
pgDataSource.setPortNumbers(new int[]{Integer.parseInt(JdbcTestSupport.config("ordo.test.pg.port", "ORDO_TEST_PG_PORT", "5432"))});
|
||||||
pgDataSource.setDatabaseName(config("ordo.test.pg.database", "ORDO_TEST_PG_DATABASE", "postgres"));
|
pgDataSource.setDatabaseName(JdbcTestSupport.config("ordo.test.pg.database", "ORDO_TEST_PG_DATABASE", "postgres"));
|
||||||
pgDataSource.setUser(config("ordo.test.pg.user", "ORDO_TEST_PG_USER", "postgres"));
|
pgDataSource.setUser(JdbcTestSupport.config("ordo.test.pg.user", "ORDO_TEST_PG_USER", "postgres"));
|
||||||
pgDataSource.setPassword(config("ordo.test.pg.password", "ORDO_TEST_PG_PASSWORD", "postgres"));
|
pgDataSource.setPassword(JdbcTestSupport.config("ordo.test.pg.password", "ORDO_TEST_PG_PASSWORD", "postgres"));
|
||||||
if (!currentSchema.isEmpty()) {
|
if (!currentSchema.isEmpty()) {
|
||||||
pgDataSource.setCurrentSchema(currentSchema);
|
pgDataSource.setCurrentSchema(currentSchema);
|
||||||
}
|
}
|
||||||
return pgDataSource;
|
return pgDataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String config(String property, String env, String defaultValue) {
|
|
||||||
String fromProperty = System.getProperty(property);
|
|
||||||
if (fromProperty != null && !fromProperty.isBlank()) {
|
|
||||||
return fromProperty;
|
|
||||||
}
|
|
||||||
String fromEnv = System.getenv(env);
|
|
||||||
if (fromEnv != null && !fromEnv.isBlank()) {
|
|
||||||
return fromEnv;
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void attempt(CountDownLatch start, CountDownLatch done, AtomicInteger wins,
|
private static void attempt(CountDownLatch start, CountDownLatch done, AtomicInteger wins,
|
||||||
ApprovalTask completed, JdbcApprovalTaskRepository repository) {
|
ApprovalTask completed, JdbcApprovalTaskRepository repository) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -30,6 +30,18 @@ final class JdbcTestSupport {
|
|||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String config(String property, String env, String defaultValue) {
|
||||||
|
String fromProperty = System.getProperty(property);
|
||||||
|
if (fromProperty != null && !fromProperty.isBlank()) {
|
||||||
|
return fromProperty;
|
||||||
|
}
|
||||||
|
String fromEnv = System.getenv(env);
|
||||||
|
if (fromEnv != null && !fromEnv.isBlank()) {
|
||||||
|
return fromEnv;
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
static void applySchema(DataSource dataSource) {
|
static void applySchema(DataSource dataSource) {
|
||||||
applySchema(dataSource, POSTGRES_BASELINE, POSTGRES_V2);
|
applySchema(dataSource, POSTGRES_BASELINE, POSTGRES_V2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user