Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Commit

Permalink
Introduce restart workflow feature - backend
Browse files Browse the repository at this point in the history
  • Loading branch information
gabriel-farache committed Jun 23, 2023
1 parent e03e65a commit 224b9e4
Show file tree
Hide file tree
Showing 56 changed files with 1,520 additions and 161 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;

import com.redhat.parodos.workflow.exception.MissingParameterException;
import com.redhat.parodos.workflow.task.log.WorkFlowTaskLogger;
Expand Down Expand Up @@ -116,6 +117,21 @@ public String getRequiredParameterValue(String parameterName) throws MissingPara
});
}

public boolean validateWorkflowParameters(WorkContext workContext) {
AtomicBoolean valid = new AtomicBoolean(true);
getWorkFlowTaskParameters().stream().filter(param -> !param.isOptional()).forEach(param -> {
try {
getRequiredParameterValue(param.getKey());
}
catch (MissingParameterException e) {
valid.set(false);
log.warn("{} is missing from workContext for workflow task {}", param.getKey(), getName());
}
});

return valid.get();
}

/**
* Gets an optional parameter. Returns the defaultValue if not found
* @param parameterName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public T submitWithRetry(Callable<T> task) {
// @formatter:on
}

public T submitWithRetry(Callable<T> task, long maxRetryTime) {
// @formatter:off
return submitWithRetry(task, () -> {}, () -> {}, maxRetryTime, RETRY_DELAY);
// @formatter:on
}

/**
* Submit a task to the executor service, retrying on failure until the task
* @param task The task to submit
Expand All @@ -58,8 +64,13 @@ public T submitWithRetry(Callable<T> task, Runnable onSuccess, Runnable onFailur
onSuccess.run();
future.complete(result); // Success, complete the future with the result
}
catch (WorkFlowServiceUtils.InProgrssStatusException e) {
return;
}
catch (Exception e) {
onFailure.run();
future.completeExceptionally(e);
return;
}
}, 0, retryDelay, TimeUnit.MILLISECONDS);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public static WorkFlowStatusResponseDTO waitWorkflowStatusAsync(WorkflowApi work
return waitWorkflowStatusAsync(workflowApi, workFlowExecutionId, StatusEnum.COMPLETED);
}

public static WorkFlowStatusResponseDTO waitWorkflowStatusAsync(WorkflowApi workflowApi, UUID workFlowExecutionId,
long maxRetryTimeInMs) {
return waitWorkflowStatusAsync(workflowApi, workFlowExecutionId);
}

/**
* Invokes @see com.redhat.parodos.sdk.api.WorkflowApi#getStatusAsync(String,
* ApiCallback<WorkFlowStatusResponseDTO>) and retries for 60 seconds.
Expand All @@ -144,8 +149,13 @@ public static WorkFlowStatusResponseDTO waitWorkflowStatusAsync(WorkflowApi work
try (var executorService = new RetryExecutorService<WorkFlowStatusResponseDTO>()) {
Callable<WorkFlowStatusResponseDTO> task = () -> {
WorkFlowStatusResponseDTO status = workflowApi.getStatus(workFlowExecutionId);
if (status.getStatus() == StatusEnum.IN_PROGRESS) {
throw new InProgrssStatusException(
"Workflow status is still in progress, not yet in state: " + expectedStatus);
}
if (status.getStatus() != expectedStatus) {
throw new ApiException("Workflow status is not " + expectedStatus);
throw new WrongStatusException(
"Workflow status is not " + expectedStatus + ", it is " + status.getStatus());
}
return status;
};
Expand Down Expand Up @@ -236,4 +246,20 @@ public static ProjectResponseDTO getProjectAsync(ApiClient apiClient, String pro
return testProject;
}

public static class InProgrssStatusException extends Exception {

public InProgrssStatusException(String message) {
super(message);
}

}

public static class WrongStatusException extends Exception {

public WrongStatusException(String message) {
super(message);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public class AdGroupsWorkFlowTask extends BaseInfrastructureWorkFlowTask {
@Override
public WorkReport execute(WorkContext workContext) {
log.info("AdGroupsWorkFlowTask");
if (!validateWorkflowParameters(workContext)) {
log.warn("Missing keys in context for workflowExecution {}, context: {}", getMainExecutionId(),
workContext);
return new DefaultWorkReport(WorkStatus.FAILED, workContext);
}
return new DefaultWorkReport(WorkStatus.COMPLETED, workContext);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public class NamespaceWorkFlowTask extends BaseInfrastructureWorkFlowTask {
@Override
public WorkReport execute(WorkContext workContext) {
log.info("NamespaceWorkFlowTask");
if (!validateWorkflowParameters(workContext)) {
log.warn("Missing keys in context for workflowExecution {}, context: {}", getMainExecutionId(),
workContext);
return new DefaultWorkReport(WorkStatus.FAILED, workContext);
}
return new DefaultWorkReport(WorkStatus.COMPLETED, workContext);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public class SslCertificationWorkFlowTask extends BaseInfrastructureWorkFlowTask
@Override
public WorkReport execute(WorkContext workContext) {
log.info("SslCertificationWorkFlowTask");
if (!validateWorkflowParameters(workContext)) {
log.warn("Missing keys in context for workflowExecution {}, context: {}", getMainExecutionId(),
workContext);
return new DefaultWorkReport(WorkStatus.FAILED, workContext);
}
return new DefaultWorkReport(WorkStatus.COMPLETED, workContext);
}

Expand Down
6 changes: 4 additions & 2 deletions workflow-service-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ Class | Method | HTTP request | Description
*WorkflowApi* | [**getStatus**](docs/WorkflowApi.md#getStatus) | **GET** /api/v1/workflows/{workFlowExecutionId}/status | Returns a workflow status
*WorkflowApi* | [**getStatusByProjectId**](docs/WorkflowApi.md#getStatusByProjectId) | **GET** /api/v1/workflows | Returns workflows by project id
*WorkflowApi* | [**getWorkflowParameters**](docs/WorkflowApi.md#getWorkflowParameters) | **GET** /api/v1/workflows/{workFlowExecutionId}/context | Returns workflow context parameters
*WorkflowApi* | [**restartWorkFlow**](docs/WorkflowApi.md#restartWorkFlow) | **POST** /api/v1/workflows/{workFlowExecutionId} | Restart a workflow execution with same parameters
*WorkflowApi* | [**updateWorkFlowCheckerTaskStatus**](docs/WorkflowApi.md#updateWorkFlowCheckerTaskStatus) | **POST** /api/v1/workflows/{workFlowExecutionId}/checkers/{workFlowCheckerTaskName} | Updates a workflow checker task status
*WorkflowDefinitionApi* | [**getWorkFlowDefinitionById**](docs/WorkflowDefinitionApi.md#getWorkFlowDefinitionById) | **GET** /api/v1/workflowdefinitions/{id} | Returns information about a workflow definition by id
*WorkflowDefinitionApi* | [**getWorkFlowDefinitions**](docs/WorkflowDefinitionApi.md#getWorkFlowDefinitions) | **GET** /api/v1/workflowdefinitions | Returns a list of workflow definition
Expand Down Expand Up @@ -163,10 +164,11 @@ Class | Method | HTTP request | Description
- [WorkStatusResponseDTO](docs/WorkStatusResponseDTO.md)


<a id="documentation-for-authorization"></a>
## Documentation for Authorization

All endpoints do not require authorization.
Authentication schemes defined for the API:
Endpoints do not require authorization.


## Recommendation

Expand Down
67 changes: 65 additions & 2 deletions workflow-service-sdk/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,48 @@ paths:
- Workflow
x-content-type: application/json
x-accepts: application/json
/api/v1/workflows/{workFlowExecutionId}:
post:
operationId: restartWorkFlow
parameters:
- explode: false
in: path
name: workFlowExecutionId
required: true
schema:
format: uuid
type: string
style: simple
responses:
"202":
content:
application/json:
schema:
$ref: '#/components/schemas/WorkFlowExecutionResponseDTO'
description: Accepted
"400":
content:
'*/*':
schema:
$ref: '#/components/schemas/ErrorMessageDTO'
description: Bad Request
"401":
description: Unauthorized
"403":
description: Forbidden
"404":
content: {}
description: Not Found
"409":
content:
'*/*':
schema:
$ref: '#/components/schemas/ErrorMessageDTO'
description: Conflict
summary: Restart a workflow execution with same parameters
tags:
- Workflow
x-accepts: application/json
/api/v1/workflows/{workFlowExecutionId}/checkers/{workFlowCheckerTaskName}:
post:
operationId: updateWorkFlowCheckerTaskStatus
Expand Down Expand Up @@ -1493,14 +1535,20 @@ components:
workFlowName: workFlowName
invokingExecutionId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91
works:
- arguments:
- works:
- null
- null
arguments:
- value: value
key: key
- value: value
key: key
type: TASK
workName: workName
- arguments:
- works:
- null
- null
arguments:
- value: value
key: key
- value: value
Expand Down Expand Up @@ -1575,6 +1623,7 @@ components:
type: object
WorkFlowStatusResponseDTO:
example:
originalExecutionId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91
workFlowName: workFlowName
works:
- alertMessage: alertMessage
Expand All @@ -1594,11 +1643,18 @@ components:
type: TASK
status: FAILED
workFlowExecutionId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91
restartedCount: 0
message: message
status: FAILED
properties:
message:
type: string
originalExecutionId:
format: uuid
type: string
restartedCount:
format: int32
type: integer
status:
enum:
- FAILED
Expand Down Expand Up @@ -1654,6 +1710,9 @@ components:
type: object
WorkRequestDTO:
example:
works:
- null
- null
arguments:
- value: value
key: key
Expand All @@ -1673,6 +1732,10 @@ components:
type: string
workName:
type: string
works:
items:
$ref: '#/components/schemas/WorkRequestDTO'
type: array
type: object
WorkStatusResponseDTO:
example:
Expand Down
2 changes: 1 addition & 1 deletion workflow-service-sdk/docs/LoginApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ All URIs are relative to *http://localhost:8080*
| [**login**](LoginApi.md#login) | **GET** /api/v1/login | Login |


<a name="login"></a>
<a id="login"></a>
# **login**
> login()
Expand Down
4 changes: 2 additions & 2 deletions workflow-service-sdk/docs/ProjectAccessApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ All URIs are relative to *http://localhost:8080*
| [**updateProjectAccessStatus**](ProjectAccessApi.md#updateProjectAccessStatus) | **POST** /api/v1/projects/access/{id}/status | Update status of a specified project access request |


<a name="getProjectAccessStatus"></a>
<a id="getProjectAccessStatus"></a>
# **getProjectAccessStatus**
> AccessStatusResponseDTO getProjectAccessStatus(id)
Expand Down Expand Up @@ -72,7 +72,7 @@ No authorization required
| **404** | Not found | - |
| **409** | Conflict | - |

<a name="updateProjectAccessStatus"></a>
<a id="updateProjectAccessStatus"></a>
# **updateProjectAccessStatus**
> updateProjectAccessStatus(id, accessStatusRequestDTO)
Expand Down
12 changes: 6 additions & 6 deletions workflow-service-sdk/docs/ProjectApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ All URIs are relative to *http://localhost:8080*
| [**updateUserRolesToProject**](ProjectApi.md#updateUserRolesToProject) | **POST** /api/v1/projects/{id}/users | Update user roles in project |


<a name="createAccessRequestToProject"></a>
<a id="createAccessRequestToProject"></a>
# **createAccessRequestToProject**
> AccessResponseDTO createAccessRequestToProject(id, accessRequestDTO)
Expand Down Expand Up @@ -78,7 +78,7 @@ No authorization required
| **404** | Not found | - |
| **409** | Conflict | - |

<a name="createProject"></a>
<a id="createProject"></a>
# **createProject**
> ProjectResponseDTO createProject(projectRequestDTO)
Expand Down Expand Up @@ -142,7 +142,7 @@ No authorization required
| **404** | Not Found | - |
| **409** | Conflict | - |

<a name="getProjectById"></a>
<a id="getProjectById"></a>
# **getProjectById**
> ProjectResponseDTO getProjectById(id)
Expand Down Expand Up @@ -207,7 +207,7 @@ No authorization required
| **404** | Not found | - |
| **409** | Conflict | - |

<a name="getProjects"></a>
<a id="getProjects"></a>
# **getProjects**
> List&lt;ProjectResponseDTO&gt; getProjects()
Expand Down Expand Up @@ -269,7 +269,7 @@ No authorization required
| **404** | Not Found | - |
| **409** | Conflict | - |

<a name="removeUsersFromProject"></a>
<a id="removeUsersFromProject"></a>
# **removeUsersFromProject**
> ProjectUserRoleResponseDTO removeUsersFromProject(id, requestBody)
Expand Down Expand Up @@ -335,7 +335,7 @@ No authorization required
| **404** | Not found | - |
| **409** | Conflict | - |

<a name="updateUserRolesToProject"></a>
<a id="updateUserRolesToProject"></a>
# **updateUserRolesToProject**
> ProjectUserRoleResponseDTO updateUserRolesToProject(id, userRoleRequestDTO)
Expand Down
2 changes: 2 additions & 0 deletions workflow-service-sdk/docs/WorkFlowStatusResponseDTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
|**message** | **String** | | [optional] |
|**originalExecutionId** | **UUID** | | [optional] |
|**restartedCount** | **Integer** | | [optional] |
|**status** | [**StatusEnum**](#StatusEnum) | | [optional] |
|**workFlowExecutionId** | **UUID** | | [optional] |
|**workFlowName** | **String** | | [optional] |
Expand Down
1 change: 1 addition & 0 deletions workflow-service-sdk/docs/WorkRequestDTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
|**arguments** | [**List&lt;ArgumentRequestDTO&gt;**](ArgumentRequestDTO.md) | | [optional] |
|**type** | [**TypeEnum**](#TypeEnum) | | [optional] |
|**workName** | **String** | | [optional] |
|**works** | [**List&lt;WorkRequestDTO&gt;**](WorkRequestDTO.md) | | [optional] |



Expand Down
Loading

0 comments on commit 224b9e4

Please sign in to comment.