Commit bd0ebfbd authored by David Diederich's avatar David Diederich
Browse files

Merge remote-tracking branch 'origin/master' into 78-upgrade-core-common-dependency

Conflicts:
	NOTICE
parents 8bf33afa 6c488e18
Pipeline #53277 passed with stages
in 39 minutes and 45 seconds
......@@ -25,7 +25,7 @@ variables:
OSDU_GCP_APPLICATION_NAME: os-storage
OSDU_GCP_DEFAULT_DATA_COUNTRY: US
# --- osdu specific variables for cloudrun storage w/o "/" at the end ---
OSDU_GCP_ENV_VARS: GOOGLE_AUDIENCES=$GOOGLE_AUDIENCE,AUTHORIZE_API=$OSDU_GCP_AUTHORIZE_API,LEGALTAG_API=$OSDU_GCP_LEGALTAG_API,STORAGE_HOSTNAME=$OSDU_GCP_STORAGE_HOSTNAME,CRS_API=$OSDU_GCP_CRS_API,DEFAULT_DATA_COUNTRY=$OSDU_GCP_DEFAULT_DATA_COUNTRY,REDIS_STORAGE_HOST=$REDIS_STORAGE_HOST,REDIS_GROUP_HOST=$REDIS_GROUP_HOST,PARTITION_API=$OSDU_GCP_PARTITION_API,POLICY_API=$OSDU_GCP_POLICY_API --vpc-connector=$OSDU_GCP_VPC_CONNECTOR
OSDU_GCP_ENV_VARS: GOOGLE_AUDIENCES=$GOOGLE_AUDIENCE,AUTHORIZE_API=$OSDU_GCP_ENTITLEMENTS_V2_URL,LEGALTAG_API=$OSDU_GCP_LEGALTAG_API,STORAGE_HOSTNAME=$OSDU_GCP_STORAGE_HOSTNAME,CRS_API=$OSDU_GCP_CRS_API,DEFAULT_DATA_COUNTRY=$OSDU_GCP_DEFAULT_DATA_COUNTRY,REDIS_STORAGE_HOST=$REDIS_STORAGE_HOST,REDIS_GROUP_HOST=$REDIS_GROUP_HOST,PARTITION_API=$OSDU_GCP_PARTITION_API,POLICY_API=$OSDU_GCP_POLICY_API,POLICY_ID=storage --vpc-connector=$OSDU_GCP_VPC_CONNECTOR
OSDU_GCP_TEST_SUBDIR: testing/$OSDU_GCP_SERVICE-test-$OSDU_GCP_VENDOR
OSDU_GCP_HELM_PACKAGE_CHARTS: "devops/gcp/deploy devops/gcp/configmap"
......
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright © 2020 Amazon Web Services
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Copyright 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License 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.
Unless required by applicable law or agreed to in writing, software
distributed under the License 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.
-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
......@@ -34,7 +35,7 @@
<id>gitlab-os-core-common-maven</id>
<url>https://community.opengroup.org/api/v4/projects/67/packages/maven</url>
</repository>
<repository>
<repository>
<id>gitlab-os-core-lib-aws-maven</id>
<url>https://community.opengroup.org/api/v4/projects/68/packages/maven</url>
</repository>
......@@ -63,15 +64,14 @@
</server>
</servers>
<!-- CodeArtifact doesn't support external repos yet that aren't Maven Central. ETA Q4 2020. -->
<!-- <mirrors> -->
<!-- <mirror> -->
<!-- <id>aws-osdu-dev-maven</id> -->
<!-- <name>aws-osdu-dev-maven</name> -->
<!-- <url>https://osdu-dev-888733619319.d.codeartifact.us-east-1.amazonaws.com/maven/osdu-maven/</url> -->
<!-- <mirrorOf>*,!gitlab-os-core-common-maven</mirrorOf> -->
<!-- </mirror> -->
<!-- </mirrors> -->
<mirrors>
<mirror>
<id>aws-osdu-dev-maven</id>
<name>aws-osdu-dev-maven</name>
<url>https://osdu-dev-${AWS_ACCOUNT_ID}.d.codeartifact.us-east-1.amazonaws.com/maven/osdu-maven/</url>
<mirrorOf>central,!gitlab-os-core-common-maven,!gitlab-os-core-lib-aws-maven</mirrorOf>
</mirror>
</mirrors>
<activeProfiles>
<activeProfile>credentialsConfiguration</activeProfile>
......
......@@ -58,7 +58,7 @@
<dependency>
<groupId>org.opengroup.osdu.core.aws</groupId>
<artifactId>os-core-lib-aws</artifactId>
<version>0.9.0</version>
<version>0.10.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
......
......@@ -60,7 +60,7 @@
<dependency>
<groupId>org.opengroup.osdu.core.aws</groupId>
<artifactId>os-core-lib-aws</artifactId>
<version>0.9.0</version>
<version>0.10.0-SNAPSHOT</version>
</dependency>
<dependency>
......
......@@ -23,8 +23,8 @@ import org.springframework.stereotype.Component;
@Component
public class GroupCache extends RedisCache<String, Groups> {
public GroupCache(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_GROUP_HOST, @Value("${aws.elasticache.cluster.port}") final String REDIS_GROUP_PORT) {
super(REDIS_GROUP_HOST, Integer.parseInt(REDIS_GROUP_PORT), 60, String.class, Groups.class);
public GroupCache(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_GROUP_HOST, @Value("${aws.elasticache.cluster.port}") final String REDIS_GROUP_PORT, @Value("${aws.elasticache.cluster.key}") final String REDIS_GROUP_KEY) {
super(REDIS_GROUP_HOST, Integer.parseInt(REDIS_GROUP_PORT), REDIS_GROUP_KEY, 60, String.class, Groups.class);
}
public static String getGroupCacheKey(DpsHeaders headers) {
......
......@@ -32,8 +32,8 @@ public class LegalTagCache implements ICache<String, String> {
private final MultiTenantCache<String> caches;
public LegalTagCache(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_LEGALTAG_HOST, @Value("${aws.elasticache.cluster.port}") final String REDIS_LEGALTAG_PORT) {
this.caches = new MultiTenantCache<>(new RedisCache<>(REDIS_LEGALTAG_HOST,Integer.parseInt(REDIS_LEGALTAG_PORT),
public LegalTagCache(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_LEGALTAG_HOST, @Value("${aws.elasticache.cluster.port}") final String REDIS_LEGALTAG_PORT, @Value("${aws.elasticache.cluster.key}") final String REDIS_LEGALTAG_KEY) {
this.caches = new MultiTenantCache<>(new RedisCache<>(REDIS_LEGALTAG_HOST,Integer.parseInt(REDIS_LEGALTAG_PORT), REDIS_LEGALTAG_KEY,
60 * 60,
String.class,
String.class));
......
......@@ -22,8 +22,8 @@ import org.springframework.stereotype.Component;
@Component
public class SchemaCache extends RedisCache<String, Schema> {
public SchemaCache(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_SCHEMA_HOST, @Value("${aws.elasticache.cluster.port}") final String REDIS_SCHEMA_PORT) {
super(REDIS_SCHEMA_HOST, Integer.parseInt(REDIS_SCHEMA_PORT), 60 * 60, String.class,
public SchemaCache(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_SCHEMA_HOST, @Value("${aws.elasticache.cluster.port}") final String REDIS_SCHEMA_PORT, @Value("${aws.elasticache.cluster.key}") final String REDIS_SCHEMA_KEY) {
super(REDIS_SCHEMA_HOST, Integer.parseInt(REDIS_SCHEMA_PORT), REDIS_SCHEMA_KEY, 60 * 60, String.class,
Schema.class);
}
......
......@@ -29,6 +29,7 @@ aws.s3.recordsBucket.ssm.relativePath=${RECORDS_BUCKET_SSM_RELATIVE_PATH:storage
## AWS ElastiCache configuration
aws.elasticache.cluster.endpoint=${CACHE_CLUSTER_ENDPOINT}
aws.elasticache.cluster.port=${CACHE_CLUSTER_PORT}
aws.elasticache.cluster.key=${CACHE_CLUSTER_KEY}
aws.ssm=${SSM_ENABLED}
aws.parameter.prefix=/osdu/${ENVIRONMENT}
......@@ -46,7 +47,9 @@ server.ssl.key-store-password=${SSL_KEY_STORE_PASSWORD:}
# Policy service properties
service.policy.enabled=true
POLICY_API=${ENTITLEMENTS_BASE_URL}/api/policy/v1
POLICY_API=${POLICY_BASE_URL}/api/policy/v1
POLICY_ID=storage
PARTITION_API=${ENTITLEMENTS_BASE_URL}/api/partition/v1
PARTITION_API=${PARTITION_BASE_URL}/api/partition/v1
aws.environment=${ENVIRONMENT}
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
\ No newline at end of file
......@@ -33,7 +33,7 @@
<azure.appservice.plan />
<azure.appservice.appname />
<azure.appservice.subscription />
<osdu.corelibazure.version>0.9.0</osdu.corelibazure.version>
<osdu.corelibazure.version>0.10.0-rc8</osdu.corelibazure.version>
<osdu.storage-core.version>0.10.0-SNAPSHOT</osdu.storage-core.version>
<junit.version>4.12</junit.version>
<mockito.version>1.10.19</mockito.version>
......
......@@ -14,11 +14,12 @@
package org.opengroup.osdu.storage.provider.azure;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.http.HttpStatus;
import org.opengroup.osdu.azure.blobstorage.BlobStore;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.entitlements.Acl;
......@@ -29,6 +30,7 @@ import org.opengroup.osdu.core.common.util.Crc32c;
import org.opengroup.osdu.storage.provider.azure.repository.GroupsInfoRepository;
import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage;
import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
......@@ -39,9 +41,6 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import org.slf4j.MDC;
import static org.apache.commons.codec.binary.Base64.encodeBase64;
......@@ -72,10 +71,10 @@ public class CloudStorageImpl implements ICloudStorage {
@Named("STORAGE_CONTAINER_NAME")
private String containerName;
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void write(RecordProcessing... recordsProcessing) {
validateRecordAcls(recordsProcessing);
List<Callable<Boolean>> tasks = new ArrayList<>();
String dataPartitionId = headers.getPartitionId();
for (RecordProcessing rp : recordsProcessing) {
......@@ -133,33 +132,6 @@ public class CloudStorageImpl implements ICloudStorage {
}
}
/**
* Ensures that the ACLs of the record are a subset of the ACLs
* @param records the records to validate
*/
private void validateRecordAcls(RecordProcessing... records) {
String[] groups = groupsInfoRepository.findById(headers.getPartitionId())
.orElseThrow(() -> new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown Tenant", "Tenant was not found"))
.getGroups();
Set<String> validGroups = Arrays.asList(groups)
.stream()
.map(group -> group.toLowerCase())
.collect(Collectors.toSet());
for (RecordProcessing record : records) {
for (String acl : record.getRecordMetadata().getAcl().getOwners()) {
String groupName = acl.split("@")[0].toLowerCase();
if (!validGroups.contains(groupName)) {
throw new AppException(
HttpStatus.SC_FORBIDDEN,
"Invalid ACL",
"Record ACL is not one of " + String.join(",", validGroups));
}
}
}
}
private boolean writeBlobThread(RecordProcessing rp, String dataPartitionId)
{
Gson gson = new GsonBuilder().serializeNulls().create();
......@@ -172,11 +144,16 @@ public class CloudStorageImpl implements ICloudStorage {
@Override
public Map<String, String> getHash(Collection<RecordMetadata> records) {
Gson gson = new Gson();
Map<String, String> hashes = new HashMap<>();
RecordData data;
for (RecordMetadata rm : records) {
String jsonData = this.read(rm, rm.getLatestVersion(), false);
RecordData data = gson.fromJson(jsonData, RecordData.class);
try {
data = objectMapper.readValue(jsonData, RecordData.class);
} catch (JsonProcessingException e){
logger.error(String.format("Error while converting metadata for record %s", rm.getId()), e);
continue;
}
String hash = getHash(data);
hashes.put(rm.getId(), hash);
}
......@@ -202,7 +179,6 @@ public class CloudStorageImpl implements ICloudStorage {
private String getHash(RecordData data) {
Gson gson = new Gson();
Crc32c checksumGenerator = new Crc32c();
String newRecordStr = gson.toJson(data);
byte[] bytes = newRecordStr.getBytes(StandardCharsets.UTF_8);
checksumGenerator.update(bytes, 0, bytes.length);
......
......@@ -80,7 +80,7 @@ public class MessageBusImpl implements IMessageBus {
DateTime.now(),
RECORDS_CHANGED_EVENT_DATA_VERSION
));
LOGGER.info("Event generated: " + messageId);
LOGGER.debug("Event generated: " + messageId);
// If a record change is not published (publishToEventGridTopic throws) we fail the job.
// This is done to make sure no notifications are missed.
......@@ -124,7 +124,7 @@ public class MessageBusImpl implements IMessageBus {
message.setContentType("application/json");
try {
LOGGER.info("Storage publishes message to Service Bus " + headers.getCorrelationId());
LOGGER.debug("Storage publishes message to Service Bus " + headers.getCorrelationId());
topicClientFactory.getClient(headers.getPartitionId(), pubSubConfig.getServiceBusTopic()).send(message);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
......
......@@ -72,7 +72,7 @@ public class LegalComplianceChangeServiceAzureImpl implements ILegalComplianceCh
for (RecordMetadata recordMetadata : recordsMetadata) {
recordsId.append(", ").append(recordMetadata.getId());
}
LOGGER.info("Record Updated Successfully {}",recordsId.substring(2));
LOGGER.debug("Record Updated Successfully {}",recordsId.substring(2));
this.pubSubclient.publishMessage(headers, pubsubInfos);
}
......
......@@ -150,15 +150,16 @@ public class EntitlementsAndCacheServiceImpl implements IEntitlementsExtensionSe
try {
groups = service.getGroups();
this.cache.put(cacheKey, groups);
this.logger.info("Entitlements cache miss");
this.logger.debug("Entitlements cache miss");
} catch (EntitlementsException e) {
HttpResponse response = e.getHttpResponse();
this.logger.error(String.format("Error requesting entitlements service %s", response));
throw new AppException(e.getHttpResponse().getResponseCode(), ERROR_REASON, ERROR_MSG, e);
} catch (RedisException ex) {
this.logger.error(String.format("Error putting key %s into redis: %s", cacheKey, ex.getMessage()), ex);
}
}
return groups;
}
......
......@@ -34,6 +34,7 @@ import org.opengroup.osdu.storage.logging.StorageAuditLogger;
import org.opengroup.osdu.storage.policy.service.IPolicyService;
import org.opengroup.osdu.storage.provider.interfaces.ICloudStorage;
import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository;
import org.opengroup.osdu.storage.util.api.RecordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -78,6 +79,9 @@ public class IngestionServiceImpl implements IngestionService {
@Autowired(required = false)
private IPolicyService policyService;
@Autowired
private RecordUtil recordUtil;
@Override
public TransferInfo createUpdateRecords(boolean skipDupes, List<Record> inputRecords, String user) {
this.validateKindFormat(inputRecords);
......@@ -239,11 +243,18 @@ public class IngestionServiceImpl implements IngestionService {
Map<String, List<RecordIdWithVersion>> recordParentMap) {
for (Entry<String, List<RecordIdWithVersion>> entry : recordParentMap.entrySet()) {
List<RecordIdWithVersion> parents = entry.getValue();
for (RecordIdWithVersion parent : parents) {
if (!existingRecords.containsKey(parent.getRecordId())) {
List<RecordIdWithVersion> parentRecordIdsWithVersions = entry.getValue();
for (RecordIdWithVersion parentRecordIdWithVersion : parentRecordIdsWithVersions) {
String parentId = parentRecordIdWithVersion .getRecordId();
if (!existingRecords.containsKey(parentId)) {
throw new AppException(HttpStatus.SC_NOT_FOUND, "Record not found",
String.format("The record '%s' was not found", parent));
String.format("The record '%s' was not found", parentRecordIdWithVersion ));
}
RecordMetadata parentRecordMetadata = existingRecords.get(parentId);
long version = parentRecordIdWithVersion .getRecordVersion();
if (!recordUtil.hasVersionPath(parentRecordMetadata.getGcsVersionPaths(), version)) {
throw new AppException(HttpStatus.SC_NOT_FOUND, "RecordMetadata version not found",
String.format("The RecordMetadata version %d for parent record '%s' was not found", version, parentId));
}
}
}
......
......@@ -142,23 +142,31 @@ public class LegalServiceImpl implements ILegalService {
}
private boolean isInCache(Set<String> legalTagNames) {
for (String legalTagName : legalTagNames) {
String legalTag = null;
try {
String currentLegalTagName = null;
try {
for (String legalTagName : legalTagNames) {
String legalTag = null;
currentLegalTagName = legalTagName;
legalTag = this.cache.get(legalTagName);
} catch (RedisException ex) {
this.log.error(String.format("Error getting key %s from redis: %s", legalTagName, ex.getMessage()), ex);
}
if (legalTag == null) {
return false;
if (legalTag == null) {
return false;
}
}
} catch (RedisException ex) {
this.log.error(String.format("Error getting key %s from redis: %s", currentLegalTagName, ex.getMessage()), ex);
}
return true;
}
private void addToCache(Set<String> legalTagNames) {
for (String legalTagName : legalTagNames) {
this.cache.put(legalTagName, "Valid LegalTag");
String currentLegalTagName = null;
try {
for (String legalTagName : legalTagNames) {
currentLegalTagName = legalTagName;
this.cache.put(legalTagName, "Valid LegalTag");
}
} catch (RedisException ex) {
this.log.error(String.format("Error putting key %s into redis: %s", currentLegalTagName, ex.getMessage()), ex);
}
}
}
\ No newline at end of file
}
......@@ -107,6 +107,8 @@ public class SchemaServiceImpl implements SchemaService {
} catch (ConcurrentModificationException e) {
throw new AppException(HttpStatus.SC_CONFLICT, "Schema already registered",
"Concurrent schema modification error.");
} catch (RedisException ex) {
this.log.error(String.format("Error putting key %s into redis: %s", this.getSchemaCacheKey(inputSchema.getKind()), ex.getMessage()), ex);
} catch (Exception e) {
throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Error on schema creation",
"An unknown error occurred during schema creation.");
......@@ -212,8 +214,11 @@ public class SchemaServiceImpl implements SchemaService {
if (schema == null) {
return null;
}
this.cache.put(key, schema);
try {
this.cache.put(key, schema);
} catch (RedisException ex) {
this.log.error(String.format("Error putting key %s into redis: %s", key, ex.getMessage()), ex);
}
return schema;
} else {
......
......@@ -17,14 +17,7 @@ package org.opengroup.osdu.storage.util;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.*;
import java.util.stream.Stream;
import com.google.gson.JsonParser;
......@@ -120,6 +113,12 @@ public class RecordUtilImpl implements RecordUtil {
return recordMetadata;
}
public boolean hasVersionPath(List<String> gcsVersionPaths, Long version) {
return gcsVersionPaths.stream()
.filter(Objects::nonNull)
.anyMatch(path -> path.endsWith("/" + version));
}
private RecordMetadata updateMetadataForAclAndLegal(RecordMetadata recordMetadata, List<PatchOperation> ops) {
JsonObject metadata = this.gson.toJsonTree(recordMetadata).getAsJsonObject();
String errorPath = "";
......
......@@ -27,4 +27,6 @@ public interface RecordUtil {
Map<String, String> mapRecordsAndVersions(List<String> recordIds);
RecordMetadata updateRecordMetaDataForPatchOperations(RecordMetadata recordMetadata, List<PatchOperation> ops, String user, long timestamp);
boolean hasVersionPath(List<String> gcsVersionPaths, Long version);
}
\ No newline at end of file
......@@ -46,6 +46,7 @@ import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository
import org.opengroup.osdu.core.common.storage.IPersistenceService;
import org.opengroup.osdu.core.common.legal.ILegalService;
import org.opengroup.osdu.core.common.entitlements.IEntitlementsAndCacheService;
import org.opengroup.osdu.storage.util.api.RecordUtil;
import java.util.*;
......@@ -96,6 +97,9 @@ public class IngestionServiceImplTest {
@Mock
private JaxRsDpsLog logger;
@Mock
private RecordUtil recordUtil;
@InjectMocks
private IngestionServiceImpl sut;
......@@ -542,4 +546,80 @@ public class IngestionServiceImplTest {
assertEquals(new Integer(1), batch.getTransferInfo().getRecordCount());
assertEquals(RecordState.active, batch.getRecords().get(0).getRecordMetadata().getStatus());
}
@Test
public void should_return404_when_updatingARecordWithNonExistingParent() {
when(this.authService.isValidAcl(any(), any())).thenReturn(true);
this.record1.setId(RECORD_ID1);
this.acl.setViewers(VALID_ACL);
this.acl.setOwners(VALID_ACL);
// set up non-empty ancestry
RecordAncestry ancestry = new RecordAncestry();
Set<String> parentSet = new HashSet<String>();
parentSet.add("test:doc:non-existing record id:111");
ancestry.setParents(parentSet);
this.record1.setAncestry(ancestry);
RecordMetadata existingRecordMetadata1 = new RecordMetadata();
Map<String, RecordMetadata> output = new HashMap<>();
output.put(RECORD_ID1, existingRecordMetadata1);
when(this.cloudStorage.hasAccess(existingRecordMetadata1)).thenReturn(true);
List<RecordMetadata> recordMetadataList = new ArrayList<>();
recordMetadataList.add(existingRecordMetadata1);
when(this.authService.hasValidAccess(any(), any())).thenReturn(recordMetadataList);
when(this.authService.hasOwnerAccess(any(), any())).thenReturn(true);
when(this.recordRepository.get(any(List.class))).thenReturn(output);
try {
this.sut.createUpdateRecords(false, this.records, USER);
fail("Should not succeed");
} catch (AppException e) {
assertEquals(HttpStatus.SC_NOT_FOUND, e.getError().getCode());
assertEquals("Record not found", e.getError().getReason());
}
}
@Test
public void should_return404_when_updatingARecordWithNonExistingRecordMetaData() {
when(this.authService.isValidAcl(any(), any())).thenReturn(true);
this.record1.setId(RECORD_ID1);
this.acl.setViewers(VALID_ACL);
this.acl.setOwners(VALID_ACL);
// set up non-empty ancestry
RecordAncestry ancestry = new RecordAncestry();
Set<String> parentSet = new HashSet<String>();
parentSet.add(RECORD_ID1 + ":111");
ancestry.setParents(parentSet);
this.record1.setAncestry(ancestry);
RecordMetadata existingRecordMetadata1 = new RecordMetadata();
Map<String, RecordMetadata> output = new HashMap<>();
output.put(RECORD_ID1, existingRecordMetadata1);
when(this.cloudStorage.hasAccess(existingRecordMetadata1)).thenReturn(true);
List<RecordMetadata> recordMetadataList = new ArrayList<>();
recordMetadataList.add(existingRecordMetadata1);
when(this.authService.hasValidAccess(any(), any())).thenReturn(recordMetadataList);
when(this.authService.hasOwnerAccess(any(), any())).thenReturn(true);
when(this.recordRepository.get(any(List.class))).thenReturn(output);
try {
this.sut.createUpdateRecords(false, this.records, USER);
fail("Should not succeed");
} catch (AppException e) {
assertEquals(HttpStatus.SC_NOT_FOUND, e.getError().getCode());
assertEquals("RecordMetadata version not found", e.getError().getReason());
}