Commit e1a18efb authored by Anastasiia Gelmut's avatar Anastasiia Gelmut
Browse files

Merge branch 'master' into gcp-can't-trigger-workflow-with-dagname-property

parents 72dcaef0 80ab284f
Pipeline #34670 failed with stages
in 44 minutes and 3 seconds
......@@ -116,6 +116,7 @@ The following software have components provided under the terms of this license:
- Jakarta Bean Validation API (from https://beanvalidation.org)
- Java Native Access (from https://github.com/java-native-access/jna)
- Java Native Access Platform (from https://github.com/java-native-access/jna)
- Java UUID Generator (from http://wiki.fasterxml.com/JugHome)
- Javassist (from http://www.javassist.org/)
- Joda-Time (from http://www.joda.org/joda-time/)
- Json Path (from https://github.com/jayway/JsonPath)
......@@ -150,8 +151,8 @@ The following software have components provided under the terms of this license:
- Microsoft Azure Java Core Library (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure Netty HTTP Client Library (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for SQL API of Azure Cosmos DB Service (from https://github.com/Azure/azure-sdk-for-java)
- Mockito (from http://mockito.org)
- Mockito (from http://www.mockito.org)
- Mockito (from http://mockito.org)
- Netty Reactive Streams HTTP support (from )
- Netty Reactive Streams Implementation (from )
- Netty/Buffer (from http://netty.io/)
......@@ -512,6 +513,7 @@ The following software have components provided under the terms of this license:
- Animal Sniffer Annotations (from )
- Azure AD Spring Security Integration Spring Boot Starter (from https://github.com/Microsoft/azure-spring-boot)
- Azure Java Client Authentication Library for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java)
- Azure Java Client Runtime for ARM (from https://github.com/Azure/autorest-clientruntime-for-java)
- Azure Java Client Runtime for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java)
- Azure Metrics Spring Boot Starter (from https://github.com/Microsoft/azure-spring-boot)
- Azure Spring Boot AutoConfigure (from https://github.com/Microsoft/azure-spring-boot)
......@@ -533,12 +535,14 @@ The following software have components provided under the terms of this license:
- Microsoft Azure Java Core Library (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure Netty HTTP Client Library (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK annotations (from https://github.com/Microsoft/java-api-annotations)
- Microsoft Azure SDK for EventGrid Management (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for SQL API of Azure Cosmos DB Service (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for Service Bus (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for eventgrid (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for Blob Storage (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for File Share Storage (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for Identity (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for KeyVault Keys (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for KeyVault Secrets (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure common module for Storage (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure internal Avro module for Storage (from https://github.com/Azure/azure-sdk-for-java)
......@@ -553,6 +557,8 @@ The following software have components provided under the terms of this license:
- Spongy Castle (from http://rtyley.github.io/spongycastle/)
- Spring Data for Azure Cosmos DB SQL API (from https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/cosmos/azure-spring-data-cosmos)
- adal4j (from https://github.com/AzureAD/azure-activedirectory-library-for-java)
- azure-documentdb (from https://azure.microsoft.com/en-us/services/cosmos-db/)
- documentdb-bulkexecutor (from http://azure.microsoft.com/en-us/services/documentdb/)
- jsoup (from http://jsoup.org/)
- micrometer-core (from https://github.com/micrometer-metrics/micrometer)
- mockito-inline (from https://github.com/mockito/mockito)
......@@ -623,11 +629,13 @@ The following software have components provided under the terms of this license:
- Joda-Time (from http://www.joda.org/joda-time/)
- LatencyUtils (from http://latencyutils.github.io/LatencyUtils/)
- Microsoft Application Insights Java SDK Core (from https://github.com/Microsoft/ApplicationInsights-Java)
- Microsoft Azure SDK for EventGrid Management (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure SDK for SQL API of Azure Cosmos DB Service (from https://github.com/Azure/azure-sdk-for-java)
- Microsoft Azure client library for Blob Storage (from https://github.com/Azure/azure-sdk-for-java)
- Project Lombok (from https://projectlombok.org)
- Spring Web (from https://github.com/spring-projects/spring-framework)
- StAX API (from http://stax.codehaus.org/)
- azure-documentdb (from https://azure.microsoft.com/en-us/services/cosmos-db/)
- msal4j (from https://github.com/AzureAD/microsoft-authentication-library-for-java)
- reactive-streams (from http://www.reactive-streams.org/)
......
......@@ -31,7 +31,7 @@
<properties>
<azure.version>2.1.7</azure.version>
<osdu.corelibazure.version>0.0.56</osdu.corelibazure.version>
<osdu.corelibazure.version>0.8.0-SNAPSHOT</osdu.corelibazure.version>
<azure.appservice.resourcegroup />
<azure.appservice.plan />
<azure.appservice.appname />
......
......@@ -16,10 +16,10 @@ public class WorkflowTasksSharingApi {
@Autowired
private IWorkflowTasksSharingService workflowTasksSharingService;
@GetMapping("/{id}/workflowRun/{runId}/getSignedUrl")
@GetMapping("/{workflow_name}/workflowRun/{runId}/getSignedUrl")
@PreAuthorize("@authorizationFilter.hasPermission('" + WorkflowRole.ADMIN + "')")
public GetSignedUrlResponse create(@PathVariable("id") final String workflowId,
public GetSignedUrlResponse create(@PathVariable("workflow_name") final String workflowName,
@PathVariable("runId") final String runId) {
return workflowTasksSharingService.getSignedUrl(workflowId, runId);
return workflowTasksSharingService.getSignedUrl(workflowName, runId);
}
}
......@@ -45,19 +45,13 @@ public class AzureBootstrapConfig {
}
@Bean
public BlobServiceClient blobServiceClient(SecretClient kv) {
public BlobServiceClient buildBlobServiceClient(SecretClient kv) {
final String partitionId = getPartitionId();
final String accountName = KeyVaultFacade.getSecretWithValidation(kv, String.format("%s-storage", partitionId));
final String accountKey = KeyVaultFacade.getSecretWithValidation(kv, String.format("%s-storage-key", partitionId));
StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
final String accountName = KeyVaultFacade.getSecretWithValidation(kv, String.format("%s-ingest-storage", partitionId));
final String accountKey = KeyVaultFacade.getSecretWithValidation(kv, String.format("%s-ingest-storage-key", partitionId));
final StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey);
String endpoint = String.format("https://%s.blob.core.windows.net", accountName);
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint(endpoint)
.credential(storageSharedKeyCredential)
.buildClient();
return blobServiceClient;
return new BlobServiceClientBuilder().endpoint(endpoint).credential(credential).buildClient();
}
@Bean
......
......@@ -5,10 +5,10 @@ import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@ConfigurationProperties("osdu.azure.blob")
@ConfigurationProperties("azure.storage")
@Configuration
@Getter
@Setter
public class BlobConfig {
private String tasksSharingContainer;
private String tasksSharingStorageAccount;
}
package org.opengroup.osdu.workflow.provider.azure.consts;
public class WorkflowRunConstants {
// Default number of workflow runs to send in the response when no limit is specified for get all run instances
public static final int DEFAULT_WORKFLOW_RUNS_LIMIT = 50;
// Maximum number of workflow runs to that can be sent in the response for get all run instances
public static final int MAX_WORKFLOW_RUNS_LIMIT = 500;
// As per the api spec, prefix for workflow run id cannot contain the word "backfill".
public static final String INVALID_WORKFLOW_RUN_PREFIX = "backfill";
}
......@@ -9,9 +9,10 @@ import lombok.*;
@EqualsAndHashCode
public class WorkflowTasksSharingDoc {
private String id;
private String workflowId;
private String partitionKey;
private String runId;
private String filePath;
private String workflowName;
private String containerId;
private Long createdAt;
private String createdBy;
}
......@@ -3,6 +3,8 @@ package org.opengroup.osdu.workflow.provider.azure.repository;
import com.azure.cosmos.CosmosException;
import com.azure.cosmos.models.SqlParameter;
import com.azure.cosmos.models.SqlQuerySpec;
import org.opengroup.osdu.azure.blobstorage.BlobStore;
import org.apache.http.HttpStatus;
import org.opengroup.osdu.azure.cosmosdb.CosmosStore;
import org.opengroup.osdu.azure.query.CosmosStorePageRequest;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
......@@ -19,6 +21,9 @@ import org.opengroup.osdu.workflow.provider.interfaces.IWorkflowRunRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component;
import org.opengroup.osdu.workflow.provider.azure.consts.WorkflowRunConstants;
import static org.opengroup.osdu.workflow.model.WorkflowStatusType.getCompletedStatusTypes;
import java.util.ArrayList;
import java.util.List;
......@@ -45,6 +50,12 @@ public class WorkflowRunRepository implements IWorkflowRunRepository {
@Autowired
private CursorUtils cursorUtils;
@Autowired
private WorkflowTasksSharingRepository workflowTasksSharingRepository;
@Autowired
private BlobStore blobStore;
@Override
public WorkflowRun saveWorkflowRun(final WorkflowRun workflowRun) {
final WorkflowRunDoc workflowRunDoc = buildWorkflowRunDoc(workflowRun);
......@@ -75,7 +86,7 @@ public class WorkflowRunRepository implements IWorkflowRunRepository {
@Override
public WorkflowRunsPage getWorkflowRunsByWorkflowName(String workflowName, Integer limit,
String cursor) {
if(cursor != null) {
if (cursor != null) {
cursor = cursorUtils.decodeCosmosCursor(cursor);
}
......@@ -84,16 +95,65 @@ public class WorkflowRunRepository implements IWorkflowRunRepository {
SqlQuerySpec sqlQuerySpec = new SqlQuerySpec(
"SELECT * from c where c.partitionKey = @workflowName ORDER BY c._ts DESC",
workflowNameParameter);
final Page<WorkflowRunDoc> pagedCustomOperatorDoc =
final Page<WorkflowRunDoc> pagedWorkflowRunDoc =
cosmosStore.queryItemsPage(dpsHeaders.getPartitionId(), cosmosConfig.getDatabase(),
cosmosConfig.getWorkflowRunCollection(), sqlQuerySpec, WorkflowRunDoc.class,
limit, cursor);
return buildWorkflowRunsPage(pagedCustomOperatorDoc);
return buildWorkflowRunsPage(pagedWorkflowRunDoc);
} catch (CosmosException e) {
throw new AppException(e.getStatusCode(), e.getMessage(), e.getMessage(), e);
}
}
@Override
public List<WorkflowRun> getAllRunInstancesOfWorkflow(String workflowName,
Map<String, Object> params) {
String queryText = buildQueryTextForGetAllRunInstances(params);
int limit = WorkflowRunConstants.DEFAULT_WORKFLOW_RUNS_LIMIT;
if (params.get("limit") != null) {
limit = Integer.parseInt((String) params.get("limit"));
if (limit > WorkflowRunConstants.MAX_WORKFLOW_RUNS_LIMIT) {
throw new AppException(HttpStatus.SC_BAD_REQUEST, "Invalid limit", String.format("Maximum limit allowed is %s", WorkflowRunConstants.MAX_WORKFLOW_RUNS_LIMIT));
}
}
String cursor = (String) params.get("cursor");
if (cursor != null) {
cursor = cursorUtils.decodeCosmosCursor(cursor);
}
try {
SqlParameter workflowNameParameter = new SqlParameter("@workflowName", workflowName);
SqlQuerySpec sqlQuerySpec = new SqlQuerySpec(queryText, workflowNameParameter);
final Page<WorkflowRunDoc> pagedWorkflowRunDoc =
cosmosStore.queryItemsPage(dpsHeaders.getPartitionId(), cosmosConfig.getDatabase(),
cosmosConfig.getWorkflowRunCollection(), sqlQuerySpec, WorkflowRunDoc.class,
limit, cursor);
return buildWorkflowRunsPage(pagedWorkflowRunDoc).getItems();
} catch (CosmosException e) {
throw new AppException(e.getStatusCode(), e.getMessage(), e.getMessage(), e);
}
}
private String buildQueryTextForGetAllRunInstances(Map<String, Object> params) {
String queryText = "SELECT * from c where c.partitionKey = @workflowName";
String prefix = (String) params.get("prefix");
if (prefix != null) {
if (prefix.contains(WorkflowRunConstants.INVALID_WORKFLOW_RUN_PREFIX)) {
throw new AppException(HttpStatus.SC_BAD_REQUEST, "Invalid prefix", "Prefix must not contain the word 'backfill'");
}
queryText = String.format("%s and startswith(c.id, '%s')", queryText, prefix);
}
String startTimeStamp = (String) params.get("startDate");
if (startTimeStamp != null) {
queryText = String.format("%s and c.startTimeStamp >= %s", queryText, startTimeStamp);
}
String endTimeStamp = (String) params.get("endDate");
if (endTimeStamp != null) {
queryText = String.format("%s and c.endTimeStamp <= %s", queryText, endTimeStamp);
}
queryText = String.format("%s ORDER BY c._ts DESC", queryText);
return queryText;
}
@Override
public void deleteWorkflowRuns(final String workflowName, final List<String> runIds) {
for(String runId: runIds) {
......@@ -115,13 +175,13 @@ public class WorkflowRunRepository implements IWorkflowRunRepository {
workflowRunDoc);
logger.info(LOGGER_NAME, String.format("Updated workflowRun with id : %s of workflowId: %s",
workflowRunDoc.getId(), workflowRunDoc.getWorkflowName()));
return getWorkflowRun(workflowRun.getWorkflowId(), workflowRun.getRunId());
}
@Override
public List<WorkflowRun> getAllRunInstancesOfWorkflow(String workflowName,
Map<String, Object> params) {
return getWorkflowRunsByWorkflowName(workflowName, 50, null).getItems();
// TODO [aaljain]: The feature for deleting container needs to be moved to service folder later
final WorkflowStatusType currentStatusType = workflowRun.getStatus();
if (getCompletedStatusTypes().contains(currentStatusType)) {
workflowTasksSharingRepository.deleteTasksSharingInfoContainer(dpsHeaders.getPartitionId(), workflowRun.getWorkflowName(), workflowRun.getRunId());
}
return getWorkflowRun(workflowRun.getWorkflowId(), workflowRun.getRunId());
}
private WorkflowRunDoc buildWorkflowRunDoc(final WorkflowRun workflowRun) {
......
......@@ -3,24 +3,29 @@ package org.opengroup.osdu.workflow.provider.azure.repository;
import com.azure.storage.blob.sas.BlobContainerSasPermission;
import org.opengroup.osdu.azure.blobstorage.BlobStore;
import org.opengroup.osdu.azure.cosmosdb.CosmosStore;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.workflow.provider.azure.config.BlobConfig;
import org.opengroup.osdu.workflow.exception.WorkflowNotFoundException;
import org.opengroup.osdu.workflow.provider.azure.config.CosmosConfig;
import org.opengroup.osdu.workflow.provider.azure.model.WorkflowTasksSharingDoc;
import org.opengroup.osdu.workflow.provider.azure.interfaces.IWorkflowTasksSharingRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.OffsetDateTime;
import java.util.Optional;
import java.util.UUID;
@Component
public class WorkflowTasksSharingRepository implements IWorkflowTasksSharingRepository {
private static final String LOGGER_NAME = WorkflowTasksSharingRepository.class.getName();
@Autowired
BlobStore blobStore;
@Autowired
DpsHeaders headers;
DpsHeaders dpsHeaders;
@Autowired
CosmosStore cosmosStore;
......@@ -29,35 +34,63 @@ public class WorkflowTasksSharingRepository implements IWorkflowTasksSharingRepo
CosmosConfig cosmosConfig;
@Autowired
BlobConfig blobConfig;
private JaxRsDpsLog logger;
@Override
public String getSignedUrl(String workflowId, String runId) {
final String dataPartitionId = headers.getPartitionId();
final String uuid = UUID.randomUUID().toString();
final String filePath = String.format("%s/%s/%s", workflowId, runId, uuid);
public String getSignedUrl(String workflowName, String runId) {
final String dataPartitionId = dpsHeaders.getPartitionId();
// TODO : Add support for using user provided expiry time and permissions (?)
int expiryDays = 7;
final int expiryDays = 7;
final OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(expiryDays);
final BlobContainerSasPermission permissions =
new BlobContainerSasPermission().setCreatePermission(true).setReadPermission(true)
.setWritePermission(true).setListPermission(true);
final String signedUrl =
blobStore.generatePreSignedURL(dataPartitionId, blobConfig.getTasksSharingContainer(), expiryTime, permissions);
//
// WorkflowTasksSharingDoc workflowTasksSharingDoc =
// WorkflowTasksSharingDoc.builder()
// .id(uuid)
// .workflowId(workflowId)
// .runId(runId)
// .filePath(filePath)
// .createdAt(System.currentTimeMillis())
// .createdBy(headers.getUserEmail())
// .build();
//
// cosmosStore.createItem(headers.getPartitionId(), cosmosConfig.getDatabase(),
// cosmosConfig.getWorkflowTasksSharingCollection(), workflowTasksSharingDoc.getWorkflowId(), workflowTasksSharingDoc);
return signedUrl;
// TODO : Add support for custom permission (?)
final BlobContainerSasPermission permissions = new BlobContainerSasPermission()
.setCreatePermission(true)
.setReadPermission(true)
.setWritePermission(true)
.setListPermission(true);
final Optional<WorkflowTasksSharingDoc> optionalWorkflowTasksSharingDoc =
cosmosStore.findItem(dataPartitionId, cosmosConfig.getDatabase(), cosmosConfig.getWorkflowTasksSharingCollection(), runId, workflowName, WorkflowTasksSharingDoc.class);
String containerId;
if (optionalWorkflowTasksSharingDoc.isPresent()) {
containerId = optionalWorkflowTasksSharingDoc.get().getContainerId();
} else {
containerId = UUID.randomUUID().toString();
blobStore.createBlobContainer(dataPartitionId, containerId);
WorkflowTasksSharingDoc workflowTasksSharingDocNewContainer = workflowTasksSharingDocBuilder(workflowName, runId, containerId);
cosmosStore.createItem(dataPartitionId, cosmosConfig.getDatabase(),
cosmosConfig.getWorkflowTasksSharingCollection(), workflowTasksSharingDocNewContainer.getPartitionKey(), workflowTasksSharingDocNewContainer);
}
return blobStore.generatePreSignedURL(dataPartitionId, containerId, expiryTime, permissions);
}
WorkflowTasksSharingDoc workflowTasksSharingDocBuilder(String workflowName, String runId, String containerId) {
return WorkflowTasksSharingDoc.builder()
.id(runId)
.partitionKey(workflowName)
.containerId(containerId)
.workflowName(workflowName)
.runId(runId)
.createdAt(System.currentTimeMillis())
.createdBy(dpsHeaders.getUserEmail())
.build();
}
public void deleteTasksSharingInfoContainer(String dataPartitionId, String workflowName, String runId) throws WorkflowNotFoundException {
final Optional<WorkflowTasksSharingDoc> optionalWorkflowTasksSharingDoc =
cosmosStore.findItem(dataPartitionId, cosmosConfig.getDatabase(), cosmosConfig.getWorkflowTasksSharingCollection(), runId, workflowName, WorkflowTasksSharingDoc.class);
if (optionalWorkflowTasksSharingDoc.isPresent()) {
String containerId = optionalWorkflowTasksSharingDoc.get().getContainerId();
blobStore.deleteBlobContainer(dataPartitionId, containerId);
cosmosStore.deleteItem(
dataPartitionId,
cosmosConfig.getDatabase(),
cosmosConfig.getWorkflowTasksSharingCollection(),
runId,
workflowName);
}
}
}
......@@ -3,8 +3,9 @@ package org.opengroup.osdu.workflow.provider.azure.service;
import org.opengroup.osdu.core.common.exception.BadRequestException;
import org.opengroup.osdu.workflow.model.WorkflowRun;
import org.opengroup.osdu.workflow.model.WorkflowStatusType;
import org.opengroup.osdu.workflow.provider.azure.interfaces.IWorkflowTasksSharingRepository;
import org.opengroup.osdu.workflow.provider.azure.interfaces.IWorkflowTasksSharingService;
import org.opengroup.osdu.workflow.provider.azure.interfaces.IWorkflowTasksSharingRepository;
import org.opengroup.osdu.workflow.provider.azure.model.GetSignedUrlResponse;
import org.opengroup.osdu.workflow.provider.interfaces.IWorkflowRunRepository;
import org.springframework.beans.factory.annotation.Autowired;
......
......@@ -35,7 +35,7 @@ osdu.azure.cosmosdb.ingestionStrategyCollection=IngestionStrategy
osdu.azure.cosmosdb.workflowStatusCollection=WorkflowStatus
osdu.azure.cosmosdb.workflowMetadataCollection=WorkflowV2
osdu.azure.cosmosdb.workflowRunCollection=WorkflowRunV2
osdu.azure.cosmosdb.workflowTasksSharingCollection=WorkflowTasksSharingInfo
osdu.azure.cosmosdb.workflowTasksSharingCollection=WorkflowTasksSharingInfoV2
osdu.azure.cosmosdb.customOperatorCollection=WorkflowCustomOperatorV2
# Azure fileshare configuration
......@@ -66,9 +66,6 @@ osdu.entitlements.appKey=${entitlements_service_api_key}
# Blobstore config
azure.blobStore.required=true
azure.storage.account-name=${storage_account}
# Storage container
osdu.azure.blob.tasksSharingContainer=workflow-tasks-sharing
azure.storage.tasksSharingStorageAccount=${tasks_sharing_storage_account}
osdu.azure.partitionId=opendes
......@@ -3,6 +3,9 @@ package org.opengroup.osdu.workflow.provider.azure.repository;
import com.azure.cosmos.models.SqlParameter;
import com.azure.cosmos.models.SqlQuerySpec;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Builder;
import lombok.Getter;
import org.apache.http.HttpStatus;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
......@@ -14,11 +17,14 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.opengroup.osdu.azure.cosmosdb.CosmosStore;
import org.opengroup.osdu.azure.query.CosmosStorePageRequest;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.http.AppError;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.workflow.exception.WorkflowRunNotFoundException;
import org.opengroup.osdu.workflow.model.WorkflowRun;
import org.opengroup.osdu.workflow.model.WorkflowRunsPage;
import org.opengroup.osdu.workflow.provider.azure.config.CosmosConfig;
import org.opengroup.osdu.workflow.provider.azure.consts.WorkflowRunConstants;
import org.opengroup.osdu.workflow.provider.azure.model.WorkflowRunDoc;
import org.opengroup.osdu.workflow.provider.azure.utils.CursorUtils;
import org.springframework.data.domain.Page;
......@@ -28,9 +34,12 @@ import org.springframework.data.domain.Sort;
import java.util.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.util.Assert.doesNotContain;
/**
* Tests for {@link WorkflowRunRepository}
......@@ -45,6 +54,10 @@ public class WorkflowRunRepositoryTest {
private static final String TEST_CURSOR = "dGVzdC1jdXJzb3I=";
private static final Integer TEST_LIMIT = 100;
private static final Long WORKFLOW_RUN_END_TIMESTAMP = 1600258424158L;
private static final String TEST_WORKFLOW_RUN_ID_PREFIX = "test-workflow-run-prefix";
private static final String TEST_WORKFLOW_RUN_START_DATE = "test-start-date";
private static final String TEST_WORKFLOW_RUN_END_DATE = "test-end-date";
private static final String WORKFLOW_RUN = "{\n" +
" \"workflowName\": \"test-workflow-name\",\n" +
" \"workflowId\": \"test-workflow-name\",\n" +
......@@ -97,6 +110,9 @@ public class WorkflowRunRepositoryTest {
@Mock
private CursorUtils cursorUtils;
@Mock
private WorkflowTasksSharingRepository workflowTasksSharingRepository;
@InjectMocks
private WorkflowRunRepository workflowRunRepository;
......@@ -175,9 +191,10 @@ public class WorkflowRunRepositoryTest {
eq(RUN_ID), eq(WORKFLOW_NAME), eq(WorkflowRunDoc.class));
verify(cosmosStore).replaceItem(eq(PARTITION_ID), eq(DATABASE_NAME),
eq(WORKFLOW_RUN_COLLECTION), eq(RUN_ID), eq(WORKFLOW_NAME), any(WorkflowRunDoc.class));
verify(workflowTasksSharingRepository, times(1)).deleteTasksSharingInfoContainer(eq(PARTITION_ID), eq(WORKFLOW_NAME), eq(RUN_ID));
verify(cosmosConfig,times(2)).getDatabase();
verify(cosmosConfig, times(2)).getWorkflowRunCollection();
verify(dpsHeaders, times(2)).getPartitionId();
verify(dpsHeaders, times(3)).getPartitionId();
assertThat(workflowRunDocArgumentCaptor.getValue().getStatus(), equalTo(response.getStatus().toString()));
assertThat(workflowRunDocArgumentCaptor.getValue().getId(), equalTo(response.getRunId()));
assertThat(workflowRunDocArgumentCaptor.getValue().getWorkflowName(), equalTo(response.getWorkflowId()));
......@@ -240,6 +257,199 @@ public class WorkflowRunRepositoryTest {
verify(dpsHeaders, times(runIds.size())).getPartitionId();
}
@Test
public void testGetAllRunInstancesOfWorkflow_givenValidParams() {
Page<WorkflowRunDoc> pagedWorkflowRunDoc = mock(Page.class);
CosmosStorePageRequest cosmosStorePageRequest = mock(CosmosStorePageRequest.class);
when(cosmosConfig.getDatabase()).thenReturn(DATABASE_NAME);
when(cosmosConfig.getWorkflowRunCollection()).thenReturn(WORKFLOW_RUN_COLLECTION);
when(dpsHeaders.getPartitionId()).thenReturn(PARTITION_ID);
when(cursorUtils.decodeCosmosCursor(eq(TEST_CURSOR))).thenReturn(TEST_CURSOR);
when(pagedWorkflowRunDoc.getPageable()).thenReturn(cosmosStorePageRequest);
GetAllRunInstancesParams getAllRunInstancesParams = GetAllRunInstancesParams.builder()
.limit(TEST_LIMIT)
.cursor(TEST_CURSOR)
.prefix(TEST_WORKFLOW_RUN_ID_PREFIX)
.startDate(TEST_WORKFLOW_RUN_START_DATE)
.endDate(TEST_WORKFLOW_RUN_END_DATE)
.build();
ArgumentCaptor<SqlQuerySpec> sqlQuerySpecArgumentCaptor = ArgumentCaptor.forClass(SqlQuerySpec.class);
when(cosmosStore.queryItemsPage(
eq(PARTITION_ID),
eq(DATABASE_NAME),
eq(WORKFLOW_RUN_COLLECTION),
any(SqlQuerySpec.class),
eq(WorkflowRunDoc.class),
eq(TEST_LIMIT),
eq(TEST_CURSOR))).thenReturn(pagedWorkflowRunDoc);
workflowRunRepository.getAllRunInstancesOfWorkflow(WORKFLOW_NAME, getAllRunInstancesParams.getParams());
verify(cosmosStore, times(1)).queryItemsPage(
eq(PARTITION_ID),
eq(DATABASE_NAME),
eq(WORKFLOW_RUN_COLLECTION),
sqlQuerySpecArgumentCaptor.capture(),
eq(WorkflowRunDoc.class),
eq(getAllRunInstancesParams.getLimit()),