/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ import * as React from 'react'; import API from '@aws-amplify/api'; import { Logger } from '@aws-amplify/core'; import { Grid, Row, Col, PageHeader, Breadcrumb, BreadcrumbItem, Alert, ProgressBar, Panel, Table, FormGroup, ControlLabel, Glyphicon, FormControl } from 'react-bootstrap'; import { LinkContainer } from 'react-router-bootstrap'; import { LOGGING_LEVEL} from '../components/CustomUtil'; // Properties interface IProps { history?: any; match?: any; location?: any; getApiToken: Function; } // States interface IState { token: string; taskId: string; parentExecutionId: string; automationExecutionId: string; execution: Execution; isLoading: boolean; error: string; showStepDetail: boolean; stepExecutionId: string; } // Execution interface interface Execution { DocumentName: string; AutomationExecutionId: string; AutomationExecutionStatus: ExecutionStatus; ExecutionStartTime?: number; ExecutionEndTime?: number; StepExecutions?: StepExecution[]; } // Step interface interface StepExecution { StepExecutionId: string; StepStatus: ExecutionStatus; Inputs: object; Outputs?: { OutputPayload?: any; }; OnFailure?: string; StepName?: string; Action?: string; FailureMessage?: string; ExecutionStartTime?: string; ExecutionEndTime?: string; FailureDetails?: { FailureStage: string; FailureType: string; Details: { ErrorCode?: string[]; ExceptionMessage?: string[]; ServiceName?: string[]; APIName?: string[]; StatusCode?: string[]; } }; } // Execution status enum enum ExecutionStatus { pending = 'Pending', inProgress = 'InProgress', waiting = 'Waiting', success = 'Success', timedOut = 'TimedOut', cancelling = 'Cancelling', cancelled = 'Cancelled', failed = 'Failed' } // External variables const LOGGER = new Logger('ExecutionDetail', LOGGING_LEVEL); const API_NAME = 'operations-conductor-api'; class AutomationExecutionDetail extends React.Component { constructor(props: Readonly) { super(props); this.state = { token: '', taskId: this.props.match.params.taskId, parentExecutionId: this.props.match.params.parentExecutionId, automationExecutionId: this.props.match.params.automationExecutionId, execution: { DocumentName: '', AutomationExecutionId: '', AutomationExecutionStatus: ExecutionStatus.inProgress }, isLoading: false, error: '', showStepDetail: false, stepExecutionId: '' }; } componentDidMount() { this.setApiToken().then(() => { this.getExecution(); }).catch((error) => { this.handleError('Error occurred while setting API token', error); }); } // Sets API token setApiToken = async () => { let token = await this.props.getApiToken(); this.setState({ token }); }; // Gets an execution getExecution = async () => { this.setState({ isLoading: true, error: '', }); const { taskId, parentExecutionId, automationExecutionId } = this.state; let path = `/tasks/${taskId}/executions/${parentExecutionId}/${automationExecutionId}`; let params = { headers: { 'Authorization': this.state.token } }; try { let execution: Execution = await API.get(API_NAME, path, params); this.setState({ execution }); } catch (error) { this.handleError('Error occurred while getting an execution detail.', error); } finally { this.setState({ isLoading: false }); } }; // Handles error handleError = (message: string, error: any) => { if (error.response !== undefined) { LOGGER.error(message, error.response.data.message); this.setState({ error: error.response.data.message }); } else { LOGGER.error(message, error.message); this.setState({ error: error.message }); } }; render() { return (
Tasks {`Task Detail: ${this.props.location.state.taskName}`} Task Execution ID: {this.props.match.params.parentExecutionId} Automation Execution ID: {this.props.match.params.automationExecutionId} { !this.state.isLoading && [ Automation Execution Detail - {this.state.execution.DocumentName} , Execution description Executed automation {this.state.execution.DocumentName} Execution ID {this.state.execution.AutomationExecutionId} Start time {this.state.execution.ExecutionStartTime} End time {this.state.execution.ExecutionEndTime} , Execution status Overall status { [ ExecutionStatus.pending, ExecutionStatus.inProgress, ExecutionStatus.waiting, ExecutionStatus.cancelling ].indexOf(this.state.execution.AutomationExecutionStatus) > -1 && {this.state.execution.AutomationExecutionStatus} } { this.state.execution.AutomationExecutionStatus === ExecutionStatus.success && {this.state.execution.AutomationExecutionStatus} } { [ ExecutionStatus.timedOut, ExecutionStatus.cancelled, ExecutionStatus.failed ].indexOf(this.state.execution.AutomationExecutionStatus) > -1 && {this.state.execution.AutomationExecutionStatus} } All executed steps { this.state.execution.StepExecutions ? this.state.execution.StepExecutions .filter((stepExecution: StepExecution) => [ ExecutionStatus.success, ExecutionStatus.timedOut, ExecutionStatus.cancelled, ExecutionStatus.failed ].indexOf(stepExecution.StepStatus) > -1 ).length : '0' } # Succeeded { this.state.execution.StepExecutions ? this.state.execution.StepExecutions .filter((stepExecution: StepExecution) => stepExecution.StepStatus === ExecutionStatus.success) .length : '0' } # Failed { this.state.execution.StepExecutions ? this.state.execution.StepExecutions .filter((stepExecution: StepExecution) => stepExecution.StepStatus === ExecutionStatus.failed) .length : '0' } # Cancelled { this.state.execution.StepExecutions ? this.state.execution.StepExecutions .filter((stepExecution: StepExecution) => stepExecution.StepStatus === ExecutionStatus.cancelled) .length : '0' } # TimedOut { this.state.execution.StepExecutions ? this.state.execution.StepExecutions .filter((stepExecution: StepExecution) => stepExecution.StepStatus === ExecutionStatus.timedOut) .length : '0' } , Executed steps { this.state.execution.StepExecutions ? this.state.execution.StepExecutions.length === 0 ? : this.state.execution.StepExecutions .filter((stepExecution) => ( (this.state.execution.AutomationExecutionStatus === ExecutionStatus.success && stepExecution.StepStatus !== ExecutionStatus.pending) || (this.state.execution.AutomationExecutionStatus !== ExecutionStatus.success)) ) .map((stepExecution: StepExecution, index: number) => { return ( ); }) : }
Step ID Step # Step Name Action Status Start Time End Time
No step execution found.
{this.setState({ showStepDetail: true, stepExecutionId: stepExecution.StepExecutionId })}}> {stepExecution.StepExecutionId} {index + 1} {stepExecution.StepName} {stepExecution.Action} { [ ExecutionStatus.pending, ExecutionStatus.inProgress, ExecutionStatus.waiting, ExecutionStatus.cancelling ].indexOf(stepExecution.StepStatus) > -1 && {stepExecution.StepStatus} } { stepExecution.StepStatus === ExecutionStatus.success && {stepExecution.StepStatus} } { [ ExecutionStatus.timedOut, ExecutionStatus.cancelled, ExecutionStatus.failed ].indexOf(stepExecution.StepStatus) > -1 && {stepExecution.StepStatus} } {stepExecution.ExecutionStartTime} {stepExecution.ExecutionEndTime}
No step execution found.
, { this.state.showStepDetail &&
{ this.state.execution.StepExecutions !== undefined && this.state.execution.StepExecutions .filter((stepExecution: StepExecution) => stepExecution.StepExecutionId === this.state.stepExecutionId) .map((stepExecution: StepExecution) => { return (
Automation step: {stepExecution.StepName} Status { [ ExecutionStatus.pending, ExecutionStatus.inProgress, ExecutionStatus.waiting, ExecutionStatus.cancelling ].indexOf(stepExecution.StepStatus) > -1 && {stepExecution.StepStatus} } { stepExecution.StepStatus === ExecutionStatus.success && {stepExecution.StepStatus} } { [ ExecutionStatus.timedOut, ExecutionStatus.cancelled, ExecutionStatus.failed ].indexOf(stepExecution.StepStatus) > -1 && {stepExecution.StepStatus} } Action {stepExecution.Action} Start time {stepExecution.ExecutionStartTime} End time {stepExecution.ExecutionEndTime} { stepExecution.Outputs !== undefined && Outputs step: {stepExecution.StepName} Payload {stepExecution.Outputs['OutputPayload']} } { stepExecution.FailureMessage !== undefined && Automation step: {stepExecution.StepName} - Failure details

Failure message
{stepExecution.FailureMessage}

FailureType { stepExecution.FailureDetails ? stepExecution.FailureDetails.FailureType : '-' } ServiceName { stepExecution.FailureDetails ? stepExecution.FailureDetails.Details.ServiceName ? stepExecution.FailureDetails.Details.ServiceName[0] : '-' : '-' } FailureStage { stepExecution.FailureDetails ? stepExecution.FailureDetails.FailureStage : '-' } StatusCode { stepExecution.FailureDetails ? stepExecution.FailureDetails.Details.StatusCode ? stepExecution.FailureDetails.Details.StatusCode[0] : '-' : '-' } APIName { stepExecution.FailureDetails ? stepExecution.FailureDetails.Details.APIName ? stepExecution.FailureDetails.Details.APIName[0] : '-' : '-' } ErrorCode { stepExecution.FailureDetails ? stepExecution.FailureDetails.Details.ErrorCode ? stepExecution.FailureDetails.Details.ErrorCode[0] : '-' : '-' } ExceptionMessage { stepExecution.FailureDetails ? stepExecution.FailureDetails.Details.ExceptionMessage ? stepExecution.FailureDetails.Details.ExceptionMessage[0] : '-' : '-' }
}
); }) }
}
] } { this.state.error && Error:
{this.state.error}
} { this.state.isLoading && }
); } } export default AutomationExecutionDetail;