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

Rewrite complex flow #240

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package com.redhat.parodos.examples.integration;

import com.redhat.parodos.examples.integration.utils.ExamplesUtils;
import com.redhat.parodos.sdk.api.ProjectApi;
import com.redhat.parodos.sdk.api.WorkflowApi;
import com.redhat.parodos.sdk.api.WorkflowDefinitionApi;
import com.redhat.parodos.sdk.invoker.ApiCallback;
import com.redhat.parodos.sdk.invoker.ApiClient;
import com.redhat.parodos.sdk.invoker.ApiException;
import com.redhat.parodos.sdk.invoker.Configuration;
import com.redhat.parodos.sdk.model.ArgumentRequestDTO;
import com.redhat.parodos.sdk.model.ProjectRequestDTO;
import com.redhat.parodos.sdk.model.ProjectResponseDTO;
import com.redhat.parodos.sdk.model.WorkFlowDefinitionResponseDTO;
import com.redhat.parodos.sdk.model.WorkFlowRequestDTO;
import com.redhat.parodos.sdk.model.WorkFlowResponseDTO;
import com.redhat.parodos.sdk.model.WorkFlowResponseDTO.WorkStatusEnum;
import com.redhat.parodos.sdk.model.WorkFlowStatusResponseDTO;
import com.redhat.parodos.sdk.model.WorkRequestDTO;
import com.redhat.parodos.workflow.utils.CredUtils;
import com.redhat.parodos.workflows.work.WorkStatus;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpHeaders;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import static com.redhat.parodos.examples.integration.utils.ExamplesUtils.getProjectByNameAndDescription;
import static com.redhat.parodos.examples.integration.utils.ExamplesUtils.waitAsyncResponse;
import static com.redhat.parodos.examples.integration.utils.ExamplesUtils.waitProjectStart;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* @author Gloria Ciavarrini (Github: gciavarrini)
*/
@Slf4j
public class ComplexWorkFlow {

private static final String projectName = "project-1";

private static final String projectDescription = "an example project";

private ApiClient apiClient;

@Before
public void setUp() throws IOException {
apiClient = Configuration.getDefaultApiClient();
apiClient.addDefaultHeader(HttpHeaders.AUTHORIZATION, "Basic " + CredUtils.getBase64Creds("test", "test"));
}

@Test
public void runComplexWorkFlow() throws ApiException, InterruptedException {
log.info("Running complex flow");

ProjectResponseDTO testProject = ExamplesUtils.commonProjectAPI(apiClient, projectName, projectDescription);

WorkflowApi workflowApi = new WorkflowApi();
log.info("******** Running The Complex WorkFlow ********");

log.info("Running the Assessment to see what WorkFlows are eligible for this situation:");

// Define WorkFlowRequest
WorkFlowRequestDTO workFlowRequestDTO = new WorkFlowRequestDTO();
workFlowRequestDTO.setProjectId(testProject.getId());
workFlowRequestDTO.setWorkFlowName("onboardingMasterAssessment_ASSESSMENT_WORKFLOW");
workFlowRequestDTO.setWorks(List.of(WorkRequestDTO.builder()
.arguments(List.of(ArgumentRequestDTO.builder().key("GIT_REPO_URL").value("git_repo_url").build()))
.build()));

WorkFlowResponseDTO workFlowResponseDTO = workflowApi.execute(workFlowRequestDTO);
assertEquals(WorkStatusEnum.COMPLETED, workFlowResponseDTO.getWorkStatus());
log.info("workflow finished successfully with response: {}", workFlowResponseDTO);
if (workFlowResponseDTO.getWorkFlowOptions() == null
|| workFlowResponseDTO.getWorkStatus() != WorkStatusEnum.COMPLETED) {
fail("There is no valid INFRASTRUCTURE_OPTION");
}

String infrastructureOption = workFlowResponseDTO.getWorkFlowOptions().getNewOptions().get(0).getWorkFlowName();
log.info("The Following Option Is Available: {}", infrastructureOption);

log.info("Running the onboarding WorkFlow");
log.info("executes 3 tasks in Parallel with a WorkFlowChecker");
WorkflowDefinitionApi workflowDefinitionApi = new WorkflowDefinitionApi();
List<WorkFlowDefinitionResponseDTO> workFlowDefinitions = workflowDefinitionApi
.getWorkFlowDefinitions(infrastructureOption);

assertNotNull(workFlowDefinitions);
assertTrue(workFlowDefinitions.size() > 0);
assertNotNull("There is no valid Onboarding workflow id", workFlowDefinitions.get(0).getId());
assertEquals("There is no valid Onboarding workflow name", workFlowDefinitions.get(0).getName(),
infrastructureOption);
log.info("Onboarding workflow id {}", workFlowDefinitions.get(0).getId());
log.info("Onboarding workflow name {}", workFlowDefinitions.get(0).getName());

WorkRequestDTO work1 = new WorkRequestDTO();
work1.setWorkName("certWorkFlowTask");
work1.setArguments(Arrays.asList(new ArgumentRequestDTO().key("user-id").value("test-user-id"),
new ArgumentRequestDTO().key("api-server").value("api.com")));

WorkRequestDTO work2 = new WorkRequestDTO();
work2.setWorkName("adGroupWorkFlowTask");
work2.setArguments(Arrays.asList(new ArgumentRequestDTO().key("user-id").value("test-user-id"),
new ArgumentRequestDTO().key("api-server").value("api.com")));

WorkRequestDTO work3 = new WorkRequestDTO();
work3.setWorkName("dynatraceWorkFlowTask");
work3.setArguments(Arrays.asList(new ArgumentRequestDTO().key("user-id").value("test-user-id"),
new ArgumentRequestDTO().key("api-server").value("api.com")));

workFlowRequestDTO.setProjectId(testProject.getId());
workFlowRequestDTO.setWorkFlowName(workFlowDefinitions.get(0).getName());
workFlowRequestDTO.setWorks(Arrays.asList(work1, work2, work3));
workFlowResponseDTO = workflowApi.execute(workFlowRequestDTO);

assertNotNull("There is no valid WorkFlowExecutionId", workFlowResponseDTO.getWorkFlowExecutionId());
assertEquals(workFlowResponseDTO.getWorkStatus(), WorkStatusEnum.IN_PROGRESS);
log.info("Onboarding workflow execution id: {}", workFlowResponseDTO.getWorkFlowExecutionId());

WorkFlowResponseDTO finalWorkFlowResponseDTO = workFlowResponseDTO;

WorkFlowStatusResponseDTO workFlowStatusResponseDTO = waitAsyncResponse(
new ExamplesUtils.FuncExecutor<WorkFlowStatusResponseDTO>() {
@Override
public boolean check(WorkFlowStatusResponseDTO result) {
return !result.getStatus().equals(WorkStatus.COMPLETED.toString());
}

@Override
public void execute(ApiCallback<WorkFlowStatusResponseDTO> callback) throws ApiException {
workflowApi.getStatusAsync(finalWorkFlowResponseDTO.getWorkFlowExecutionId(), callback);
}
});

assertNotNull(workFlowStatusResponseDTO);
assertNotNull(workFlowStatusResponseDTO.getWorkFlowExecutionId());
assertEquals(WorkStatusEnum.COMPLETED.toString(), workFlowStatusResponseDTO.getStatus());
log.info("Onboarding workflow execution completed with status {}", workFlowStatusResponseDTO.getStatus());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.List;

import static com.redhat.parodos.examples.integration.utils.ExamplesUtils.getProjectByNameAndDescription;
import static com.redhat.parodos.examples.integration.utils.ExamplesUtils.waitProjectStart;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand Down Expand Up @@ -58,40 +59,7 @@ public void setUp() throws IOException {
public void runSimpleWorkFlow() throws ApiException, InterruptedException {
log.info("Running simple flow");

ProjectApi projectApi = new ProjectApi(apiClient);

ExamplesUtils.waitProjectStart(projectApi);
log.info("Project is ✔️ on {}", apiClient.getBasePath());

ProjectResponseDTO testProject;

// RETRIEVE ALL PROJECTS AVAILABLE
log.info("Get all available projects");
List<ProjectResponseDTO> projects = projectApi.getProjects();
// CHECK IF testProject ALREADY EXISTS
testProject = getProjectByNameAndDescription(projects, projectName, projectDescription);

// CREATE PROJECT "Test Project Name" IF NOT EXISTS
if (testProject == null) {
log.info("There are no projects. Creating project {}", projectName);
// DEFINE A TEST PROJECT REQUEST
ProjectRequestDTO projectRequestDTO = new ProjectRequestDTO();
projectRequestDTO.setName(projectName);
projectRequestDTO.setDescription(projectDescription);

ProjectResponseDTO projectResponseDTO = projectApi.createProject(projectRequestDTO);
assertNotNull(projectResponseDTO);
assertEquals(projectName, projectResponseDTO.getName());
assertEquals(projectDescription, projectResponseDTO.getDescription());
log.info("Project {} successfully created", projectName);
}

// ASSERT PROJECT "testProject" IS PRESENT
projects = projectApi.getProjects();
log.debug("PROJECTS: {}", projects);
assertTrue(projects.size() > 0);
testProject = getProjectByNameAndDescription(projects, projectName, projectDescription);
assertNotNull(testProject);
ProjectResponseDTO testProject = ExamplesUtils.commonProjectAPI(apiClient, projectName, projectDescription);

// GET simpleSequentialWorkFlow DEFINITIONS
WorkflowDefinitionApi workflowDefinitionApi = new WorkflowDefinitionApi();
Expand Down Expand Up @@ -143,6 +111,7 @@ public void runSimpleWorkFlow() throws ApiException, InterruptedException {

WorkflowApi workflowApi = new WorkflowApi();
log.info("******** Running The Simple Sequence Flow ********");

WorkFlowResponseDTO workFlowResponseDTO = workflowApi.execute(workFlowRequestDTO);

assertNotNull(workFlowResponseDTO.getWorkFlowExecutionId());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,65 +1,70 @@

package com.redhat.parodos.examples.integration.utils;

import com.redhat.parodos.sdk.api.ProjectApi;
import com.redhat.parodos.sdk.invoker.ApiCallback;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.redhat.parodos.sdk.invoker.ApiClient;
import com.redhat.parodos.sdk.invoker.ApiException;
import com.redhat.parodos.sdk.model.ProjectRequestDTO;
import com.redhat.parodos.sdk.model.ProjectResponseDTO;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Strings;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.Nullable;

import static org.junit.Assert.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import com.redhat.parodos.sdk.api.ProjectApi;
import com.redhat.parodos.sdk.invoker.ApiCallback;
import com.redhat.parodos.sdk.invoker.ApiException;
import org.assertj.core.util.Strings;
import com.redhat.parodos.sdk.model.ProjectResponseDTO;
import lombok.Data;

/**
* @author Gloria Ciavarrini (Github: gciavarrini)
*/
@Slf4j
public final class ExamplesUtils {

public static void waitProjectStart(ProjectApi projectApi) throws ApiException, InterruptedException {
AsyncResult asyncResult = new AsyncResult();
public static <T> T waitAsyncResponse(FuncExecutor<T> f) throws ApiException, InterruptedException {
AsyncResult<T> asyncResult = new AsyncResult<>();
Lock lock = new ReentrantLock();
Condition response = lock.newCondition();
ApiCallback<List<ProjectResponseDTO>> apiCallback = new ApiCallback<>() {
AtomicInteger failureCounter = new AtomicInteger(0);
ApiCallback<T> apiCallback = new ApiCallback<T>() {

@Override
public void onFailure(ApiException e, int statusCode, Map<String, List<String>> responseHeaders) {
int i = failureCounter.incrementAndGet();
if (i >= 100) {
asyncResult.setError(e.getMessage());

try {
f.execute(this);
}
catch (ApiException apie) {
asyncResult.setError(apie.getMessage());
signal();
}
else {
}

@Override
public void onSuccess(T result, int statusCode, Map<String, List<String>> responseHeaders) {
if (f.check(result)) {
try {
projectApi.getProjectsAsync(this);
f.execute(this);
}
catch (ApiException apie) {
asyncResult.setError(apie.getMessage());
signal();
}
}
}

@Override
public void onSuccess(List<ProjectResponseDTO> result, int statusCode,
Map<String, List<String>> responseHeaders) {
signal();
else {
asyncResult.setStatusCode(statusCode);
asyncResult.setResult(result);
asyncResult.setError(null);
signal();
}
}

@Override
Expand All @@ -80,18 +85,23 @@ private void signal() {
}
}
};
projectApi.getProjectsAsync(apiCallback);
f.execute(apiCallback);
lock.lock();
try {
// should be more than enough
response.await(60, TimeUnit.SECONDS);
if (asyncResult.getError() != null) {
fail("An error occurred while executing getProjectsAsync: " + asyncResult.getError());
fail("An error occurred while executing waitAsyncResponse: " + asyncResult.getError());
}
}
finally {
lock.unlock();
}
return asyncResult.getResult();
}

public static void waitProjectStart(ProjectApi projectApi) throws InterruptedException, ApiException {
waitAsyncResponse((FuncExecutor<List<ProjectResponseDTO>>) callback -> projectApi.getProjectsAsync(callback));
}

@Nullable
Expand All @@ -104,10 +114,24 @@ public static ProjectResponseDTO getProjectByNameAndDescription(List<ProjectResp
}

@Data
private static class AsyncResult {
private static class AsyncResult<T> {

private String error;

T result;

int statusCode;

}

public interface FuncExecutor<T> {

void execute(ApiCallback<T> callback) throws ApiException;

default boolean check(T result) {
return true;
}

}

public static ProjectResponseDTO commonProjectAPI(ApiClient apiClient, String projectName,
Expand Down