com.codepoetics.fluvius.execution.KeyCheckingFlowExecution Maven / Gradle / Ivy
package com.codepoetics.fluvius.execution;
import com.codepoetics.fluvius.api.*;
import com.codepoetics.fluvius.api.scratchpad.Key;
import com.codepoetics.fluvius.api.scratchpad.KeyValue;
import com.codepoetics.fluvius.api.scratchpad.Scratchpad;
import com.codepoetics.fluvius.exceptions.MissingKeysException;
import com.codepoetics.fluvius.scratchpad.Scratchpads;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* Flow execution that checks that all required keys are provided before executing the flow.
* @param The type of value returned by executing the flow.
*/
public final class KeyCheckingFlowExecution extends AbstractFlowExecution {
/**
* Create a key-checking flow execution using the supplied flow and visitor.
* @param flow The flow to build flow execution for.
* @param visitor The visitor to use to compile the flow.
* @param The type of value returned by executing the flow.
* @return The constructed flow execution.
*/
public static FlowExecution forFlow(Flow flow, FlowVisitor visitor) {
return forAction(flow.visit(visitor), flow.getRequiredKeys(), flow.getProvidedKey());
}
static FlowExecution forAction(Action action, Set> requiredKeys, Key providedKey) {
return new KeyCheckingFlowExecution<>(action, requiredKeys, providedKey);
}
private final Action action;
private final Set> requiredKeys;
private final Key providedKey;
KeyCheckingFlowExecution(Action action, Set> requiredKeys, Key providedKey) {
this.action = action;
this.requiredKeys = requiredKeys;
this.providedKey = providedKey;
}
private Set> getMissingKeys(Scratchpad initialScratchpad) {
Set> missingKeys = new HashSet<>();
for (Key> requiredKey : requiredKeys) {
if (!initialScratchpad.containsKey(requiredKey)) {
missingKeys.add(requiredKey);
}
}
return missingKeys;
}
@Override
public T run(UUID flowId, Scratchpad initialScratchpad) throws Exception {
Set> missingKeys = getMissingKeys(initialScratchpad);
if (!missingKeys.isEmpty()) {
throw MissingKeysException.create(missingKeys);
}
Scratchpad finalScratchpad = action.run(flowId, initialScratchpad.locked());
if (finalScratchpad.isSuccessful(providedKey)) {
return finalScratchpad.get(providedKey);
} else {
throw (finalScratchpad.getFailureReason(providedKey));
}
}
@Override
public T run(UUID flowId, KeyValue... initialKeyValues) throws Exception {
return run(flowId, Scratchpads.create(initialKeyValues));
}
@Override
public Runnable asAsync(UUID flowId, FlowResultCallback callback, Scratchpad initialScratchpad) {
return new RunWithCallback<>(flowId, initialScratchpad, callback, this);
}
private static final class RunWithCallback implements Runnable {
private final UUID flowId;
private final Scratchpad initialScratchpad;
private final FlowResultCallback callback;
private final KeyCheckingFlowExecution execution;
private RunWithCallback(UUID flowId, Scratchpad initialScratchpad, FlowResultCallback callback, KeyCheckingFlowExecution execution) {
this.flowId = flowId;
this.initialScratchpad = initialScratchpad;
this.callback = callback;
this.execution = execution;
}
@Override
public void run() {
T result = null;
try {
result = execution.run(flowId, initialScratchpad);
} catch (Exception e) {
callback.onFailure(flowId, e);
}
if (result != null) {
callback.onSuccess(flowId, result);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy