Link expanded generic REST paths via parameter alias tracking
Follow renamed path variables through call-graph aliases, expand machineType×event bindings from branch-scoped valueOf, treat fully resolved URLs as internal, and synthesize concrete polymorphic events from path constraints for transition linking. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -57,6 +57,8 @@ public class TransitionLinkerEnricher implements AnalysisEnricher {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tp = MachineEnumCanonicalizer.expandBoundValueOfFromConstraints(
|
||||||
|
tp, machineTypes, context, chain.getEntryPoint());
|
||||||
tp = MachineEnumCanonicalizer.ensureCallChainPolymorphicEvents(
|
tp = MachineEnumCanonicalizer.ensureCallChainPolymorphicEvents(
|
||||||
tp, machineTypes, context, stateMachineTransitions, true);
|
tp, machineTypes, context, stateMachineTransitions, true);
|
||||||
tp = MachineEnumCanonicalizer.canonicalizeTriggerLabelsForLinking(tp, machineTypes, context);
|
tp = MachineEnumCanonicalizer.canonicalizeTriggerLabelsForLinking(tp, machineTypes, context);
|
||||||
@@ -207,8 +209,20 @@ public class TransitionLinkerEnricher implements AnalysisEnricher {
|
|||||||
if (constraint == null || machineName == null) {
|
if (constraint == null || machineName == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
String machineConstraint = stripEventBindingClauses(constraint);
|
||||||
return BooleanConstraintEvaluator.isCompatibleWithMachineDomain(
|
return BooleanConstraintEvaluator.isCompatibleWithMachineDomain(
|
||||||
constraint, MachineDomainKeys.extractMachineDomainKey(machineName));
|
machineConstraint, MachineDomainKeys.extractMachineDomainKey(machineName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String stripEventBindingClauses(String constraint) {
|
||||||
|
if (constraint == null || constraint.isBlank()) {
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
String stripped = constraint.replaceAll("\"[^\"]+\"\\.equalsIgnoreCase\\(event\\)", "true");
|
||||||
|
stripped = stripped.replaceAll("&&\\s*&&+", "&&");
|
||||||
|
stripped = stripped.replaceAll("^\\s*&&\\s*", "");
|
||||||
|
stripped = stripped.replaceAll("\\s*&&\\s*$", "");
|
||||||
|
return stripped.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final java.util.Map<String, String> simplifySourceCache = new java.util.HashMap<>();
|
private final java.util.Map<String, String> simplifySourceCache = new java.util.HashMap<>();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package click.kamil.springstatemachineexporter.analysis.resolver;
|
package click.kamil.springstatemachineexporter.analysis.resolver;
|
||||||
|
|
||||||
|
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||||
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||||
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
|
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
|
||||||
import click.kamil.springstatemachineexporter.model.Event;
|
import click.kamil.springstatemachineexporter.model.Event;
|
||||||
@@ -999,4 +1000,86 @@ public final class MachineEnumCanonicalizer {
|
|||||||
}
|
}
|
||||||
return simpleName(enumTypeFqn) + "." + canonicalFqn.substring(lastDot + 1);
|
return simpleName(enumTypeFqn) + "." + canonicalFqn.substring(lastDot + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When path bindings prove a single {@code event} literal (e.g. {@code "PAY".equalsIgnoreCase(event)})
|
||||||
|
* and the trigger is {@code Enum.valueOf(...)}, synthesize one concrete polymorphic event for linking.
|
||||||
|
*/
|
||||||
|
public static TriggerPoint expandBoundValueOfFromConstraints(
|
||||||
|
TriggerPoint trigger,
|
||||||
|
StateMachineTypeResolver.MachineTypes machineTypes,
|
||||||
|
CodebaseContext context) {
|
||||||
|
return expandBoundValueOfFromConstraints(trigger, machineTypes, context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TriggerPoint expandBoundValueOfFromConstraints(
|
||||||
|
TriggerPoint trigger,
|
||||||
|
StateMachineTypeResolver.MachineTypes machineTypes,
|
||||||
|
CodebaseContext context,
|
||||||
|
EntryPoint entryPoint) {
|
||||||
|
if (trigger == null || trigger.getEvent() == null || machineTypes == null) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
if (!isDynamicTriggerExpression(trigger.getEvent()) || !trigger.getEvent().contains(".valueOf(")) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
String constraint = trigger.getConstraint();
|
||||||
|
if (constraint == null || constraint.isBlank()) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
List<String> boundEventLiterals = extractBoundEventLiteralsFromConstraint(constraint);
|
||||||
|
if (boundEventLiterals.size() != 1) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
String eventTypeFqn = machineTypes.eventTypeFqn();
|
||||||
|
if (eventTypeFqn == null || eventTypeFqn.isBlank()) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
String literal = boundEventLiterals.get(0).toUpperCase();
|
||||||
|
if (entryPoint != null && entryPoint.getName() != null
|
||||||
|
&& !entryPoint.getName().toUpperCase().contains("/" + literal + "/")
|
||||||
|
&& !entryPoint.getName().toUpperCase().endsWith("/" + literal)) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
String machineTypeLiteral = extractBoundParamLiteralFromConstraint(constraint, "machineType");
|
||||||
|
if (machineTypeLiteral != null && entryPoint != null && entryPoint.getName() != null
|
||||||
|
&& !entryPoint.getName().toUpperCase().contains("/" + machineTypeLiteral.toUpperCase() + "/")) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
String constantFqn = eventTypeFqn + "." + literal;
|
||||||
|
if (context != null) {
|
||||||
|
List<String> machineEnumValues = context.getEnumValues(eventTypeFqn);
|
||||||
|
if (machineEnumValues == null || machineEnumValues.stream().noneMatch(constantFqn::equals)) {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return trigger.toBuilder()
|
||||||
|
.polymorphicEvents(List.of(constantFqn))
|
||||||
|
.ambiguous(false)
|
||||||
|
.external(false)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String extractBoundParamLiteralFromConstraint(String constraint, String paramName) {
|
||||||
|
java.util.regex.Matcher matcher = java.util.regex.Pattern
|
||||||
|
.compile("\"([^\"]+)\"\\.equalsIgnoreCase\\(" + paramName + "\\)")
|
||||||
|
.matcher(constraint);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> extractBoundEventLiteralsFromConstraint(String constraint) {
|
||||||
|
List<String> literals = new ArrayList<>();
|
||||||
|
java.util.regex.Matcher matcher = java.util.regex.Pattern
|
||||||
|
.compile("\"([^\"]+)\"\\.equalsIgnoreCase\\((\\w+)\\)")
|
||||||
|
.matcher(constraint);
|
||||||
|
while (matcher.find()) {
|
||||||
|
if ("event".equals(matcher.group(2))) {
|
||||||
|
literals.add(matcher.group(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return literals;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package click.kamil.springstatemachineexporter.analysis.service;
|
|||||||
|
|
||||||
import click.kamil.springstatemachineexporter.analysis.model.CallEdge;
|
import click.kamil.springstatemachineexporter.analysis.model.CallEdge;
|
||||||
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||||
|
import click.kamil.springstatemachineexporter.analysis.resolver.BooleanConstraintEvaluator;
|
||||||
|
import click.kamil.springstatemachineexporter.ast.common.AstUtils;
|
||||||
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
|
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
|
||||||
import org.eclipse.jdt.core.dom.*;
|
import org.eclipse.jdt.core.dom.*;
|
||||||
|
|
||||||
@@ -59,22 +61,26 @@ public final class EntryPointBindingExpander {
|
|||||||
if (isPlaceholderResolvedInPath(entryPoint, parameter.getName())) {
|
if (isPlaceholderResolvedInPath(entryPoint, parameter.getName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
List<Map<String, String>> expanded = new ArrayList<>();
|
||||||
|
for (Map<String, String> base : variants) {
|
||||||
List<String> cases = resolveBindingCasesForParameter(
|
List<String> cases = resolveBindingCasesForParameter(
|
||||||
entryPoint.getClassName() + "." + entryPoint.getMethodName(),
|
entryPoint.getClassName() + "." + entryPoint.getMethodName(),
|
||||||
parameter.getName(),
|
parameter.getName(),
|
||||||
context,
|
context,
|
||||||
callGraph);
|
callGraph,
|
||||||
|
base);
|
||||||
if (cases.isEmpty()) {
|
if (cases.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<Map<String, String>> expanded = new ArrayList<>();
|
|
||||||
for (Map<String, String> base : variants) {
|
|
||||||
for (String caseValue : cases) {
|
for (String caseValue : cases) {
|
||||||
Map<String, String> merged = new LinkedHashMap<>(base);
|
Map<String, String> merged = new LinkedHashMap<>(base);
|
||||||
merged.put(parameter.getName(), caseValue);
|
merged.put(parameter.getName(), caseValue);
|
||||||
expanded.add(merged);
|
expanded.add(merged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (expanded.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
variants = expanded;
|
variants = expanded;
|
||||||
}
|
}
|
||||||
return variants.stream().filter(map -> !map.isEmpty()).toList();
|
return variants.stream().filter(map -> !map.isEmpty()).toList();
|
||||||
@@ -270,81 +276,149 @@ public final class EntryPointBindingExpander {
|
|||||||
String startMethod,
|
String startMethod,
|
||||||
String paramName,
|
String paramName,
|
||||||
CodebaseContext context,
|
CodebaseContext context,
|
||||||
Map<String, List<CallEdge>> callGraph) {
|
Map<String, List<CallEdge>> callGraph,
|
||||||
List<String> stringCases = resolveStringCasesForParameter(startMethod, paramName, context, callGraph);
|
Map<String, String> partialBindings) {
|
||||||
|
List<String> stringCases = resolveCasesWithParameterAliases(
|
||||||
|
startMethod, paramName, context, callGraph, partialBindings,
|
||||||
|
EntryPointBindingExpander::extractStringSwitchCasesForBindings);
|
||||||
if (!stringCases.isEmpty()) {
|
if (!stringCases.isEmpty()) {
|
||||||
return stringCases;
|
return stringCases;
|
||||||
}
|
}
|
||||||
return resolveEnumValueOfCasesForParameter(startMethod, paramName, context, callGraph);
|
return resolveCasesWithParameterAliases(
|
||||||
|
startMethod, paramName, context, callGraph, partialBindings,
|
||||||
|
EntryPointBindingExpander::extractEnumValueOfCasesForBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> resolveStringCasesForParameter(
|
@FunctionalInterface
|
||||||
String startMethod,
|
private interface ParameterCaseExtractor {
|
||||||
|
List<String> extract(
|
||||||
|
String methodFqn,
|
||||||
String paramName,
|
String paramName,
|
||||||
CodebaseContext context,
|
CodebaseContext context,
|
||||||
Map<String, List<CallEdge>> callGraph) {
|
Map<String, String> partialBindings);
|
||||||
ArrayDeque<String> queue = new ArrayDeque<>();
|
}
|
||||||
|
|
||||||
|
private static List<String> extractStringSwitchCasesForBindings(
|
||||||
|
String methodFqn,
|
||||||
|
String paramName,
|
||||||
|
CodebaseContext context,
|
||||||
|
Map<String, String> partialBindings) {
|
||||||
|
return extractStringSwitchCases(methodFqn, paramName, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> extractEnumValueOfCasesForBindings(
|
||||||
|
String methodFqn,
|
||||||
|
String paramName,
|
||||||
|
CodebaseContext context,
|
||||||
|
Map<String, String> partialBindings) {
|
||||||
|
return extractEnumValueOfCases(methodFqn, paramName, context, partialBindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record ParameterAliasState(String methodFqn, String paramName) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> resolveCasesWithParameterAliases(
|
||||||
|
String startMethod,
|
||||||
|
String entryParamName,
|
||||||
|
CodebaseContext context,
|
||||||
|
Map<String, List<CallEdge>> callGraph,
|
||||||
|
Map<String, String> partialBindings,
|
||||||
|
ParameterCaseExtractor extractor) {
|
||||||
|
ArrayDeque<ParameterAliasState> queue = new ArrayDeque<>();
|
||||||
Set<String> visited = new HashSet<>();
|
Set<String> visited = new HashSet<>();
|
||||||
queue.add(startMethod);
|
queue.add(new ParameterAliasState(startMethod, entryParamName));
|
||||||
while (!queue.isEmpty()) {
|
while (!queue.isEmpty()) {
|
||||||
String methodFqn = queue.poll();
|
ParameterAliasState state = queue.poll();
|
||||||
if (!visited.add(methodFqn)) {
|
String visitKey = state.methodFqn() + "#" + state.paramName();
|
||||||
|
if (!visited.add(visitKey)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (visited.size() > 12) {
|
if (visited.size() > 24) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
List<String> localCases = extractStringSwitchCases(methodFqn, paramName, context);
|
List<String> localCases = extractor.extract(
|
||||||
|
state.methodFqn(), state.paramName(), context, partialBindings);
|
||||||
if (!localCases.isEmpty()) {
|
if (!localCases.isEmpty()) {
|
||||||
return localCases;
|
return localCases;
|
||||||
}
|
}
|
||||||
List<CallEdge> edges = callGraph.get(methodFqn);
|
enqueueParameterAliasSuccessors(state, context, callGraph, partialBindings, queue);
|
||||||
if (edges == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (CallEdge edge : edges) {
|
|
||||||
if (edge.getTargetMethod() != null) {
|
|
||||||
queue.add(edge.getTargetMethod());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> resolveEnumValueOfCasesForParameter(
|
private static void enqueueParameterAliasSuccessors(
|
||||||
String startMethod,
|
ParameterAliasState state,
|
||||||
String paramName,
|
|
||||||
CodebaseContext context,
|
CodebaseContext context,
|
||||||
Map<String, List<CallEdge>> callGraph) {
|
Map<String, List<CallEdge>> callGraph,
|
||||||
ArrayDeque<String> queue = new ArrayDeque<>();
|
Map<String, String> partialBindings,
|
||||||
Set<String> visited = new HashSet<>();
|
ArrayDeque<ParameterAliasState> queue) {
|
||||||
queue.add(startMethod);
|
List<CallEdge> edges = callGraph.get(state.methodFqn());
|
||||||
while (!queue.isEmpty()) {
|
|
||||||
String methodFqn = queue.poll();
|
|
||||||
if (!visited.add(methodFqn)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (visited.size() > 12) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
List<String> localCases = extractEnumValueOfCases(methodFqn, paramName, context);
|
|
||||||
if (!localCases.isEmpty()) {
|
|
||||||
return localCases;
|
|
||||||
}
|
|
||||||
List<CallEdge> edges = callGraph.get(methodFqn);
|
|
||||||
if (edges == null) {
|
if (edges == null) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
for (CallEdge edge : edges) {
|
for (CallEdge edge : edges) {
|
||||||
if (edge.getTargetMethod() != null) {
|
if (edge.getTargetMethod() == null || !isEdgeCompatibleWithBindings(edge, partialBindings)) {
|
||||||
queue.add(edge.getTargetMethod());
|
continue;
|
||||||
|
}
|
||||||
|
List<String> args = edge.getArguments();
|
||||||
|
if (args == null || args.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<String> targetParamNames = getParameterNames(edge.getTargetMethod(), context);
|
||||||
|
if (targetParamNames == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int limit = Math.min(args.size(), targetParamNames.size());
|
||||||
|
for (int i = 0; i < limit; i++) {
|
||||||
|
if (!argumentForwardsParameter(args.get(i), state.paramName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
queue.add(new ParameterAliasState(edge.getTargetMethod(), targetParamNames.get(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<String> extractEnumValueOfCases(String methodFqn, String paramName, CodebaseContext context) {
|
private static boolean isEdgeCompatibleWithBindings(CallEdge edge, Map<String, String> partialBindings) {
|
||||||
|
if (partialBindings == null || partialBindings.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String constraint = edge.getConstraint();
|
||||||
|
if (constraint == null || constraint.isBlank()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return BooleanConstraintEvaluator.isCompatibleWithBindings(constraint, partialBindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean argumentForwardsParameter(String argument, String paramName) {
|
||||||
|
if (argument == null || paramName == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String trimmed = argument.trim();
|
||||||
|
if (paramName.equals(trimmed)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return ("this." + paramName).equals(trimmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> getParameterNames(String methodFqn, CodebaseContext context) {
|
||||||
|
MethodDeclaration method = findMethodDeclaration(methodFqn, context);
|
||||||
|
if (method == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
for (Object paramObj : method.parameters()) {
|
||||||
|
if (paramObj instanceof SingleVariableDeclaration param) {
|
||||||
|
names.add(param.getName().getIdentifier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<String> extractEnumValueOfCases(
|
||||||
|
String methodFqn,
|
||||||
|
String paramName,
|
||||||
|
CodebaseContext context,
|
||||||
|
Map<String, String> partialBindings) {
|
||||||
MethodDeclaration method = findMethodDeclaration(methodFqn, context);
|
MethodDeclaration method = findMethodDeclaration(methodFqn, context);
|
||||||
if (method == null || method.getBody() == null || context == null) {
|
if (method == null || method.getBody() == null || context == null) {
|
||||||
return List.of();
|
return List.of();
|
||||||
@@ -363,6 +437,9 @@ public final class EntryPointBindingExpander {
|
|||||||
if (!argumentReferencesParameter(argument, paramName)) {
|
if (!argumentReferencesParameter(argument, paramName)) {
|
||||||
return super.visit(node);
|
return super.visit(node);
|
||||||
}
|
}
|
||||||
|
if (!isValueOfSiteCompatibleWithBindings(node, partialBindings)) {
|
||||||
|
return super.visit(node);
|
||||||
|
}
|
||||||
String enumType = resolveValueOfEnumType(node, context);
|
String enumType = resolveValueOfEnumType(node, context);
|
||||||
if (enumType != null) {
|
if (enumType != null) {
|
||||||
enumTypes.add(enumType);
|
enumTypes.add(enumType);
|
||||||
@@ -388,6 +465,19 @@ public final class EntryPointBindingExpander {
|
|||||||
return List.copyOf(pathValues);
|
return List.copyOf(pathValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isValueOfSiteCompatibleWithBindings(
|
||||||
|
MethodInvocation valueOfInvocation,
|
||||||
|
Map<String, String> partialBindings) {
|
||||||
|
if (partialBindings == null || partialBindings.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String branchConstraint = AstUtils.findConditionConstraint(valueOfInvocation);
|
||||||
|
if (branchConstraint == null || branchConstraint.isBlank()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return BooleanConstraintEvaluator.isCompatibleWithBindings(branchConstraint, partialBindings);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean argumentReferencesParameter(Expression argument, String paramName) {
|
private static boolean argumentReferencesParameter(Expression argument, String paramName) {
|
||||||
if (argument instanceof SimpleName simpleName) {
|
if (argument instanceof SimpleName simpleName) {
|
||||||
return paramName.equals(simpleName.getIdentifier());
|
return paramName.equals(simpleName.getIdentifier());
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ public final class ExternalTriggerPolicy {
|
|||||||
RestParamBinding binding = findRestParameterBinding(entryPoint, paramName, context);
|
RestParamBinding binding = findRestParameterBinding(entryPoint, paramName, context);
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
if (binding.pathOrQueryVariable() && !binding.enumType()) {
|
if (binding.pathOrQueryVariable() && !binding.enumType()) {
|
||||||
|
if (binding.pathVariable() && !entryPointHasUnboundPlaceholders(entryPoint)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (binding.requestBodyEnum()) {
|
if (binding.requestBodyEnum()) {
|
||||||
@@ -81,9 +84,30 @@ public final class ExternalTriggerPolicy {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (entryPoint != null && entryPoint.getType() == EntryPoint.Type.REST
|
||||||
|
&& !entryPointHasUnboundPlaceholders(entryPoint)
|
||||||
|
&& MachineEnumCanonicalizer.isDynamicTriggerExpression(trigger.getEvent())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return trigger.isExternal();
|
return trigger.isExternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean entryPointHasUnboundPlaceholders(EntryPoint entryPoint) {
|
||||||
|
if (entryPoint == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entryPoint.getName() != null && entryPoint.getName().contains("{")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entryPoint.getMetadata() != null) {
|
||||||
|
String path = entryPoint.getMetadata().get("path");
|
||||||
|
if (path != null && path.contains("{")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static String resolveRestEventParameterName(EntryPoint entryPoint, String resolvedEventParamName) {
|
private static String resolveRestEventParameterName(EntryPoint entryPoint, String resolvedEventParamName) {
|
||||||
if (resolvedEventParamName != null && !resolvedEventParamName.isBlank()) {
|
if (resolvedEventParamName != null && !resolvedEventParamName.isBlank()) {
|
||||||
return resolvedEventParamName;
|
return resolvedEventParamName;
|
||||||
|
|||||||
@@ -437,6 +437,11 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
if (chain.getMatchedTransitions() != null && !chain.getMatchedTransitions().isEmpty()) {
|
if (chain.getMatchedTransitions() != null && !chain.getMatchedTransitions().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (chain.getLinkResolution() == click.kamil.springstatemachineexporter.analysis.model.LinkResolution.NO_MATCH
|
||||||
|
|| chain.getLinkResolution()
|
||||||
|
== click.kamil.springstatemachineexporter.analysis.model.LinkResolution.UNRESOLVED_EXTERNAL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MachineEnumCanonicalizer.TriggerEventKind eventKind =
|
MachineEnumCanonicalizer.TriggerEventKind eventKind =
|
||||||
MachineEnumCanonicalizer.classifyTriggerEvent(trigger.getEvent());
|
MachineEnumCanonicalizer.classifyTriggerEvent(trigger.getEvent());
|
||||||
|
|||||||
@@ -51,14 +51,16 @@ class EnterpriseBooleanEnumPredicateExportTest {
|
|||||||
.toList();
|
.toList();
|
||||||
assertThat(callChains).isNotEmpty();
|
assertThat(callChains).isNotEmpty();
|
||||||
|
|
||||||
JsonNode dynamicChain = callChains.stream()
|
List<JsonNode> dispatchChains = callChains.stream()
|
||||||
.filter(chain -> chain.get("methodChain").toString().contains("OrderDispatcher.dispatch"))
|
.filter(chain -> chain.get("methodChain").toString().contains("OrderDispatcher.dispatch"))
|
||||||
.findFirst()
|
.toList();
|
||||||
.orElseThrow(() -> new AssertionError("missing OrderDispatcher.dispatch chain: " + callChains));
|
assertThat(dispatchChains).isNotEmpty();
|
||||||
|
|
||||||
JsonNode trigger = dynamicChain.get("triggerPoint");
|
List<String> polyEvents = dispatchChains.stream()
|
||||||
List<String> polyEvents = StreamSupport.stream(trigger.get("polymorphicEvents").spliterator(), false)
|
.flatMap(chain -> StreamSupport.stream(
|
||||||
|
chain.get("triggerPoint").get("polymorphicEvents").spliterator(), false))
|
||||||
.map(JsonNode::asText)
|
.map(JsonNode::asText)
|
||||||
|
.distinct()
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
assertThat(polyEvents)
|
assertThat(polyEvents)
|
||||||
@@ -71,12 +73,23 @@ class EnterpriseBooleanEnumPredicateExportTest {
|
|||||||
"com.example.order.OrderEvent.SHIP");
|
"com.example.order.OrderEvent.SHIP");
|
||||||
assertThat(polyEvents.size()).isLessThan(4);
|
assertThat(polyEvents.size()).isLessThan(4);
|
||||||
|
|
||||||
List<JsonNode> matched = StreamSupport.stream(dynamicChain.get("matchedTransitions").spliterator(), false)
|
for (JsonNode dispatchChain : dispatchChains) {
|
||||||
.toList();
|
long chainMatched = StreamSupport.stream(dispatchChain.get("matchedTransitions").spliterator(), false)
|
||||||
assertThat(matched.size())
|
.count();
|
||||||
.as("matchedTransitions must not cover every transition × every enum constant")
|
assertThat(chainMatched)
|
||||||
|
.as("each dispatch chain must not cover all transitions")
|
||||||
.isLessThanOrEqualTo(transitionCount);
|
.isLessThanOrEqualTo(transitionCount);
|
||||||
Set<String> matchedEvents = matched.stream()
|
}
|
||||||
|
int matchedCount = dispatchChains.stream()
|
||||||
|
.mapToInt(chain -> StreamSupport.stream(chain.get("matchedTransitions").spliterator(), false)
|
||||||
|
.mapToInt(node -> 1)
|
||||||
|
.sum())
|
||||||
|
.sum();
|
||||||
|
assertThat(matchedCount)
|
||||||
|
.as("matchedTransitions must not cover every transition × every enum constant")
|
||||||
|
.isLessThan(transitionCount * dispatchChains.size());
|
||||||
|
Set<String> matchedEvents = dispatchChains.stream()
|
||||||
|
.flatMap(chain -> StreamSupport.stream(chain.get("matchedTransitions").spliterator(), false))
|
||||||
.map(node -> node.get("event").asText())
|
.map(node -> node.get("event").asText())
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
assertThat(matchedEvents)
|
assertThat(matchedEvents)
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package click.kamil.springstatemachineexporter.analysis.resolver;
|
||||||
|
|
||||||
|
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||||
|
import click.kamil.springstatemachineexporter.analysis.resolver.StateMachineTypeResolver.MachineTypes;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class MachineEnumCanonicalizerBoundValueOfTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExpandSingleBoundEventLiteralForValueOfTrigger() {
|
||||||
|
TriggerPoint trigger = TriggerPoint.builder()
|
||||||
|
.event("OrderEvent.valueOf(eventString.toUpperCase())")
|
||||||
|
.constraint("\"ORDER\".equalsIgnoreCase(machineType) && \"PAY\".equalsIgnoreCase(event)")
|
||||||
|
.external(true)
|
||||||
|
.build();
|
||||||
|
StateMachineTypeResolver.MachineTypes machineTypes =
|
||||||
|
new StateMachineTypeResolver.MachineTypes(
|
||||||
|
"com.example.order.OrderState",
|
||||||
|
"com.example.order.OrderEvent");
|
||||||
|
|
||||||
|
TriggerPoint expanded = MachineEnumCanonicalizer.expandBoundValueOfFromConstraints(
|
||||||
|
trigger, machineTypes, null);
|
||||||
|
|
||||||
|
assertThat(expanded.getPolymorphicEvents())
|
||||||
|
.containsExactly("com.example.order.OrderEvent.PAY");
|
||||||
|
assertThat(expanded.isExternal()).isFalse();
|
||||||
|
assertThat(expanded.isAmbiguous()).isFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,19 +10,18 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regression for REST dispatcher chains: JSON round-trip must not re-infer all transition events
|
* Regression for REST dispatcher chains: expanded concrete endpoints must not re-infer all
|
||||||
* for generic {@code {event}} endpoints.
|
* transition events; unresolved {@code {event}} templates stay external.
|
||||||
*/
|
*/
|
||||||
class EnterpriseDispatcherMatchedTransitionsRegressionTest {
|
class EnterpriseDispatcherMatchedTransitionsRegressionTest {
|
||||||
|
|
||||||
private static final String TRANSITION_ENDPOINT = "POST /api/machine/{machineType}/transition/{event}";
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void astExportGenericTransitionEndpointShouldRemainUnlinked(@TempDir Path tempDir) throws Exception {
|
void astExportExpandedTransitionEndpointsShouldNotOverLink(@TempDir Path tempDir) throws Exception {
|
||||||
Path enterprise = findProjectRoot().resolve("state_machines/state_machine_enterprise");
|
Path enterprise = findProjectRoot().resolve("state_machines/state_machine_enterprise");
|
||||||
ExportService exportService = new ExportService(List.of(new JsonExporter()));
|
ExportService exportService = new ExportService(List.of(new JsonExporter()));
|
||||||
exportService.runExporter(enterprise, tempDir, List.of("json"), true, List.of(), null, null,
|
exportService.runExporter(enterprise, tempDir, List.of("json"), true, List.of(), null, null,
|
||||||
@@ -30,25 +29,31 @@ class EnterpriseDispatcherMatchedTransitionsRegressionTest {
|
|||||||
click.kamil.springstatemachineexporter.exporter.EnumFormat.fn);
|
click.kamil.springstatemachineexporter.exporter.EnumFormat.fn);
|
||||||
|
|
||||||
JsonNode json = readMachineJson(tempDir, "OrderStateMachineConfiguration", new ObjectMapper());
|
JsonNode json = readMachineJson(tempDir, "OrderStateMachineConfiguration", new ObjectMapper());
|
||||||
JsonNode chain = findTransitionEndpointChain(json);
|
int transitionCount = json.path("transitions").size();
|
||||||
|
|
||||||
assertThat(chain.path("triggerPoint").path("external").asBoolean()).isTrue();
|
StreamSupport.stream(json.path("metadata").path("callChains").spliterator(), false)
|
||||||
assertThat(chain.path("triggerPoint").path("polymorphicEvents").isArray()).isTrue();
|
.filter(chain -> chain.path("entryPoint").path("name").asText().contains("/transition/{event}"))
|
||||||
assertThat(chain.path("triggerPoint").path("polymorphicEvents")).isEmpty();
|
.forEach(chain -> {
|
||||||
JsonNode matched = chain.path("matchedTransitions");
|
JsonNode matched = chain.path("matchedTransitions");
|
||||||
assertThat(matched.isNull() || (matched.isArray() && matched.isEmpty())).isTrue();
|
assertThat(matched.isNull() || (matched.isArray() && matched.isEmpty())).isTrue();
|
||||||
assertThat(chain.path("linkResolution").asText()).isEqualTo("UNRESOLVED_EXTERNAL");
|
assertThat(chain.path("linkResolution").asText()).isEqualTo("UNRESOLVED_EXTERNAL");
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonNode orderPay = findChainByEndpoint(json, "POST /api/machine/ORDER/transition/PAY");
|
||||||
|
assertThat(orderPay.path("linkResolution").asText()).isEqualTo("RESOLVED");
|
||||||
|
JsonNode matched = orderPay.path("matchedTransitions");
|
||||||
|
assertThat(matched.isArray()).isTrue();
|
||||||
|
assertThat(matched.size()).isLessThanOrEqualTo(transitionCount);
|
||||||
|
assertThat(matched.size()).isGreaterThan(0);
|
||||||
|
assertThat(matched.get(0).path("event").asText())
|
||||||
|
.contains("OrderEvent.PAY");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JsonNode findTransitionEndpointChain(JsonNode machineJson) {
|
private static JsonNode findChainByEndpoint(JsonNode machineJson, String endpointName) {
|
||||||
for (JsonNode chain : machineJson.path("metadata").path("callChains")) {
|
return StreamSupport.stream(machineJson.path("metadata").path("callChains").spliterator(), false)
|
||||||
String name = chain.path("entryPoint").path("name").asText();
|
.filter(chain -> endpointName.equals(chain.path("entryPoint").path("name").asText()))
|
||||||
if (TRANSITION_ENDPOINT.equals(name)
|
.findFirst()
|
||||||
|| (name.contains("/transition/{event}") && name.contains("POST /api/machine/"))) {
|
.orElseThrow(() -> new IllegalStateException("chain not found for " + endpointName));
|
||||||
return chain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("transition endpoint chain not found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JsonNode readMachineJson(Path outputDir, String configBaseName, ObjectMapper mapper)
|
private static JsonNode readMachineJson(Path outputDir, String configBaseName, ObjectMapper mapper)
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package click.kamil.springstatemachineexporter.analysis.service;
|
||||||
|
|
||||||
|
import click.kamil.springstatemachineexporter.exporter.JsonExporter;
|
||||||
|
import click.kamil.springstatemachineexporter.service.ExportService;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When path bindings prove machine type and event, expanded REST endpoints should link;
|
||||||
|
* the unresolved generic template remains external.
|
||||||
|
*/
|
||||||
|
class EnterpriseExpandedGenericEndpointLinkingTest {
|
||||||
|
|
||||||
|
private static final String ORDER_PAY = "POST /api/machine/ORDER/transition/PAY";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void astExportExpandedOrderPayEndpointShouldLink(@TempDir Path tempDir) throws Exception {
|
||||||
|
Path enterprise = findProjectRoot().resolve("state_machines/state_machine_enterprise");
|
||||||
|
ExportService exportService = new ExportService(List.of(new JsonExporter()));
|
||||||
|
exportService.runExporter(enterprise, tempDir, List.of("json"), true, List.of(), null, null,
|
||||||
|
click.kamil.springstatemachineexporter.exporter.EnumFormat.fn,
|
||||||
|
click.kamil.springstatemachineexporter.exporter.EnumFormat.fn);
|
||||||
|
|
||||||
|
JsonNode json = readMachineJson(tempDir, "OrderStateMachineConfiguration", new ObjectMapper());
|
||||||
|
|
||||||
|
JsonNode expandedPayChain = findChainByEndpoint(json, ORDER_PAY);
|
||||||
|
assertThat(expandedPayChain.path("linkResolution").asText()).isEqualTo("RESOLVED");
|
||||||
|
assertThat(expandedPayChain.path("matchedTransitions").isArray()).isTrue();
|
||||||
|
assertThat(expandedPayChain.path("matchedTransitions")).isNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonNode findChainByEndpoint(JsonNode machineJson, String endpointName) {
|
||||||
|
return StreamSupport.stream(machineJson.path("metadata").path("callChains").spliterator(), false)
|
||||||
|
.filter(chain -> endpointName.equals(chain.path("entryPoint").path("name").asText()))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new IllegalStateException("chain not found for " + endpointName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonNode readMachineJson(Path outputDir, String configBaseName, ObjectMapper mapper)
|
||||||
|
throws Exception {
|
||||||
|
Path machineDir;
|
||||||
|
try (var stream = Files.list(outputDir)) {
|
||||||
|
machineDir = stream
|
||||||
|
.filter(Files::isDirectory)
|
||||||
|
.filter(path -> path.getFileName().toString().endsWith(configBaseName))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new IllegalStateException("No output for " + configBaseName));
|
||||||
|
}
|
||||||
|
return mapper.readTree(machineDir.resolve(machineDir.getFileName() + ".json").toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Path findProjectRoot() {
|
||||||
|
Path current = Path.of(".").toAbsolutePath();
|
||||||
|
while (current != null && !Files.exists(current.resolve("settings.gradle"))) {
|
||||||
|
current = current.getParent();
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -244,4 +244,130 @@ class EntryPointBindingExpanderTest {
|
|||||||
assertThat(EntryPointBindingExpander.withResolvedPath(entryPoint, variants.get(0)).getName())
|
assertThat(EntryPointBindingExpander.withResolvedPath(entryPoint, variants.get(0)).getName())
|
||||||
.isEqualTo("POST /api/order/PAY");
|
.isEqualTo("POST /api/order/PAY");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExpandRenamedEventThroughDispatcherWhenMachineTypeIsBound(@TempDir Path tempDir) throws Exception {
|
||||||
|
String source = """
|
||||||
|
package com.example;
|
||||||
|
public class MachineController {
|
||||||
|
StateMachineDispatcher dispatcher;
|
||||||
|
public void transition(String machineType, String event) {
|
||||||
|
dispatcher.dispatch(machineType, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class StateMachineDispatcher {
|
||||||
|
void dispatch(String machineType, String eventString) {
|
||||||
|
if ("ORDER".equalsIgnoreCase(machineType)) {
|
||||||
|
fireOrder(eventString);
|
||||||
|
} else if ("DOCUMENT".equalsIgnoreCase(machineType)) {
|
||||||
|
fireDocument(eventString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void fireOrder(String eventString) {
|
||||||
|
OrderEvent.valueOf(eventString.toUpperCase());
|
||||||
|
}
|
||||||
|
void fireDocument(String eventString) {
|
||||||
|
DocumentEvent.valueOf(eventString.toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enum OrderEvent { PAY, SHIP }
|
||||||
|
enum DocumentEvent { SUBMIT, APPROVE }
|
||||||
|
""";
|
||||||
|
Files.writeString(tempDir.resolve("App.java"), source);
|
||||||
|
|
||||||
|
CodebaseContext context = new CodebaseContext();
|
||||||
|
context.setResolveBindings(true);
|
||||||
|
context.scan(tempDir);
|
||||||
|
|
||||||
|
HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);
|
||||||
|
Map<String, List<click.kamil.springstatemachineexporter.analysis.model.CallEdge>> graph = engine.buildCallGraph();
|
||||||
|
|
||||||
|
EntryPoint entryPoint = EntryPoint.builder()
|
||||||
|
.className("com.example.MachineController")
|
||||||
|
.methodName("transition")
|
||||||
|
.name("POST /api/machine/{machineType}/transition/{event}")
|
||||||
|
.parameters(List.of(
|
||||||
|
EntryPoint.Parameter.builder()
|
||||||
|
.name("machineType")
|
||||||
|
.type("String")
|
||||||
|
.annotations(List.of("PathVariable"))
|
||||||
|
.build(),
|
||||||
|
EntryPoint.Parameter.builder()
|
||||||
|
.name("event")
|
||||||
|
.type("String")
|
||||||
|
.annotations(List.of("PathVariable"))
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<Map<String, String>> variants =
|
||||||
|
EntryPointBindingExpander.expandPathVariableBindings(entryPoint, context, graph);
|
||||||
|
|
||||||
|
assertThat(variants).anySatisfy(variant -> {
|
||||||
|
assertThat(variant).containsEntry("machineType", "ORDER");
|
||||||
|
assertThat(variant.get("event")).isIn("PAY", "SHIP");
|
||||||
|
});
|
||||||
|
assertThat(EntryPointBindingExpander.withResolvedPath(
|
||||||
|
entryPoint, Map.of("machineType", "ORDER", "event", "PAY")).getName())
|
||||||
|
.isEqualTo("POST /api/machine/ORDER/transition/PAY");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExpandRenamedEventFromInlineValueOfWhenMachineTypeIsBound(@TempDir Path tempDir) throws Exception {
|
||||||
|
String source = """
|
||||||
|
package com.example;
|
||||||
|
public class MachineController {
|
||||||
|
StateMachineDispatcher dispatcher;
|
||||||
|
public void transition(String machineType, String event) {
|
||||||
|
dispatcher.dispatch(machineType, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class StateMachineDispatcher {
|
||||||
|
void dispatch(String machineType, String eventString) {
|
||||||
|
if ("ORDER".equalsIgnoreCase(machineType)) {
|
||||||
|
OrderEvent event = OrderEvent.valueOf(eventString.toUpperCase());
|
||||||
|
send(event);
|
||||||
|
} else if ("DOCUMENT".equalsIgnoreCase(machineType)) {
|
||||||
|
DocumentEvent event = DocumentEvent.valueOf(eventString.toUpperCase());
|
||||||
|
send(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void send(OrderEvent event) {}
|
||||||
|
void send(DocumentEvent event) {}
|
||||||
|
}
|
||||||
|
enum OrderEvent { PAY, SHIP }
|
||||||
|
enum DocumentEvent { SUBMIT, APPROVE }
|
||||||
|
""";
|
||||||
|
Files.writeString(tempDir.resolve("App.java"), source);
|
||||||
|
|
||||||
|
CodebaseContext context = new CodebaseContext();
|
||||||
|
context.setResolveBindings(true);
|
||||||
|
context.scan(tempDir);
|
||||||
|
|
||||||
|
HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);
|
||||||
|
Map<String, List<click.kamil.springstatemachineexporter.analysis.model.CallEdge>> graph = engine.buildCallGraph();
|
||||||
|
|
||||||
|
EntryPoint entryPoint = EntryPoint.builder()
|
||||||
|
.className("com.example.MachineController")
|
||||||
|
.methodName("transition")
|
||||||
|
.name("POST /api/machine/{machineType}/transition/{event}")
|
||||||
|
.parameters(List.of(
|
||||||
|
EntryPoint.Parameter.builder()
|
||||||
|
.name("machineType")
|
||||||
|
.type("String")
|
||||||
|
.annotations(List.of("PathVariable"))
|
||||||
|
.build(),
|
||||||
|
EntryPoint.Parameter.builder()
|
||||||
|
.name("event")
|
||||||
|
.type("String")
|
||||||
|
.annotations(List.of("PathVariable"))
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<Map<String, String>> variants =
|
||||||
|
EntryPointBindingExpander.expandPathVariableBindings(entryPoint, context, graph);
|
||||||
|
|
||||||
|
assertThat(variants.stream().anyMatch(variant ->
|
||||||
|
"ORDER".equals(variant.get("machineType"))
|
||||||
|
&& List.of("PAY", "SHIP").contains(variant.get("event")))).isTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,33 @@ class ExternalTriggerPolicyTest {
|
|||||||
entryPoint, trigger, "com.example.Api.transition", "event", context)).isFalse();
|
entryPoint, trigger, "com.example.Api.transition", "event", context)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void concreteResolvedPathVariableEndpointShouldBeInternal() {
|
||||||
|
EntryPoint entryPoint = EntryPoint.builder()
|
||||||
|
.type(EntryPoint.Type.REST)
|
||||||
|
.name("POST /api/machine/ORDER/transition/PAY")
|
||||||
|
.className("com.example.Api")
|
||||||
|
.methodName("transition")
|
||||||
|
.parameters(List.of(
|
||||||
|
EntryPoint.Parameter.builder()
|
||||||
|
.name("machineType")
|
||||||
|
.type("String")
|
||||||
|
.annotations(List.of("PathVariable"))
|
||||||
|
.build(),
|
||||||
|
EntryPoint.Parameter.builder()
|
||||||
|
.name("event")
|
||||||
|
.type("String")
|
||||||
|
.annotations(List.of("PathVariable"))
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
TriggerPoint trigger = TriggerPoint.builder()
|
||||||
|
.event("OrderEvent.valueOf(eventString.toUpperCase())")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(ExternalTriggerPolicy.isExternalFromSource(
|
||||||
|
entryPoint, trigger, "com.example.Api.transition", "event", null)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void requestBodyEnumShouldBeInternal(@TempDir Path tempDir) throws Exception {
|
void requestBodyEnumShouldBeInternal(@TempDir Path tempDir) throws Exception {
|
||||||
String source = """
|
String source = """
|
||||||
|
|||||||
@@ -169,12 +169,12 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/ORDER/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/PAY",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/ORDER/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/PAY",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -192,12 +192,12 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/DOCUMENT/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/SHIP",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/DOCUMENT/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/SHIP",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -215,12 +215,127 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/USER/transition/{event}",
|
"name" : "POST /api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/USER/transition/{event}",
|
"path" : "/api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/REGISTER",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/REGISTER",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/VERIFY",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/VERIFY",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/SUSPEND",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/SUSPEND",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -380,12 +495,12 @@
|
|||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/ORDER/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/PAY",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/ORDER/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/PAY",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -413,22 +528,65 @@
|
|||||||
"sourceState" : null,
|
"sourceState" : null,
|
||||||
"lineNumber" : 87,
|
"lineNumber" : 87,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && \"PAY\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : null,
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"linkResolution" : "NO_MATCH"
|
||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/DOCUMENT/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/SHIP",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/DOCUMENT/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/SHIP",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 87,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && \"SHIP\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -453,25 +611,123 @@
|
|||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
"sourceModule" : null,
|
"sourceModule" : null,
|
||||||
"stateMachineId" : null,
|
"stateMachineId" : null,
|
||||||
"sourceState" : null,
|
"sourceState" : "click.kamil.enterprise.machines.document.DocumentState.DRAFT",
|
||||||
"lineNumber" : 87,
|
"lineNumber" : 87,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT" ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"SUBMIT\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : [ {
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"sourceState" : "click.kamil.enterprise.machines.document.DocumentState.DRAFT",
|
||||||
|
"targetState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW",
|
||||||
|
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT"
|
||||||
|
} ],
|
||||||
|
"linkResolution" : "RESOLVED"
|
||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/USER/transition/{event}",
|
"name" : "POST /api/machine/DOCUMENT/transition/APPROVE",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/USER/transition/{event}",
|
"path" : "/api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "DocumentEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW",
|
||||||
|
"lineNumber" : 87,
|
||||||
|
"polymorphicEvents" : [ "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE" ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"APPROVE\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW",
|
||||||
|
"targetState" : "click.kamil.enterprise.machines.document.DocumentState.APPROVED",
|
||||||
|
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE"
|
||||||
|
} ],
|
||||||
|
"linkResolution" : "RESOLVED"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "DocumentEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW",
|
||||||
|
"lineNumber" : 87,
|
||||||
|
"polymorphicEvents" : [ "click.kamil.enterprise.machines.document.DocumentEvent.REJECT" ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"REJECT\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW",
|
||||||
|
"targetState" : "click.kamil.enterprise.machines.document.DocumentState.DRAFT",
|
||||||
|
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT"
|
||||||
|
} ],
|
||||||
|
"linkResolution" : "RESOLVED"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/REGISTER",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/REGISTER",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -499,13 +755,99 @@
|
|||||||
"sourceState" : null,
|
"sourceState" : null,
|
||||||
"lineNumber" : 87,
|
"lineNumber" : 87,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"REGISTER\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : null,
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/VERIFY",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/VERIFY",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "UserEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 87,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"VERIFY\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/SUSPEND",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/SUSPEND",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "UserEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 87,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"SUSPEND\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
} ],
|
} ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"default" : { }
|
"default" : { }
|
||||||
|
|||||||
@@ -131,12 +131,12 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/ORDER/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/PAY",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/ORDER/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/PAY",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -154,12 +154,12 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/DOCUMENT/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/SHIP",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/DOCUMENT/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/SHIP",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -177,12 +177,127 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/USER/transition/{event}",
|
"name" : "POST /api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/USER/transition/{event}",
|
"path" : "/api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/REGISTER",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/REGISTER",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/VERIFY",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/VERIFY",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/SUSPEND",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/SUSPEND",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -303,12 +418,12 @@
|
|||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/ORDER/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/PAY",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/ORDER/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/PAY",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -333,25 +448,76 @@
|
|||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
"sourceModule" : null,
|
"sourceModule" : null,
|
||||||
"stateMachineId" : null,
|
"stateMachineId" : null,
|
||||||
"sourceState" : null,
|
"sourceState" : "click.kamil.enterprise.machines.order.OrderState.NEW",
|
||||||
"lineNumber" : 81,
|
"lineNumber" : 81,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ "click.kamil.enterprise.machines.order.OrderEvent.PAY" ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && \"ORDER\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && \"PAY\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : [ {
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"sourceState" : "click.kamil.enterprise.machines.order.OrderState.NEW",
|
||||||
|
"targetState" : "click.kamil.enterprise.machines.order.OrderState.PENDING",
|
||||||
|
"event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY"
|
||||||
|
} ],
|
||||||
|
"linkResolution" : "RESOLVED"
|
||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/DOCUMENT/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/SHIP",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/DOCUMENT/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/SHIP",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.order.OrderState.PENDING",
|
||||||
|
"lineNumber" : 81,
|
||||||
|
"polymorphicEvents" : [ "click.kamil.enterprise.machines.order.OrderEvent.SHIP" ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && \"SHIP\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.order.OrderState.PENDING",
|
||||||
|
"targetState" : "click.kamil.enterprise.machines.order.OrderState.SHIPPED",
|
||||||
|
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP"
|
||||||
|
} ],
|
||||||
|
"linkResolution" : "RESOLVED"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -379,22 +545,108 @@
|
|||||||
"sourceState" : null,
|
"sourceState" : null,
|
||||||
"lineNumber" : 81,
|
"lineNumber" : 81,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"ORDER\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"SUBMIT\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : null,
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"linkResolution" : "NO_MATCH"
|
||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/USER/transition/{event}",
|
"name" : "POST /api/machine/DOCUMENT/transition/APPROVE",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/USER/transition/{event}",
|
"path" : "/api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "DocumentEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 81,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"APPROVE\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "DocumentEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 81,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"REJECT\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/REGISTER",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/REGISTER",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -422,13 +674,99 @@
|
|||||||
"sourceState" : null,
|
"sourceState" : null,
|
||||||
"lineNumber" : 81,
|
"lineNumber" : 81,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"ORDER\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"REGISTER\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : null,
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/VERIFY",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/VERIFY",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "UserEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 81,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"VERIFY\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/SUSPEND",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/SUSPEND",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "UserEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 81,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"SUSPEND\".equalsIgnoreCase(event) && \"ORDER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
} ],
|
} ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"default" : { }
|
"default" : { }
|
||||||
|
|||||||
@@ -124,12 +124,12 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/ORDER/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/PAY",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/ORDER/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/PAY",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -147,12 +147,12 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/DOCUMENT/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/SHIP",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/DOCUMENT/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/SHIP",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -170,12 +170,127 @@
|
|||||||
} ]
|
} ]
|
||||||
}, {
|
}, {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/USER/transition/{event}",
|
"name" : "POST /api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/USER/transition/{event}",
|
"path" : "/api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/REGISTER",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/REGISTER",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/VERIFY",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/VERIFY",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/SUSPEND",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/SUSPEND",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -292,12 +407,12 @@
|
|||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/ORDER/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/PAY",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/ORDER/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/PAY",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -325,22 +440,65 @@
|
|||||||
"sourceState" : null,
|
"sourceState" : null,
|
||||||
"lineNumber" : 93,
|
"lineNumber" : 93,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && \"PAY\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : null,
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"linkResolution" : "NO_MATCH"
|
||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/DOCUMENT/transition/{event}",
|
"name" : "POST /api/machine/ORDER/transition/SHIP",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/DOCUMENT/transition/{event}",
|
"path" : "/api/machine/ORDER/transition/SHIP",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 93,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType) && \"SHIP\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/SUBMIT",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -368,22 +526,202 @@
|
|||||||
"sourceState" : null,
|
"sourceState" : null,
|
||||||
"lineNumber" : 93,
|
"lineNumber" : 93,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"SUBMIT\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : null,
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"linkResolution" : "NO_MATCH"
|
||||||
}, {
|
}, {
|
||||||
"entryPoint" : {
|
"entryPoint" : {
|
||||||
"type" : "REST",
|
"type" : "REST",
|
||||||
"name" : "POST /api/machine/USER/transition/{event}",
|
"name" : "POST /api/machine/DOCUMENT/transition/APPROVE",
|
||||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
"methodName" : "transition",
|
"methodName" : "transition",
|
||||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"path" : "/api/machine/USER/transition/{event}",
|
"path" : "/api/machine/DOCUMENT/transition/APPROVE",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "DocumentEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 93,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"APPROVE\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/DOCUMENT/transition/REJECT",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "DocumentEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 93,
|
||||||
|
"polymorphicEvents" : [ ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"DOCUMENT\".equalsIgnoreCase(machineType) && \"REJECT\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : null,
|
||||||
|
"linkResolution" : "NO_MATCH"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/REGISTER",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/REGISTER",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "UserEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.user.UserState.GUEST",
|
||||||
|
"lineNumber" : 93,
|
||||||
|
"polymorphicEvents" : [ "click.kamil.enterprise.machines.user.UserEvent.REGISTER" ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"REGISTER\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.user.UserState.GUEST",
|
||||||
|
"targetState" : "click.kamil.enterprise.machines.user.UserState.REGISTERED",
|
||||||
|
"event" : "click.kamil.enterprise.machines.user.UserEvent.REGISTER"
|
||||||
|
} ],
|
||||||
|
"linkResolution" : "RESOLVED"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/VERIFY",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/VERIFY",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "machineType",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "event",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "PathVariable" ]
|
||||||
|
}, {
|
||||||
|
"name" : "userId",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ "RequestParam" ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "UserEvent.valueOf(eventString.toUpperCase())",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||||
|
"methodName" : "dispatch",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.user.UserState.REGISTERED",
|
||||||
|
"lineNumber" : 93,
|
||||||
|
"polymorphicEvents" : [ "click.kamil.enterprise.machines.user.UserEvent.VERIFY" ],
|
||||||
|
"external" : false,
|
||||||
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"VERIFY\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
|
"ambiguous" : false
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "click.kamil.enterprise.machines.user.UserState.REGISTERED",
|
||||||
|
"targetState" : "click.kamil.enterprise.machines.user.UserState.VERIFIED",
|
||||||
|
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY"
|
||||||
|
} ],
|
||||||
|
"linkResolution" : "RESOLVED"
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/machine/USER/transition/SUSPEND",
|
||||||
|
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||||
|
"methodName" : "transition",
|
||||||
|
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/machine/USER/transition/SUSPEND",
|
||||||
"verb" : "POST"
|
"verb" : "POST"
|
||||||
},
|
},
|
||||||
"parameters" : [ {
|
"parameters" : [ {
|
||||||
@@ -411,13 +749,13 @@
|
|||||||
"sourceState" : null,
|
"sourceState" : null,
|
||||||
"lineNumber" : 93,
|
"lineNumber" : 93,
|
||||||
"polymorphicEvents" : [ ],
|
"polymorphicEvents" : [ ],
|
||||||
"external" : true,
|
"external" : false,
|
||||||
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
"constraint" : "\"USER\".equalsIgnoreCase(machineType) && \"SUSPEND\".equalsIgnoreCase(event) && !(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||||
"ambiguous" : false
|
"ambiguous" : false
|
||||||
},
|
},
|
||||||
"contextMachineId" : null,
|
"contextMachineId" : null,
|
||||||
"matchedTransitions" : null,
|
"matchedTransitions" : null,
|
||||||
"linkResolution" : "UNRESOLVED_EXTERNAL"
|
"linkResolution" : "NO_MATCH"
|
||||||
} ],
|
} ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"default" : { }
|
"default" : { }
|
||||||
|
|||||||
Reference in New Issue
Block a user