Search in sources :

Example 16 with StorageFile

use of org.finra.herd.model.api.xml.StorageFile in project herd by FINRAOS.

the class MockHttpClientOperationsImpl method buildGetBusinessObjectDataResponse.

/**
 * Builds a business object data response.
 *
 * @param response the response.
 * @param uri the URI of the incoming request.
 *
 * @throws JAXBException if a JAXB error occurred.
 */
private void buildGetBusinessObjectDataResponse(MockCloseableHttpResponse response, URI uri) throws JAXBException {
    Pattern pattern = Pattern.compile("/herd-app/rest/businessObjectData/namespaces/(.*)/businessObjectDefinitionNames/(.*)/businessObjectFormatUsages/(.*)" + "/businessObjectFormatFileTypes/(.*).*");
    Matcher matcher = pattern.matcher(uri.getPath());
    if (matcher.find()) {
        BusinessObjectData businessObjectData = new BusinessObjectData();
        businessObjectData.setNamespace(matcher.group(1));
        businessObjectData.setBusinessObjectDefinitionName(matcher.group(2));
        businessObjectData.setBusinessObjectFormatUsage(matcher.group(3));
        businessObjectData.setBusinessObjectFormatFileType(matcher.group(4));
        businessObjectData.setPartitionValue("2014-01-31");
        businessObjectData.setPartitionKey("PROCESS_DATE");
        businessObjectData.setAttributes(new ArrayList<Attribute>());
        businessObjectData.setBusinessObjectFormatVersion(0);
        businessObjectData.setLatestVersion(true);
        businessObjectData.setStatus(BusinessObjectDataStatusEntity.VALID);
        List<StorageUnit> storageUnits = new ArrayList<>();
        businessObjectData.setStorageUnits(storageUnits);
        StorageUnit storageUnit = new StorageUnit();
        storageUnits.add(storageUnit);
        storageUnit.setStorage(getNewStorage(StorageEntity.MANAGED_STORAGE));
        List<StorageFile> storageFiles = new ArrayList<>();
        storageUnit.setStorageFiles(storageFiles);
        storageUnit.setStorageUnitStatus(StorageUnitStatusEntity.ENABLED);
        List<String> localFiles = Arrays.asList("foo1.dat", "Foo2.dat", "FOO3.DAT", "folder/foo3.dat", "folder/foo2.dat", "folder/foo1.dat");
        for (String filename : localFiles) {
            StorageFile storageFile = new StorageFile();
            storageFiles.add(storageFile);
            storageFile.setFilePath(businessObjectData.getNamespace().toLowerCase().replace('_', '-') + "/exchange-a/" + businessObjectData.getBusinessObjectFormatUsage().toLowerCase().replace('_', '-') + "/" + businessObjectData.getBusinessObjectFormatFileType().toLowerCase().replace('_', '-') + "/" + businessObjectData.getBusinessObjectDefinitionName().toLowerCase().replace('_', '-') + "/frmt-v" + businessObjectData.getBusinessObjectFormatVersion() + "/data-v" + businessObjectData.getVersion() + "/" + businessObjectData.getPartitionKey().toLowerCase().replace('_', '-') + "=" + businessObjectData.getPartitionValue() + "/" + filename);
            storageFile.setFileSizeBytes(1024L);
            storageFile.setRowCount(10L);
        }
        businessObjectData.setSubPartitionValues(new ArrayList<String>());
        businessObjectData.setId(1234);
        businessObjectData.setVersion(0);
        response.setEntity(getHttpEntity(businessObjectData));
    }
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) BusinessObjectData(org.finra.herd.model.api.xml.BusinessObjectData) Attribute(org.finra.herd.model.api.xml.Attribute) ArrayList(java.util.ArrayList) StorageUnit(org.finra.herd.model.api.xml.StorageUnit) StorageFile(org.finra.herd.model.api.xml.StorageFile)

Example 17 with StorageFile

use of org.finra.herd.model.api.xml.StorageFile in project herd by FINRAOS.

the class BusinessObjectDataStorageFileServiceImpl method validateStorageFiles.

/**
 * Validates a list of storage files to be added to the specified storage unit.
 *
 * @param storageFiles the list of storage files
 * @param storageUnitEntity the storage unit entity
 * @param validatePathPrefix the validate path prefix flag
 * @param validateFileExistence the validate file existence flag
 * @param validateFileSize the validate file size flag
 */
private void validateStorageFiles(List<StorageFile> storageFiles, StorageUnitEntity storageUnitEntity, boolean validatePathPrefix, boolean validateFileExistence, boolean validateFileSize) {
    // Retrieve all storage files already registered for this storage unit loaded in a map for easy access.
    Map<String, StorageFileEntity> storageFileEntities = storageFileHelper.getStorageFileEntitiesMap(storageUnitEntity.getStorageFiles());
    // Perform validation of storage files listed in the request per storage directory path and/or validation flags.
    String directoryPath = null;
    String directoryPathWithTrailingSlash = null;
    if (StringUtils.isNotBlank(storageUnitEntity.getDirectoryPath())) {
        // Use the storage directory path from the storage unit.
        directoryPath = storageUnitEntity.getDirectoryPath();
        // Add a trailing slash to the storage directory path if it doesn't already have it.
        directoryPathWithTrailingSlash = StringUtils.appendIfMissing(directoryPath, "/");
        // If a storage directory path exists, then validate that all files being added are contained within that directory.
        for (StorageFile storageFile : storageFiles) {
            Assert.isTrue(storageFile.getFilePath().startsWith(directoryPathWithTrailingSlash), String.format("Storage file path \"%s\" does not match the storage directory path \"%s\".", storageFile.getFilePath(), directoryPathWithTrailingSlash));
        }
    } else if (validatePathPrefix || validateFileExistence) {
        // Use the expected S3 key prefix value as the storage directory path.
        directoryPath = s3KeyPrefixHelper.buildS3KeyPrefix(storageUnitEntity.getStorage(), storageUnitEntity.getBusinessObjectData().getBusinessObjectFormat(), businessObjectDataHelper.getBusinessObjectDataKey(storageUnitEntity.getBusinessObjectData()));
        // Add a trailing slash to the expected S3 key prefix if it doesn't already have it.
        directoryPathWithTrailingSlash = StringUtils.appendIfMissing(directoryPath, "/");
        // Validate that all files are contained within the expected S3 key prefix.
        for (StorageFile storageFile : storageFiles) {
            Assert.isTrue(storageFile.getFilePath().startsWith(directoryPathWithTrailingSlash), String.format("Specified storage file path \"%s\" does not match the expected S3 key prefix \"%s\".", storageFile.getFilePath(), directoryPathWithTrailingSlash));
        }
    }
    // Validate that files in the request does not already exist in the database.
    if (StringUtils.isNotBlank(directoryPath)) {
        // Get a list of request storage file paths.
        List<String> requestStorageFilePaths = storageFileHelper.getFilePathsFromStorageFiles(storageFiles);
        // Retrieve all already registered storage files from the storage that start with the directory path.
        List<String> registeredStorageFilePaths = storageFileDao.getStorageFilesByStorageAndFilePathPrefix(storageUnitEntity.getStorage().getName(), directoryPathWithTrailingSlash);
        // Check if request contains any of the already registered files.
        registeredStorageFilePaths.retainAll(requestStorageFilePaths);
        if (!CollectionUtils.isEmpty(registeredStorageFilePaths)) {
            // Retrieve the storage file entity for the first "already registered" storage file.
            // Since the discovered storage file path exists in the database, we should not get a null back.
            StorageFileEntity storageFileEntity = storageFileDao.getStorageFileByStorageNameAndFilePath(storageUnitEntity.getStorage().getName(), registeredStorageFilePaths.get(0));
            // Throw an exception reporting the information on the "already registered" storage file.
            throw new AlreadyExistsException(String.format("S3 file \"%s\" in \"%s\" storage is already registered by the business object data {%s}.", registeredStorageFilePaths.get(0), storageUnitEntity.getStorage().getName(), businessObjectDataHelper.businessObjectDataEntityAltKeyToString(storageFileEntity.getStorageUnit().getBusinessObjectData())));
        }
    } else {
        // Since directory path is not available, we need to validate each storage file specified in the request individually.
        for (StorageFile storageFile : storageFiles) {
            // Ensure that the file is not already registered in this storage by some other business object data.
            StorageFileEntity storageFileEntity = storageFileDao.getStorageFileByStorageNameAndFilePath(storageUnitEntity.getStorage().getName(), storageFile.getFilePath());
            if (storageFileEntity != null) {
                throw new AlreadyExistsException(String.format("S3 file \"%s\" in \"%s\" storage is already registered by the business object data {%s}.", storageFile.getFilePath(), storageUnitEntity.getStorage().getName(), businessObjectDataHelper.businessObjectDataEntityAltKeyToString(storageFileEntity.getStorageUnit().getBusinessObjectData())));
            }
        }
    }
    // Validate file existence.
    if (validateFileExistence) {
        // Get S3 bucket access parameters and set the key prefix to the directory path with a trailing slash.
        // Please note that since we got here, the directory path can not be empty.
        S3FileTransferRequestParamsDto params = storageHelper.getS3BucketAccessParams(storageUnitEntity.getStorage());
        params.setS3KeyPrefix(directoryPathWithTrailingSlash);
        // When listing S3 files, we ignore 0 byte objects that represent S3 directories.
        Map<String, StorageFile> actualS3Keys = storageFileHelper.getStorageFilesMapFromS3ObjectSummaries(s3Service.listDirectory(params, true));
        // For the already registered storage files, validate each storage file against S3 keys and metadata reported by S3.
        for (Map.Entry<String, StorageFileEntity> entry : storageFileEntities.entrySet()) {
            storageFileHelper.validateStorageFileEntity(entry.getValue(), params.getS3BucketName(), actualS3Keys, validateFileSize);
        }
        // Validate each storage file listed in the request.
        for (StorageFile storageFile : storageFiles) {
            storageFileHelper.validateStorageFile(storageFile, params.getS3BucketName(), actualS3Keys, validateFileSize);
        }
    }
}
Also used : StorageFileEntity(org.finra.herd.model.jpa.StorageFileEntity) AlreadyExistsException(org.finra.herd.model.AlreadyExistsException) S3FileTransferRequestParamsDto(org.finra.herd.model.dto.S3FileTransferRequestParamsDto) StorageFile(org.finra.herd.model.api.xml.StorageFile) Map(java.util.Map)

Example 18 with StorageFile

use of org.finra.herd.model.api.xml.StorageFile in project herd by FINRAOS.

the class BusinessObjectDataStorageFileServiceImpl method createBusinessObjectDataStorageFilesImpl.

/**
 * Adds files to Business object data storage.
 *
 * @param businessObjectDataStorageFilesCreateRequest the business object data storage files create request
 *
 * @return BusinessObjectDataStorageFilesCreateResponse
 */
protected BusinessObjectDataStorageFilesCreateResponse createBusinessObjectDataStorageFilesImpl(BusinessObjectDataStorageFilesCreateRequest businessObjectDataStorageFilesCreateRequest) {
    // validate request
    validateBusinessObjectDataStorageFilesCreateRequest(businessObjectDataStorageFilesCreateRequest);
    // retrieve and validate that the business object data exists
    BusinessObjectDataEntity businessObjectDataEntity = businessObjectDataDaoHelper.getBusinessObjectDataEntity(getBusinessObjectDataKey(businessObjectDataStorageFilesCreateRequest));
    // Validate that business object data is in one of the pre-registered states.
    Assert.isTrue(BooleanUtils.isTrue(businessObjectDataEntity.getStatus().getPreRegistrationStatus()), String.format("Business object data status must be one of the pre-registration statuses. Business object data status {%s}, business object data {%s}", businessObjectDataEntity.getStatus().getCode(), businessObjectDataHelper.businessObjectDataEntityAltKeyToString(businessObjectDataEntity)));
    // retrieve and validate that the storage unit exists
    StorageUnitEntity storageUnitEntity = storageUnitDaoHelper.getStorageUnitEntity(businessObjectDataStorageFilesCreateRequest.getStorageName(), businessObjectDataEntity);
    // Validate the storage unit has an acceptable status for adding new files.
    Assert.isTrue(StorageUnitStatusEntity.ENABLED.equals(storageUnitEntity.getStatus().getCode()), String.format("Storage unit must be in the ENABLED status. Storage unit status {%s}, business object data {%s}", storageUnitEntity.getStatus().getCode(), businessObjectDataHelper.businessObjectDataEntityAltKeyToString(businessObjectDataEntity)));
    StorageEntity storageEntity = storageUnitEntity.getStorage();
    // Get the S3 validation flags.
    boolean validatePathPrefix = storageHelper.getBooleanStorageAttributeValueByName(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_VALIDATE_PATH_PREFIX), storageEntity, false, true);
    boolean validateFileExistence = storageHelper.getBooleanStorageAttributeValueByName(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_VALIDATE_FILE_EXISTENCE), storageEntity, false, true);
    boolean validateFileSize = storageHelper.getBooleanStorageAttributeValueByName(configurationHelper.getProperty(ConfigurationValue.S3_ATTRIBUTE_NAME_VALIDATE_FILE_SIZE), storageEntity, false, true);
    // Ensure that file size validation is not enabled without file existence validation.
    if (validateFileSize) {
        Assert.isTrue(validateFileExistence, String.format("Storage \"%s\" has file size validation enabled without file existence validation.", storageEntity.getName()));
    }
    // Process the add storage files request based on the auto-discovery of storage files being enabled or not.
    List<StorageFile> storageFiles;
    if (BooleanUtils.isTrue(businessObjectDataStorageFilesCreateRequest.isDiscoverStorageFiles())) {
        // Discover new storage files for this storage unit.
        storageFiles = discoverStorageFiles(storageUnitEntity);
    } else {
        // Get the list of storage files from the request.
        storageFiles = businessObjectDataStorageFilesCreateRequest.getStorageFiles();
        // Validate storage files.
        validateStorageFiles(storageFiles, storageUnitEntity, validatePathPrefix, validateFileExistence, validateFileSize);
    }
    // Add new storage files to the storage unit.
    storageFileDaoHelper.createStorageFileEntitiesFromStorageFiles(storageUnitEntity, storageFiles);
    // Construct and return the response.
    return createBusinessObjectDataStorageFilesCreateResponse(storageEntity, businessObjectDataEntity, storageFiles);
}
Also used : StorageUnitEntity(org.finra.herd.model.jpa.StorageUnitEntity) StorageFile(org.finra.herd.model.api.xml.StorageFile) StorageEntity(org.finra.herd.model.jpa.StorageEntity) BusinessObjectDataEntity(org.finra.herd.model.jpa.BusinessObjectDataEntity)

Example 19 with StorageFile

use of org.finra.herd.model.api.xml.StorageFile in project herd by FINRAOS.

the class BusinessObjectDataFinalizeRestoreHelperServiceTest method testExecuteS3SpecificStepsGlacierS3FileStillRestoring.

@Test
public void testExecuteS3SpecificStepsGlacierS3FileStillRestoring() throws Exception {
    // Create S3FileTransferRequestParamsDto to access the S3 bucket.
    // Since test S3 key prefix represents a directory, we add a trailing '/' character to it.
    S3FileTransferRequestParamsDto s3FileTransferRequestParamsDto = S3FileTransferRequestParamsDto.builder().withS3BucketName(S3_BUCKET_NAME).withS3KeyPrefix(TEST_S3_KEY_PREFIX + "/").build();
    // Create a business object data key.
    BusinessObjectDataKey businessObjectDataKey = new BusinessObjectDataKey(BDEF_NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, FORMAT_VERSION, PARTITION_VALUE, SUBPARTITION_VALUES, DATA_VERSION);
    // Create a business object data restore DTO.
    BusinessObjectDataRestoreDto businessObjectDataRestoreDto = new BusinessObjectDataRestoreDto(businessObjectDataKey, STORAGE_NAME, NO_S3_ENDPOINT, S3_BUCKET_NAME, TEST_S3_KEY_PREFIX, NO_STORAGE_UNIT_STATUS, NO_STORAGE_UNIT_STATUS, Arrays.asList(new StorageFile(TEST_S3_KEY_PREFIX + "/" + LOCAL_FILE, FILE_SIZE_1_KB, NO_ROW_COUNT)), NO_EXCEPTION);
    try {
        // Put a "still restoring" Glacier storage class S3 file in the Glacier S3 bucket.
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier);
        metadata.setOngoingRestore(true);
        s3Operations.putObject(new PutObjectRequest(S3_BUCKET_NAME, String.format("%s/%s", TEST_S3_KEY_PREFIX, LOCAL_FILE), new ByteArrayInputStream(new byte[(int) FILE_SIZE_1_KB]), metadata), NO_S3_CLIENT);
        // Try to execute S3 specific steps to finalize a restore for the storage unit when Glacier S3 file is still restoring.
        try {
            businessObjectDataFinalizeRestoreHelperService.executeS3SpecificSteps(businessObjectDataRestoreDto);
            fail();
        } catch (IllegalArgumentException e) {
            assertEquals(String.format("Archived Glacier S3 file \"%s/%s\" is not restored. " + "StorageClass {GLACIER}, OngoingRestore flag {true}, S3 bucket name {%s}", TEST_S3_KEY_PREFIX, LOCAL_FILE, S3_BUCKET_NAME), e.getMessage());
        }
        // Validate that we have a Glacier S3 file at the expected S3 location.
        assertEquals(1, s3Dao.listDirectory(s3FileTransferRequestParamsDto).size());
    } finally {
        // Delete test files from S3 storage.
        if (!s3Dao.listDirectory(s3FileTransferRequestParamsDto).isEmpty()) {
            s3Dao.deleteDirectory(s3FileTransferRequestParamsDto);
        }
        s3Operations.rollback();
    }
}
Also used : S3FileTransferRequestParamsDto(org.finra.herd.model.dto.S3FileTransferRequestParamsDto) ByteArrayInputStream(java.io.ByteArrayInputStream) StorageFile(org.finra.herd.model.api.xml.StorageFile) BusinessObjectDataKey(org.finra.herd.model.api.xml.BusinessObjectDataKey) BusinessObjectDataRestoreDto(org.finra.herd.model.dto.BusinessObjectDataRestoreDto) ObjectMetadata(com.amazonaws.services.s3.model.ObjectMetadata) PutObjectRequest(com.amazonaws.services.s3.model.PutObjectRequest) Test(org.junit.Test)

Example 20 with StorageFile

use of org.finra.herd.model.api.xml.StorageFile in project herd by FINRAOS.

the class BusinessObjectDataFinalizeRestoreHelperServiceTest method testExecuteS3SpecificSteps.

@Test
public void testExecuteS3SpecificSteps() throws Exception {
    // Create S3FileTransferRequestParamsDto to access the S3 bucket.
    // Since test S3 key prefix represents a directory, we add a trailing '/' character to it.
    S3FileTransferRequestParamsDto s3FileTransferRequestParamsDto = S3FileTransferRequestParamsDto.builder().withS3BucketName(S3_BUCKET_NAME).withS3KeyPrefix(TEST_S3_KEY_PREFIX + "/").build();
    // Create a business object data key.
    BusinessObjectDataKey businessObjectDataKey = new BusinessObjectDataKey(BDEF_NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, FORMAT_VERSION, PARTITION_VALUE, SUBPARTITION_VALUES, DATA_VERSION);
    // Create a list of storage files.
    List<StorageFile> storageFiles = new ArrayList<>();
    for (String filePath : LOCAL_FILES) {
        storageFiles.add(new StorageFile(TEST_S3_KEY_PREFIX + "/" + filePath, FILE_SIZE_1_KB, NO_ROW_COUNT));
    }
    // Create a business object data restore DTO.
    BusinessObjectDataRestoreDto businessObjectDataRestoreDto = new BusinessObjectDataRestoreDto(businessObjectDataKey, STORAGE_NAME, NO_S3_ENDPOINT, S3_BUCKET_NAME, TEST_S3_KEY_PREFIX, NO_STORAGE_UNIT_STATUS, NO_STORAGE_UNIT_STATUS, storageFiles, NO_EXCEPTION);
    try {
        // Put relative Glacier storage class S3 files in the S3 bucket.
        for (StorageFile storageFile : storageFiles) {
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader(Headers.STORAGE_CLASS, StorageClass.Glacier);
            metadata.setOngoingRestore(false);
            s3Operations.putObject(new PutObjectRequest(S3_BUCKET_NAME, storageFile.getFilePath(), new ByteArrayInputStream(new byte[storageFile.getFileSizeBytes().intValue()]), metadata), NO_S3_CLIENT);
        }
        // Execute S3 specific steps to finalize a restore for the Glacier storage unit.
        businessObjectDataFinalizeRestoreHelperService.executeS3SpecificSteps(businessObjectDataRestoreDto);
        // Validate that we have the restored S3 files at the expected S3 location.
        assertEquals(storageFiles.size(), s3Dao.listDirectory(s3FileTransferRequestParamsDto).size());
    } finally {
        // Delete test files from S3 storage.
        if (!s3Dao.listDirectory(s3FileTransferRequestParamsDto).isEmpty()) {
            s3Dao.deleteDirectory(s3FileTransferRequestParamsDto);
        }
        s3Operations.rollback();
    }
}
Also used : S3FileTransferRequestParamsDto(org.finra.herd.model.dto.S3FileTransferRequestParamsDto) ByteArrayInputStream(java.io.ByteArrayInputStream) StorageFile(org.finra.herd.model.api.xml.StorageFile) ArrayList(java.util.ArrayList) BusinessObjectDataKey(org.finra.herd.model.api.xml.BusinessObjectDataKey) BusinessObjectDataRestoreDto(org.finra.herd.model.dto.BusinessObjectDataRestoreDto) ObjectMetadata(com.amazonaws.services.s3.model.ObjectMetadata) PutObjectRequest(com.amazonaws.services.s3.model.PutObjectRequest) Test(org.junit.Test)

Aggregations

StorageFile (org.finra.herd.model.api.xml.StorageFile)75 Test (org.junit.Test)43 BusinessObjectDataKey (org.finra.herd.model.api.xml.BusinessObjectDataKey)38 ArrayList (java.util.ArrayList)26 AbstractServiceTest (org.finra.herd.service.AbstractServiceTest)23 StorageUnitEntity (org.finra.herd.model.jpa.StorageUnitEntity)22 BusinessObjectDataEntity (org.finra.herd.model.jpa.BusinessObjectDataEntity)16 BusinessObjectDataRestoreDto (org.finra.herd.model.dto.BusinessObjectDataRestoreDto)15 S3FileTransferRequestParamsDto (org.finra.herd.model.dto.S3FileTransferRequestParamsDto)15 S3ObjectSummary (com.amazonaws.services.s3.model.S3ObjectSummary)13 BusinessObjectDataCreateRequest (org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest)11 Attribute (org.finra.herd.model.api.xml.Attribute)9 StorageEntity (org.finra.herd.model.jpa.StorageEntity)9 StorageFileEntity (org.finra.herd.model.jpa.StorageFileEntity)9 StorageUnitStatusEntity (org.finra.herd.model.jpa.StorageUnitStatusEntity)8 PutObjectRequest (com.amazonaws.services.s3.model.PutObjectRequest)7 ByteArrayInputStream (java.io.ByteArrayInputStream)7 HashMap (java.util.HashMap)7 BusinessObjectDataStorageUnitKey (org.finra.herd.model.api.xml.BusinessObjectDataStorageUnitKey)7 StorageDirectory (org.finra.herd.model.api.xml.StorageDirectory)7