Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2012 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.common;
 
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
 
Convenience methods to be used by unit tests and during development.

Author(s):
fateev
 
 public class WorkflowExecutionUtils {

    
Blocks until workflow instance completes and returns its result. Useful for unit tests and during development. Never use in production setting as polling for worklow instance status is an expensive operation.

Parameters:
workflowExecution result of AmazonSimpleWorkflow#startWorkflowInstance(com.amazonaws.services.simpleworkflow.model.StartWorkflowInstanceRequest )
Returns:
workflow instance result.
Throws:
java.lang.InterruptedException if thread is interrupted
java.lang.RuntimeException if workflow instance ended up in any state but completed
 
             String domainWorkflowExecution workflowExecutionthrows InterruptedException {
         try {
             return waitForWorkflowExecutionResult(servicedomainworkflowExecution, 0);
         }
         catch (TimeoutException e) {
             throw new Error("should never happen"e);
         }
     }

    
Waits up to specified timeout until workflow instance completes and returns its result. Useful for unit tests and during development. Never use in production setting as polling for worklow instance status is an expensive operation.

Parameters:
workflowExecution result of AmazonSimpleWorkflow#startWorkflowInstance(com.amazonaws.services.simpleworkflow.model.StartWorkflowInstanceRequest )
Returns:
workflow instance result.
Throws:
java.lang.InterruptedException if thread is interrupted
java.util.concurrent.TimeoutException if instance is not complete after specified timeout
java.lang.RuntimeException if workflow instance ended up in any state but completed
 
             String domainWorkflowExecution workflowExecutionlong timeoutSeconds)
             throws InterruptedExceptionTimeoutException {
        if (!waitForWorkflowInstanceCompletion(servicedomainworkflowExecutiontimeoutSeconds).equals(
                ..toString())) {
            String historyDump = WorkflowExecutionUtils.prettyPrintHistory(servicedomainworkflowExecution);
            throw new RuntimeException("Workflow instance is not in completed state:\n" + historyDump);
        }
        return getWorkflowExecutionResult(servicedomainworkflowExecution);
    }

    
Returns result of workflow instance execution. result of AmazonSimpleWorkflow#startWorkflowInstance(com.amazonaws.services.simpleworkflow.model.StartWorkflowInstanceRequest )

Throws:
java.lang.IllegalStateException if workflow is still running
java.lang.RuntimeException if workflow instance ended up in any state but completed
            String domainWorkflowExecution workflowExecution) {
        HistoryEvent closeEvent = getInstanceCloseEvent(servicedomainworkflowExecution);
        if (closeEvent == null) {
            throw new IllegalStateException("Workflow is still running");
        }
        if (closeEvent.getEventType().equals(..toString())) {
            return closeEvent.getWorkflowExecutionCompletedEventAttributes();
        }
        throw new RuntimeException("Workflow end state is not completed: " + prettyPrintHistoryEvent(closeEvent));
    }
    public static HistoryEvent getInstanceCloseEvent(AmazonSimpleWorkflow serviceString domain,
            WorkflowExecution workflowExecution) {
        WorkflowExecutionInfo executionInfo = describeWorkflowInstance(servicedomainworkflowExecution);
        if (executionInfo == null || executionInfo.getExecutionStatus().equals(..toString())) {
            return null;
        }
        List<HistoryEventevents = getHistory(servicedomainworkflowExecution);
        HistoryEvent result = null;
        for (HistoryEvent event : events) {
            if (isWorkflowExecutionCompletedEvent(event)) {
                result = event;
                break;
            }
        }
        return result;
    }
    public static boolean isWorkflowExecutionCompletedEvent(HistoryEvent event) {
        return ((event != null) && (event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString()) || event.getEventType().equals(
                ..toString())));
    }
    public static boolean isActivityTaskClosedEvent(HistoryEvent event) {
        return ((event != null) && (event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString()) || event.getEventType().equals(
                ..toString())));
    }
    public static boolean isExternalWorkflowClosedEvent(HistoryEvent event) {
        return ((event != null) && (event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString())
                || event.getEventType().equals(..toString()) || event.getEventType().equals(
                ..toString())));
    }
        if (event != null) {
            if (event.getEventType().equals(..toString())) {
                return event.getChildWorkflowExecutionCompletedEventAttributes().getWorkflowExecution();
            }
            else if (event.getEventType().equals(..toString())) {
                return event.getChildWorkflowExecutionCanceledEventAttributes().getWorkflowExecution();
            }
            else if (event.getEventType().equals(..toString())) {
                return event.getChildWorkflowExecutionFailedEventAttributes().getWorkflowExecution();
            }
            else if (event.getEventType().equals(..toString())) {
                return event.getChildWorkflowExecutionTerminatedEventAttributes().getWorkflowExecution();
            }
            else if (event.getEventType().equals(..toString())) {
                return event.getChildWorkflowExecutionTimedOutEventAttributes().getWorkflowExecution();
            }
        }
        return null;
    }
    
    public static String getId(HistoryEvent historyEvent) {
        String id = null;
        if (historyEvent != null) {
            if (historyEvent.getEventType().equals(..toString())) {
                id = historyEvent.getStartChildWorkflowExecutionFailedEventAttributes().getWorkflowId();
            } else if (historyEvent.getEventType().equals(..toString())) {
                id = historyEvent.getScheduleActivityTaskFailedEventAttributes().getActivityId();
            } else if (historyEvent.getEventType().equals(..toString())) {
                id = historyEvent.getStartTimerFailedEventAttributes().getTimerId();
            } 
        }
        
        return id;
    }
    
    public static String getFailureCause(HistoryEvent historyEvent) {
        String failureCause = null;
        if (historyEvent != null) {
            if (historyEvent.getEventType().equals(..toString())) {
                failureCause = historyEvent.getStartChildWorkflowExecutionFailedEventAttributes().getCause();
            } else if (historyEvent.getEventType().equals(..toString())) {
                failureCause = historyEvent.getSignalExternalWorkflowExecutionFailedEventAttributes().getCause();
            } else if (historyEvent.getEventType().equals(..toString())) {
                failureCause = historyEvent.getScheduleActivityTaskFailedEventAttributes().getCause();
            } else if (historyEvent.getEventType().equals(..toString())) {
                failureCause = historyEvent.getStartTimerFailedEventAttributes().getCause();
            } else if (historyEvent.getEventType().equals(..toString())) {
                failureCause = historyEvent.getContinueAsNewWorkflowExecutionFailedEventAttributes().getCause();
            } else if (historyEvent.getEventType().equals(..toString())) {
            	failureCause = historyEvent.getRecordMarkerFailedEventAttributes().getCause();
            }
        }
        
        return failureCause;
    }

    
Blocks until workflow instance completes. Never use in production setting as polling for worklow instance status is an expensive operation.

Parameters:
workflowExecution result of AmazonSimpleWorkflow#startWorkflowInstance(com.amazonaws.services.simpleworkflow.model.StartWorkflowInstanceRequest )
Returns:
instance close status
    public static String waitForWorkflowInstanceCompletion(AmazonSimpleWorkflow serviceString domain,
            WorkflowExecution workflowExecutionthrows InterruptedException {
        try {
            return waitForWorkflowInstanceCompletion(servicedomainworkflowExecution, 0);
        }
        catch (TimeoutException e) {
            throw new Error("should never happen"e);
        }
    }

    
Waits up to specified timeout for workflow instance completion. Never use in production setting as polling for worklow instance status is an expensive operation.

Parameters:
workflowExecution result of AmazonSimpleWorkflow#startWorkflowInstance(com.amazonaws.services.simpleworkflow.model.StartWorkflowInstanceRequest )
timeoutSeconds maximum time to wait for completion. 0 means wait forever.
Returns:
instance close status
Throws:
java.util.concurrent.TimeoutException
    public static String waitForWorkflowInstanceCompletion(AmazonSimpleWorkflow serviceString domain,
            WorkflowExecution workflowExecutionlong timeoutSeconds
                throws InterruptedExceptionTimeoutException {
        long start = System.currentTimeMillis();
        WorkflowExecutionInfo executionInfo = null;
        do {
            if (timeoutSeconds > 0 && System.currentTimeMillis() - start >= timeoutSeconds * 1000) {
                String historyDump = WorkflowExecutionUtils.prettyPrintHistory(servicedomainworkflowExecution);
                throw new TimeoutException("Workflow instance is not complete after " + timeoutSeconds + " seconds: \n"
                        + historyDump);
            }
            if (executionInfo != null) {
                Thread.sleep(1000);
            }
            executionInfo = describeWorkflowInstance(servicedomainworkflowExecution);
        }
        while (executionInfo.getExecutionStatus().equals(..toString()));
        return executionInfo.getCloseStatus();
    }

    
            WorkflowExecution workflowExecutionlong timeoutSecondsthrows InterruptedExceptionTimeoutException {
        WorkflowExecution lastExecutionToRun = workflowExecution;
        long millisecondsAtFirstWait = System.currentTimeMillis();
        String lastExecutionToRunCloseStatus = waitForWorkflowInstanceCompletion(servicedomainlastExecutionToRun,
                timeoutSeconds);
        // keep waiting if the instance continued as new
        while (lastExecutionToRunCloseStatus.equals(..toString())) {
            // get the new execution's information
            HistoryEvent closeEvent = getInstanceCloseEvent(servicedomainlastExecutionToRun);
            WorkflowExecutionContinuedAsNewEventAttributes continuedAsNewAttributes = closeEvent.getWorkflowExecutionContinuedAsNewEventAttributes();
            WorkflowExecution newGenerationExecution = new WorkflowExecution().withWorkflowId(lastExecutionToRun.getWorkflowId()).withRunId(
                    continuedAsNewAttributes.getNewExecutionRunId());
            
            // and wait for it
            long currentTime = System.currentTimeMillis();
            long millisecondsSinceFirstWait = currentTime - millisecondsAtFirstWait;
            long timeoutInSecondsForNextWait = timeoutSeconds - (millisecondsSinceFirstWait / 1000L);
            
            lastExecutionToRunCloseStatus = waitForWorkflowInstanceCompletion(servicedomainnewGenerationExecutiontimeoutInSecondsForNextWait);
            lastExecutionToRun = newGenerationExecution;
        }
        return lastExecutionToRunCloseStatus;
    }

    
            WorkflowExecution workflowExecutionthrows InterruptedException {
        try {
            return waitForWorkflowInstanceCompletionAcrossGenerations(servicedomainworkflowExecution, 0L);
        }
        catch (TimeoutException e) {
            throw new Error("should never happen"e);
        }
    }
            WorkflowExecution workflowExecution) {
        DescribeWorkflowExecutionRequest describeRequest = new DescribeWorkflowExecutionRequest();
        describeRequest.setDomain(domain);
        describeRequest.setExecution(workflowExecution);
        WorkflowExecutionDetail executionDetail = service.describeWorkflowExecution(describeRequest);
        WorkflowExecutionInfo instanceMetadata = executionDetail.getExecutionInfo();
        return instanceMetadata;
    }

    
Returns workflow instance history in a human readable format.

Parameters:
workflowExecution result of AmazonSimpleWorkflow#startWorkflowInstance(com.amazonaws.services.simpleworkflow.model.StartWorkflowInstanceRequest )
    public static String prettyPrintHistory(AmazonSimpleWorkflow serviceString domainWorkflowExecution workflowExecution) {
        return prettyPrintHistory(servicedomainworkflowExecutiontrue);
    }

    
Returns workflow instance history in a human readable format.

Parameters:
workflowExecution result of AmazonSimpleWorkflow#startWorkflowInstance(com.amazonaws.services.simpleworkflow.model.StartWorkflowInstanceRequest )
showWorkflowTasks when set to false workflow task events (decider events) are not included
    public static String prettyPrintHistory(AmazonSimpleWorkflow serviceString domainWorkflowExecution workflowExecution,
            boolean showWorkflowTasks) {
        List<HistoryEventevents = getHistory(servicedomainworkflowExecution);
        return prettyPrintHistory(eventsshowWorkflowTasks);
    }
    public static List<HistoryEventgetHistory(AmazonSimpleWorkflow serviceString domain,
            WorkflowExecution workflowExecution) {
        List<HistoryEventevents = new ArrayList<HistoryEvent>();
        String nextPageToken = null;
        do {
            History history = getHistoryPage(nextPageTokenservicedomainworkflowExecution);
            events.addAll(history.getEvents());
            nextPageToken = history.getNextPageToken();
        }
        while (nextPageToken != null);
        return events;
    }
    public static History getHistoryPage(String nextPageTokenAmazonSimpleWorkflow serviceString domain,
            WorkflowExecution workflowExecution) {
        GetWorkflowExecutionHistoryRequest getHistoryRequest = new GetWorkflowExecutionHistoryRequest();
        getHistoryRequest.setDomain(domain);
        getHistoryRequest.setExecution(workflowExecution);
        getHistoryRequest.setNextPageToken(nextPageToken);
        History history = service.getWorkflowExecutionHistory(getHistoryRequest);
        if (history == null) {
            throw new IllegalArgumentException("unknown workflow execution: " + workflowExecution);
        }
        return history;
    }

    
Returns workflow instance history in a human readable format.

Parameters:
showWorkflowTasks when set to false workflow task events (decider events) are not included
History:
Workflow instance history
    public static String prettyPrintHistory(History historyboolean showWorkflowTasks) {
        return prettyPrintHistory(history.getEvents(), showWorkflowTasks);
    }
    public static String prettyPrintHistory(Iterable<HistoryEventeventsboolean showWorkflowTasks) {
        StringBuffer result = new StringBuffer();
        result.append("{");
        boolean first = true;
        for (HistoryEvent event : events) {
            if (!showWorkflowTasks && event.getEventType().startsWith("WorkflowTask")) {
                continue;
            }
            if (first) {
                first = false;
            }
            else {
                result.append(",");
            }
            result.append("\n    ");
            result.append(prettyPrintHistoryEvent(event));
        }
        result.append("\n}");
        return result.toString();
    }
    public static String prettyPrintDecisions(Iterable<Decisiondecisions) {
        StringBuffer result = new StringBuffer();
        result.append("{");
        boolean first = true;
        for (Decision decision : decisions) {
            if (first) {
                first = false;
            }
            else {
                result.append(",");
            }
            result.append("\n    ");
            result.append(prettyPrintDecision(decision));
        }
        result.append("\n}");
        return result.toString();
    }

    
Returns single event in a human readable format

Parameters:
event event to pretty print
    public static String prettyPrintHistoryEvent(HistoryEvent event) {
        String eventType = event.getEventType();
        StringBuffer result = new StringBuffer();
        result.append(eventType);
        result.append(prettyPrintObject(event"getType"true"    "false));
        return result.toString();
    }

    
Returns single decision in a human readable format

Parameters:
event event to pretty print
    public static String prettyPrintDecision(Decision decision) {
        return prettyPrintObject(decision"getType"true"    "true);
    }
    
    
Not really a generic method for printing random object graphs. But it works for events and decisions.
    private static String prettyPrintObject(Object objectString methodToSkipboolean skipNullsAndEmptyCollections,
            String indentationboolean skipLevel) {
        StringBuffer result = new StringBuffer();
        if (object == null) {
            return "null";
        }
        Class<? extends Objectclz = object.getClass();
        if (Number.class.isAssignableFrom(clz)) {
            return String.valueOf(object);
        }
        if (Boolean.class.isAssignableFrom(clz)) {
            return String.valueOf(object);
        }
        if (clz.equals(String.class)) {
            return (Stringobject;
        }
        if (clz.equals(Date.class)) {
            return String.valueOf(object);
        }
        if (Map.class.isAssignableFrom(clz)) {
            return String.valueOf(object);
        }
        if (Collection.class.isAssignableFrom(clz)) {
            return String.valueOf(object);
        }
        if (!skipLevel) {
            result.append(" {");
        }
        Method[] eventMethods = object.getClass().getMethods();
        boolean first = true;
        for (Method method : eventMethods) {
            String name = method.getName();
            if (!name.startsWith("get")) {
                continue;
            }
            if (name.equals(methodToSkip) || name.equals("getClass")) {
                continue;
            }
            if (Modifier.isStatic(method.getModifiers())) {
                continue;
            }
            Object value;
            try {
                value = method.invoke(object, (Object[]) null);
                if (value != null && value.getClass().equals(String.class) && name.equals("getDetails")) {
                    value = printDetails((Stringvalue);
                }
            }
            catch (InvocationTargetException e) {
                throw new RuntimeException(e.getTargetException());
            }
            catch (RuntimeException e) {
                throw (RuntimeExceptione;
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
            if (skipNullsAndEmptyCollections) {
                if (value == null) {
                    continue;
                }
                if (value instanceof Map && ((Map<?, ?>) value).isEmpty()) {
                    continue;
                }
                if (value instanceof Collection && ((Collection<?>) value).isEmpty()) {
                    continue;
                }
            }
            if (!skipLevel) {
                if (first) {
                    first = false;
                }
                else {
                    result.append(";");
                }
                result.append("\n");
                result.append(indentation);
                result.append("    ");
                result.append(name.substring(3));
                result.append(" = ");
                result.append(prettyPrintObject(valuemethodToSkipskipNullsAndEmptyCollectionsindentation + "    "false));
            }
            else {
                result.append(prettyPrintObject(valuemethodToSkipskipNullsAndEmptyCollectionsindentationfalse));
            }
        }
        if (!skipLevel) {
            result.append("\n");
            result.append(indentation);
            result.append("}");
        }
        return result.toString();
    }
    
    public static String printDetails(String details) {
        Throwable failure = null;
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(.false);
            mapper.enableDefaultTyping(.);
            
            failure = mapper.readValue(detailsThrowable.class);
        } catch (Exception e) {
            // eat up any data converter exceptions
        }
        
        if (failure != null) {
            StringBuilder builder = new StringBuilder();
            
            // Also print callstack
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            failure.printStackTrace(pw);
            
            builder.append(sw.toString());
            
            details = builder.toString();
        }
        
        return details;
    }

    
Simple Workflow limits length of the reason field. This method truncates the passed argument to the maximum length.

Parameters:
reason string value to truncate
Returns:
truncated value
    public static String truncateReason(String reason) {
        if (reason != null && reason.length() > ..getMaxSize()) {
            reason = reason.substring(0, ..getMaxSize());
        }
        return reason;
    }
    
    public static String truncateDetails(String details) {
        if (details != null && details.length() > ..getMaxSize()) {
            details = details.substring(0, ..getMaxSize());
        }
        return details;
    }
New to GrepCode? Check out our FAQ X