
com.amazonaws.services.simpleworkflow.flow.pojo.POJOWorkflowDefinition Maven / Gradle / Ivy
/*
* Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.amazonaws.services.simpleworkflow.flow.pojo;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.concurrent.atomic.AtomicReference;
import com.amazonaws.services.simpleworkflow.flow.*;
import com.amazonaws.services.simpleworkflow.flow.common.WorkflowExecutionUtils;
import com.amazonaws.services.simpleworkflow.flow.core.*;
import com.amazonaws.services.simpleworkflow.flow.generic.*;
@SuppressWarnings("rawtypes")
public class POJOWorkflowDefinition extends WorkflowDefinition {
private final MethodConverterPair workflowMethod;
private final Map signals;
private final MethodConverterPair getStateMethod;
private final Object workflowImplementationInstance;
private final DataConverter converter;
private final DecisionContext context;
public POJOWorkflowDefinition(Object workflowImplmentationInstance, MethodConverterPair workflowImplementationMethod,
Map signals, MethodConverterPair getStateMethod, DataConverter converter,
DecisionContext context)
throws ClassNotFoundException, SecurityException, NoSuchMethodException, NoSuchFieldException {
this.workflowImplementationInstance = workflowImplmentationInstance;
this.workflowMethod = workflowImplementationMethod;
this.getStateMethod = getStateMethod;
this.signals = signals;
this.converter = converter;
this.context = context;
}
@Override
public Promise execute(final String input) throws WorkflowException {
final DataConverter c;
if (workflowMethod.getConverter() == null) {
c = converter;
}
else {
c = workflowMethod.getConverter();
}
final Settable result = new Settable();
final AtomicReference methodResult = new AtomicReference();
new TryCatchFinally() {
@Override
protected void doTry() throws Throwable {
//TODO: Support ability to call workflow using old client
// after new parameters were added to @Execute method
// It requires creation of parameters array of the correct size and
// populating the new parameter values with default values for each type
Object[] parameters = c.fromData(input, Object[].class);
Method method = workflowMethod.getMethod();
Object r = invokeMethod(method, parameters);
if (!method.getReturnType().equals(Void.TYPE)) {
methodResult.set((Promise) r);
}
}
@Override
protected void doCatch(Throwable e) throws Throwable {
if (!(e instanceof CancellationException) || !context.getWorkflowContext().isCancelRequested()) {
throwWorkflowException(c, e);
}
}
@Override
protected void doFinally() throws Throwable {
Promise r = methodResult.get();
if (r == null || r.isReady()) {
Object workflowResult = r == null ? null : r.get();
String convertedResult = c.toData(workflowResult);
result.set(convertedResult);
}
}
};
return result;
}
@Override
public void signalRecieved(String signalName, String details) throws WorkflowException {
MethodConverterPair signalMethod = signals.get(signalName);
if (signalMethod != null) {
DataConverter c = signalMethod.getConverter();
if (c == null) {
c = converter;
}
Method method = signalMethod.getMethod();
Object[] parameters = c.fromData(details, Object[].class);
try {
invokeMethod(method, parameters);
}
catch (Throwable e) {
throwWorkflowException(c, e);
throw new IllegalStateException("Unreacheable");
}
}
else {
// TODO: Unhandled signal
}
}
@Override
public String getWorkflowState() throws WorkflowException {
if (getStateMethod == null) {
return null;
}
final DataConverter c;
if (getStateMethod.getConverter() == null) {
c = converter;
}
else {
c = getStateMethod.getConverter();
}
try {
Method method = getStateMethod.getMethod();
Object result = invokeMethod(method, null);
return c.toData(result);
}
catch (Throwable e) {
throwWorkflowException(c, e);
throw new IllegalStateException("Unreacheable");
}
}
private Object invokeMethod(final Method method, final Object[] input) throws Throwable {
try {
return method.invoke(workflowImplementationInstance, input);
}
catch (InvocationTargetException invocationException) {
if (invocationException.getTargetException() != null) {
throw invocationException.getTargetException();
}
throw invocationException;
}
}
private void throwWorkflowException(DataConverter c, Throwable exception) throws WorkflowException {
if (exception instanceof WorkflowException) {
throw (WorkflowException)exception;
}
String reason = WorkflowExecutionUtils.truncateReason(exception.getMessage());
String details = null;
try {
details = c.toData(exception);
}
catch (DataConverterException dataConverterException) {
if (dataConverterException.getCause() == null) {
dataConverterException.initCause(exception);
}
throw dataConverterException;
}
throw new WorkflowException(reason, details);
}
public Object getImplementationInstance() {
return workflowImplementationInstance;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy