/* * Copyright 2015 herd contributors * * 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 * * 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. */ package org.finra.herd.rest; import java.util.ArrayList; import java.util.Arrays; import javax.servlet.ServletRequest; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.finra.herd.model.api.xml.BusinessObjectData; import org.finra.herd.model.api.xml.BusinessObjectDataAvailability; import org.finra.herd.model.api.xml.BusinessObjectDataAvailabilityCollectionRequest; import org.finra.herd.model.api.xml.BusinessObjectDataAvailabilityCollectionResponse; import org.finra.herd.model.api.xml.BusinessObjectDataAvailabilityRequest; import org.finra.herd.model.api.xml.BusinessObjectDataCreateRequest; import org.finra.herd.model.api.xml.BusinessObjectDataDdl; import org.finra.herd.model.api.xml.BusinessObjectDataDdlCollectionRequest; import org.finra.herd.model.api.xml.BusinessObjectDataDdlCollectionResponse; import org.finra.herd.model.api.xml.BusinessObjectDataDdlRequest; import org.finra.herd.model.api.xml.BusinessObjectDataDownloadCredential; import org.finra.herd.model.api.xml.BusinessObjectDataInvalidateUnregisteredRequest; import org.finra.herd.model.api.xml.BusinessObjectDataInvalidateUnregisteredResponse; import org.finra.herd.model.api.xml.BusinessObjectDataKey; import org.finra.herd.model.api.xml.BusinessObjectDataKeys; import org.finra.herd.model.api.xml.BusinessObjectDataRetryStoragePolicyTransitionRequest; import org.finra.herd.model.api.xml.BusinessObjectDataSearchRequest; import org.finra.herd.model.api.xml.BusinessObjectDataSearchResult; import org.finra.herd.model.api.xml.BusinessObjectDataUploadCredential; import org.finra.herd.model.api.xml.BusinessObjectDataVersions; import org.finra.herd.model.api.xml.BusinessObjectDefinitionKey; import org.finra.herd.model.api.xml.BusinessObjectFormatKey; import org.finra.herd.model.api.xml.S3KeyPrefixInformation; import org.finra.herd.model.api.xml.StorageUnitDownloadCredential; import org.finra.herd.model.api.xml.StorageUnitUploadCredential; import org.finra.herd.model.dto.SecurityFunctions; import org.finra.herd.service.BusinessObjectDataService; import org.finra.herd.service.StorageUnitService; import org.finra.herd.service.helper.BusinessObjectDataDaoHelper; import org.finra.herd.ui.constants.UiConstants; /** * The REST controller that handles business object data REST requests. */ @RestController @RequestMapping(value = UiConstants.REST_URL_BASE, produces = {"application/xml", "application/json"}) @Api(tags = "Business Object Data") public class BusinessObjectDataRestController extends HerdBaseController { @Autowired private BusinessObjectDataDaoHelper businessObjectDataDaoHelper; @Autowired private BusinessObjectDataService businessObjectDataService; @Autowired private StorageUnitService storageUnitService; /** * Performs a search and returns a list of business object data key values and relative statuses for a range of requested business object data. <p> Requires * READ permission on namespace </p> * * @param businessObjectDataAvailabilityRequest the business object data availability request * * @return the business object data availability information */ @RequestMapping(value = "/businessObjectData/availability", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_AVAILABILITY_POST) public BusinessObjectDataAvailability checkBusinessObjectDataAvailability( @RequestBody BusinessObjectDataAvailabilityRequest businessObjectDataAvailabilityRequest) { return businessObjectDataService.checkBusinessObjectDataAvailability(businessObjectDataAvailabilityRequest); } /** * Performs an availability check for a collection of business object data. <p> Requires READ permission on ALL namespaces </p> * * @param businessObjectDataAvailabilityCollectionRequest the business object data availability collection request * * @return the business object data availability information */ @RequestMapping(value = "/businessObjectData/availabilityCollection", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_AVAILABILITY_COLLECTION_POST) public BusinessObjectDataAvailabilityCollectionResponse checkBusinessObjectDataAvailabilityCollection( @RequestBody BusinessObjectDataAvailabilityCollectionRequest businessObjectDataAvailabilityCollectionRequest) { return businessObjectDataService.checkBusinessObjectDataAvailabilityCollection(businessObjectDataAvailabilityCollectionRequest); } /** * Creates (i.e. registers) business object data. You may pre-register business object data by setting the status to one of the pre-registration statuses * (UPLOADING, PENDING_VALID, and PROCESSING). <p> Requires WRITE permission on namespace </p> * * @param businessObjectDataCreateRequest the information needed to create the business object data * * @return the created business object data */ @RequestMapping(value = "/businessObjectData", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_POST) public BusinessObjectData createBusinessObjectData(@RequestBody BusinessObjectDataCreateRequest businessObjectDataCreateRequest) { BusinessObjectData businessObjectData = businessObjectDataService.createBusinessObjectData(businessObjectDataCreateRequest); // TODO This should be enhanced such that the notification events are captured by probably as an advice, and these calls are not specified everywhere // in the code. // The calls to notifications is being done in REST layer so that the event transaction (e.g. in this case: create business object data) is committed // and the event data is available for when notification is processed. // With proposed designed, when we go to event publish mode(e.g. create a database record for the event that will be picked up by notification // processing engine), We would want the event transaction to also rollback if event publishing failed. These calls will be moved to service layer. // Trigger notifications. businessObjectDataDaoHelper.triggerNotificationsForCreateBusinessObjectData(businessObjectData); return businessObjectData; } /** * Deletes an existing business object data without subpartition values with namespace. <p> Requires WRITE permission on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param businessObjectDataVersion the business object data version * @param deleteFiles whether files should be deleted * * @return the deleted business object data information */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}" + "/partitionValues/{partitionValue}/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.DELETE) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_DELETE) public BusinessObjectData deleteBusinessObjectData(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam("deleteFiles") Boolean deleteFiles) { return businessObjectDataService.deleteBusinessObjectData( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, new ArrayList<String>(), businessObjectDataVersion), deleteFiles); } /** * Deletes an existing business object data with 1 subpartition value with namespace. <p> Requires WRITE permission on namespace </p> * * @param namespace the namespace. * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param subPartition1Value sub-partition value 1 * @param businessObjectDataVersion the business object data version * @param deleteFiles whether files should be deleted * * @return the deleted business object data information */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}" + "/partitionValues/{partitionValue}/subPartition1Values/{subPartition1Value}/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.DELETE) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_DELETE) public BusinessObjectData deleteBusinessObjectData(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("subPartition1Value") String subPartition1Value, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam("deleteFiles") Boolean deleteFiles) { return businessObjectDataService.deleteBusinessObjectData( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, Arrays.asList(subPartition1Value), businessObjectDataVersion), deleteFiles); } /** * Deletes an existing business object data with 2 subpartition values with namespace. <p> Requires WRITE permission on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param subPartition1Value sub-partition value 1 * @param subPartition2Value sub-partition value 2 * @param businessObjectDataVersion the business object data version * @param deleteFiles whether files should be deleted * * @return the deleted business object data information */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}" + "/partitionValues/{partitionValue}/subPartition1Values/{subPartition1Value}/subPartition2Values/{subPartition2Value}" + "/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.DELETE) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_DELETE) public BusinessObjectData deleteBusinessObjectData(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("subPartition1Value") String subPartition1Value, @PathVariable("subPartition2Value") String subPartition2Value, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam("deleteFiles") Boolean deleteFiles) { return businessObjectDataService.deleteBusinessObjectData( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, Arrays.asList(subPartition1Value, subPartition2Value), businessObjectDataVersion), deleteFiles); } /** * Deletes an existing business object data with 3 subpartition values with namespace <p> Requires WRITE permission on namespace </p> * * @param namespace the namespace. * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param subPartition1Value sub-partition value 1 * @param subPartition2Value sub-partition value 2 * @param subPartition3Value sub-partition value 3 * @param businessObjectDataVersion the business object data version * @param deleteFiles whether files should be deleted * * @return the deleted business object data information */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}" + "/partitionValues/{partitionValue}/subPartition1Values/{subPartition1Value}/subPartition2Values/{subPartition2Value}" + "/subPartition3Values/{subPartition3Value}/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.DELETE) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_DELETE) public BusinessObjectData deleteBusinessObjectData(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("subPartition1Value") String subPartition1Value, @PathVariable("subPartition2Value") String subPartition2Value, @PathVariable("subPartition3Value") String subPartition3Value, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam("deleteFiles") Boolean deleteFiles) { return businessObjectDataService.deleteBusinessObjectData( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, Arrays.asList(subPartition1Value, subPartition2Value, subPartition3Value), businessObjectDataVersion), deleteFiles); } /** * Deletes an existing business object data with 4 subpartition values with namespace. <p> Requires WRITE permission on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param subPartition1Value sub-partition value 1 * @param subPartition2Value sub-partition value 2 * @param subPartition3Value sub-partition value 3 * @param subPartition4Value sub-partition value 4 * @param businessObjectDataVersion the business object data version * @param deleteFiles whether files should be deleted * * @return the deleted business object data information */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}" + "/partitionValues/{partitionValue}/subPartition1Values/{subPartition1Value}/subPartition2Values/{subPartition2Value}" + "/subPartition3Values/{subPartition3Value}/subPartition4Values/{subPartition4Value}/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.DELETE) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_DELETE) public BusinessObjectData deleteBusinessObjectData(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("subPartition1Value") String subPartition1Value, @PathVariable("subPartition2Value") String subPartition2Value, @PathVariable("subPartition3Value") String subPartition3Value, @PathVariable("subPartition4Value") String subPartition4Value, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam("deleteFiles") Boolean deleteFiles) { return businessObjectDataService.deleteBusinessObjectData( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, Arrays.asList(subPartition1Value, subPartition2Value, subPartition3Value, subPartition4Value), businessObjectDataVersion), deleteFiles); } /** * Retrieves the DDL to initialize the specified type of the database system to perform queries for a range of requested business object data in the * specified storage. <p> Requires READ permission on namespace </p> * * @param businessObjectDataDdlRequest the business object data DDL request * * @return the business object data DDL information */ @RequestMapping(value = "/businessObjectData/generateDdl", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_GENERATE_DDL_POST) public BusinessObjectDataDdl generateBusinessObjectDataDdl(@RequestBody BusinessObjectDataDdlRequest businessObjectDataDdlRequest) { return businessObjectDataService.generateBusinessObjectDataDdl(businessObjectDataDdlRequest); } /** * Retrieves the DDL to initialize the specified type of the database system to perform queries for a collection of business object data in the specified * storage. <p> Requires READ permission on ALL namespaces </p> * * @param businessObjectDataDdlCollectionRequest the business object data DDL collection request * * @return the business object data DDL information */ @RequestMapping(value = "/businessObjectData/generateDdlCollection", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_GENERATE_DDL_COLLECTION_POST) public BusinessObjectDataDdlCollectionResponse generateBusinessObjectDataDdlCollection( @RequestBody BusinessObjectDataDdlCollectionRequest businessObjectDataDdlCollectionRequest) { return businessObjectDataService.generateBusinessObjectDataDdlCollection(businessObjectDataDdlCollectionRequest); } /** * Retrieves a list of keys for all existing business object data up to the limit configured in the system per specified business object definition. <p> * Results are sorted alphabetically by primary and sub-partition values descending. </p> <p> The limit on how many records this endpoint returns is set by * "business.object.data.search.max.results.per.page" configuration value. </p> <p> Requires READ permission on namespace. </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * * @return the list of business object data keys */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_BY_BUSINESS_OBJECT_DEFINITION_GET) public BusinessObjectDataKeys getAllBusinessObjectDataByBusinessObjectDefinition(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName) { return businessObjectDataService .getAllBusinessObjectDataByBusinessObjectDefinition(new BusinessObjectDefinitionKey(namespace, businessObjectDefinitionName)); } /** * Retrieves a list of keys for all existing business object data up to the limit configured in the system per specified business object format. <p> Results * are sorted alphabetically by primary and sub-partition values descending. </p> <p> The limit on how many records this endpoint returns is set by * "business.object.data.search.max.results.per.page" configuration value. </p> <p> Requires READ permission on namespace. </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * * @return the list of business object data keys */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_BY_BUSINESS_OBJECT_FORMAT_GET) public BusinessObjectDataKeys getAllBusinessObjectDataByBusinessObjectFormat(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion) { return businessObjectDataService.getAllBusinessObjectDataByBusinessObjectFormat( new BusinessObjectFormatKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion)); } /** * Retrieves existing business object data entry information. <p/> NOTE: When both business object format version and business object data version are not * specified, the business object format version has the precedence. The latest business object format version is determined by a sub-query, which does the * following: <p> <ul> <li>selects all available data for the specified business object format (disregarding business object format version), partition * values, and business object data status (default is "VALID") <li>gets the latest business object format version from the records selected in the previous * step </ul> <p> <p> Requires READ permission on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatPartitionKey the partition key of the business object format. When specified, the partition key is validated against the * partition key associated with the relative business object format * @param partitionValue the partition value of the business object data * @param subPartitionValues the list of sub-partition values delimited by "|" (delimiter can be escaped by "\") * @param businessObjectFormatVersion the version of the business object format. When the business object format version is not specified, the business * object data with the latest business format version available for the specified partition values is returned * @param businessObjectDataVersion the version of the business object data. When business object data version is not specified, the latest version of * business object data of the specified business object data status is returned * @param businessObjectDataStatus the status of the business object data. When business object data version is specified, this parameter is ignored. * Default value is "VALID" * @param includeBusinessObjectDataStatusHistory specifies to include business object data status history in the response * * @return the retrieved business object data information */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_GET) public BusinessObjectData getBusinessObjectData(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @RequestParam(value = "partitionKey", required = false) String businessObjectFormatPartitionKey, @RequestParam("partitionValue") String partitionValue, @RequestParam(value = "subPartitionValues", required = false) DelimitedFieldValues subPartitionValues, @RequestParam(value = "businessObjectFormatVersion", required = false) Integer businessObjectFormatVersion, @RequestParam(value = "businessObjectDataVersion", required = false) Integer businessObjectDataVersion, @RequestParam(value = "businessObjectDataStatus", required = false) String businessObjectDataStatus, @RequestParam(value = "includeBusinessObjectDataStatusHistory", required = false) Boolean includeBusinessObjectDataStatusHistory) { return businessObjectDataService.getBusinessObjectData( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, getList(subPartitionValues), businessObjectDataVersion), businessObjectFormatPartitionKey, businessObjectDataStatus, includeBusinessObjectDataStatusHistory); } /** * Gets the AWS credential to download to the specified business object data and storage. <p> Requires READ permission on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param businessObjectDataVersion the business object data version * @param storageName the storage name * @param subPartitionValues the list of sub-partition values * * @return AWS credential */ @RequestMapping(value = "/businessObjectData/download/credential/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}" + "/partitionValues/{partitionValue}/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_DOWNLOAD_CREDENTIAL_GET) @ApiOperation(value = "Gets Business Object Data Download Credentials. This is not meant for public consumption.", hidden = true) public BusinessObjectDataDownloadCredential getBusinessObjectDataDownloadCredential(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam(value = "storageName", required = true) String storageName, @RequestParam(value = "subPartitionValues", required = false) DelimitedFieldValues subPartitionValues) { StorageUnitDownloadCredential storageUnitDownloadCredential = storageUnitService.getStorageUnitDownloadCredential( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, getList(subPartitionValues), businessObjectDataVersion), storageName); return new BusinessObjectDataDownloadCredential(storageUnitDownloadCredential.getAwsCredential()); } /** * Gets the AWS credential to upload to the specified business object data and storage. <p> Requires WRITE permission on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param businessObjectDataVersion the business object data version * @param createNewVersion flag to create new version * @param storageName the storage name * @param subPartitionValues the list of sub-partition values * * @return AWS credential */ @RequestMapping(value = "/businessObjectData/upload/credential/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/businessObjectFormatVersions/{businessObjectFormatVersion}" + "/partitionValues/{partitionValue}", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_UPLOAD_CREDENTIAL_GET) @ApiOperation(value = "Gets Business Object Data Upload Credentials. This is not meant for public consumption.", hidden = true) public BusinessObjectDataUploadCredential getBusinessObjectDataUploadCredential(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @RequestParam(value = "businessObjectDataVersion", required = false) Integer businessObjectDataVersion, @RequestParam(value = "createNewVersion", required = false) Boolean createNewVersion, @RequestParam(value = "storageName", required = true) String storageName, @RequestParam(value = "subPartitionValues", required = false) DelimitedFieldValues subPartitionValues) { StorageUnitUploadCredential storageUnitUploadCredential = storageUnitService.getStorageUnitUploadCredential( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, getList(subPartitionValues), businessObjectDataVersion), createNewVersion, storageName); return new BusinessObjectDataUploadCredential(storageUnitUploadCredential.getAwsCredential(), storageUnitUploadCredential.getAwsKmsKeyId()); } /** * Retrieves a list of existing business object data versions. <p> Requires READ permission on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param partitionValue the partition value * @param subPartitionValues the list of sub-partition values * @param businessObjectFormatVersion the business object format version * @param businessObjectDataVersion the business object data version * * @return the retrieved business object data versions */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}" + "/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages/{businessObjectFormatUsage}" + "/businessObjectFormatFileTypes/{businessObjectFormatFileType}/versions", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_VERSIONS_GET) public BusinessObjectDataVersions getBusinessObjectDataVersions(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @RequestParam("partitionValue") String partitionValue, @RequestParam(value = "subPartitionValues", required = false) DelimitedFieldValues subPartitionValues, @RequestParam(value = "businessObjectFormatVersion", required = false) Integer businessObjectFormatVersion, @RequestParam(value = "businessObjectDataVersion", required = false) Integer businessObjectDataVersion) { return businessObjectDataService.getBusinessObjectDataVersions( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, getList(subPartitionValues), businessObjectDataVersion)); } /** * <p> Gets the S3 key prefix for writing or accessing business object data. </p> <p> This endpoint requires a namespace. </p> <p> Requires READ permission * on namespace </p> * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the business object format version * @param partitionKey the partition key * @param partitionValue the partition value * @param subPartitionValues the list of sub-partition values * @param businessObjectDataVersion the business object data version * @param storageName the storage name * @param createNewVersion Whether a new business object data can be created * @param servletRequest the servlet request * * @return the S3 key prefix */ @RequestMapping( value = "/businessObjectData/namespaces/{namespace}/businessObjectDefinitionNames/{businessObjectDefinitionName}/businessObjectFormatUsages" + "/{businessObjectFormatUsage}/businessObjectFormatFileTypes/{businessObjectFormatFileType}" + "/businessObjectFormatVersions/{businessObjectFormatVersion}/s3KeyPrefix", method = RequestMethod.GET) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_S3_KEY_PREFIX_GET) @ApiOperation(value = "Gets the S3 key prefix information for a specified namespace") public S3KeyPrefixInformation getS3KeyPrefix(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @RequestParam(value = "partitionKey", required = false) String partitionKey, @RequestParam("partitionValue") String partitionValue, @RequestParam(value = "subPartitionValues", required = false) DelimitedFieldValues subPartitionValues, @RequestParam(value = "businessObjectDataVersion", required = false) Integer businessObjectDataVersion, @RequestParam(value = "storageName", required = false) String storageName, @RequestParam(value = "createNewVersion", required = false, defaultValue = "false") Boolean createNewVersion, ServletRequest servletRequest) { return storageUnitService.getS3KeyPrefix( validateRequestAndCreateBusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, subPartitionValues, businessObjectDataVersion, servletRequest), partitionKey, storageName, createNewVersion); } /** * Registers data as INVALID for objects which exist in S3 but are not registered in herd. <p> Requires WRITE permission on namespace </p> * * @param businessObjectDataInvalidateUnregisteredRequest the business object data invalidate un-register request * * @return the business object data invalidate unregistered response */ @RequestMapping(value = "/businessObjectData/unregistered/invalidation", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_UNREGISTERED_INVALIDATE) public BusinessObjectDataInvalidateUnregisteredResponse invalidateUnregisteredBusinessObjectData( @RequestBody BusinessObjectDataInvalidateUnregisteredRequest businessObjectDataInvalidateUnregisteredRequest) { BusinessObjectDataInvalidateUnregisteredResponse businessObjectDataInvalidateUnregisteredResponse = businessObjectDataService.invalidateUnregisteredBusinessObjectData(businessObjectDataInvalidateUnregisteredRequest); // Trigger notifications. businessObjectDataDaoHelper.triggerNotificationsForInvalidateUnregisteredBusinessObjectData(businessObjectDataInvalidateUnregisteredResponse); return businessObjectDataInvalidateUnregisteredResponse; } /** * Initiates a restore request for a currently archived business object data. * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format file type * @param businessObjectFormatVersion the version of the business object format * @param partitionValue the primary partition value of the business object data * @param businessObjectDataVersion the version of the business object data * @param subPartitionValues the list of sub-partition values delimited by "|" (delimiter can be escaped by "\") * @param expirationInDays the time, in days, between when the business object data is restored to the S3 bucket and when it expires * * @return the business object data information */ @RequestMapping( value = "/businessObjectData/restore/namespaces/{namespace}/businessObjectDefinitionNames/{businessObjectDefinitionName}" + "/businessObjectFormatUsages/{businessObjectFormatUsage}/businessObjectFormatFileTypes/{businessObjectFormatFileType}" + "/businessObjectFormatVersions/{businessObjectFormatVersion}/partitionValues/{partitionValue}" + "/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_RESTORE_POST) public BusinessObjectData restoreBusinessObjectData(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam(value = "subPartitionValues", required = false) DelimitedFieldValues subPartitionValues, @RequestParam(value = "expirationInDays", required = false) Integer expirationInDays) { return businessObjectDataService.restoreBusinessObjectData( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, getList(subPartitionValues), businessObjectDataVersion), expirationInDays); } /** * Retries a storage policy transition by forcing re-initiation of the archiving process for the specified business object data that is still in progress of * a valid archiving operation. This endpoint is designed to be run only after confirmation that the business object data is stuck due to an error during * archiving. * * @param namespace the namespace of the business object definition * @param businessObjectDefinitionName the name of the business object definition * @param businessObjectFormatUsage the usage of the business object format * @param businessObjectFormatFileType the file type of the business object format * @param businessObjectFormatVersion the version of the business object format * @param partitionValue the primary partition value of the business object data * @param businessObjectDataVersion the version of the business object data * @param subPartitionValues the optional list of sub-partition values delimited by "|" (delimiter can be escaped by "\") * @param request the information needed to retry a storage policy transition * * @return the business object data information */ @RequestMapping( value = "/businessObjectData/retryStoragePolicyTransition/namespaces/{namespace}/businessObjectDefinitionNames/{businessObjectDefinitionName}" + "/businessObjectFormatUsages/{businessObjectFormatUsage}/businessObjectFormatFileTypes/{businessObjectFormatFileType}" + "/businessObjectFormatVersions/{businessObjectFormatVersion}/partitionValues/{partitionValue}" + "/businessObjectDataVersions/{businessObjectDataVersion}", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_RETRY_STORAGE_POLICY_TRANSITION_POST) public BusinessObjectData retryStoragePolicyTransition(@PathVariable("namespace") String namespace, @PathVariable("businessObjectDefinitionName") String businessObjectDefinitionName, @PathVariable("businessObjectFormatUsage") String businessObjectFormatUsage, @PathVariable("businessObjectFormatFileType") String businessObjectFormatFileType, @PathVariable("businessObjectFormatVersion") Integer businessObjectFormatVersion, @PathVariable("partitionValue") String partitionValue, @PathVariable("businessObjectDataVersion") Integer businessObjectDataVersion, @RequestParam(value = "subPartitionValues", required = false) DelimitedFieldValues subPartitionValues, @RequestBody BusinessObjectDataRetryStoragePolicyTransitionRequest request) { return businessObjectDataService.retryStoragePolicyTransition( new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, getList(subPartitionValues), businessObjectDataVersion), request); } /** * Searches business object data based on namespace, definition name, format usage, file type, and format version. <p> Namespace and definition name are * required. </p> <p> Requires READ permission on namespace </p> * * @param businessObjectDataSearchRequest search request * * @return search result */ @RequestMapping(value = "/businessObjectData/search", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}) @Secured(SecurityFunctions.FN_BUSINESS_OBJECT_DATA_SEARCH_POST) public BusinessObjectDataSearchResult searchBusinessObjectData(@RequestBody BusinessObjectDataSearchRequest businessObjectDataSearchRequest) { return businessObjectDataService.searchBusinessObjectData(businessObjectDataSearchRequest); } /** * Validates the given {@code servletRequest} and constructs a new {@link BusinessObjectDataKey}. The {@code servletRequest} validation involves validations * of request parameters which Spring MVC may not implement out-of-the-box. In our case, the request is asserted to no contain duplicate parameters. * * @param namespace the namespace * @param businessObjectDefinitionName the business object definition name * @param businessObjectFormatUsage the business object format usage * @param businessObjectFormatFileType the business object format type * @param businessObjectFormatVersion the business object format version * @param partitionValue the partition value * @param subPartitionValues the list of sub-partition values * @param businessObjectDataVersion the business object data version * @param servletRequest the servlet request * * @return a new {@link BusinessObjectDataKey} */ private BusinessObjectDataKey validateRequestAndCreateBusinessObjectDataKey(String namespace, String businessObjectDefinitionName, String businessObjectFormatUsage, String businessObjectFormatFileType, Integer businessObjectFormatVersion, String partitionValue, DelimitedFieldValues subPartitionValues, Integer businessObjectDataVersion, ServletRequest servletRequest) { // Ensure there are no duplicate query string parameters. validateNoDuplicateQueryStringParams(servletRequest.getParameterMap(), "partitionKey", "partitionValue"); // Invoke the service. return new BusinessObjectDataKey(namespace, businessObjectDefinitionName, businessObjectFormatUsage, businessObjectFormatFileType, businessObjectFormatVersion, partitionValue, getList(subPartitionValues), businessObjectDataVersion); } }