org.finra.herd.service.impl.RelationalTableRegistrationHelperServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of herd-service Show documentation
Show all versions of herd-service Show documentation
This project contains the business service code. This is a classic service tier where business logic is defined along with it's associated
transaction management configuration.
/*
* 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.service.impl;
import static org.finra.herd.model.dto.SearchIndexUpdateDto.SEARCH_INDEX_UPDATE_TYPE_CREATE;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.finra.herd.core.helper.ConfigurationHelper;
import org.finra.herd.dao.BusinessObjectDataDao;
import org.finra.herd.dao.BusinessObjectDefinitionDao;
import org.finra.herd.dao.BusinessObjectFormatDao;
import org.finra.herd.dao.config.DaoSpringModuleConfig;
import org.finra.herd.dao.exception.CredStashGetCredentialFailedException;
import org.finra.herd.dao.helper.CredStashHelper;
import org.finra.herd.dao.helper.JsonHelper;
import org.finra.herd.model.AlreadyExistsException;
import org.finra.herd.model.annotation.PublishNotificationMessages;
import org.finra.herd.model.api.xml.Attribute;
import org.finra.herd.model.api.xml.BusinessObjectData;
import org.finra.herd.model.api.xml.BusinessObjectDataStorageUnitKey;
import org.finra.herd.model.api.xml.BusinessObjectDefinitionCreateRequest;
import org.finra.herd.model.api.xml.BusinessObjectDefinitionKey;
import org.finra.herd.model.api.xml.BusinessObjectFormat;
import org.finra.herd.model.api.xml.BusinessObjectFormatCreateRequest;
import org.finra.herd.model.api.xml.BusinessObjectFormatKey;
import org.finra.herd.model.api.xml.RelationalTableRegistrationCreateRequest;
import org.finra.herd.model.api.xml.Schema;
import org.finra.herd.model.api.xml.SchemaColumn;
import org.finra.herd.model.dto.ConfigurationValue;
import org.finra.herd.model.dto.RelationalStorageAttributesDto;
import org.finra.herd.model.dto.RelationalTableRegistrationDto;
import org.finra.herd.model.jpa.BusinessObjectDataEntity;
import org.finra.herd.model.jpa.BusinessObjectDataStatusEntity;
import org.finra.herd.model.jpa.BusinessObjectDefinitionEntity;
import org.finra.herd.model.jpa.BusinessObjectFormatEntity;
import org.finra.herd.model.jpa.FileTypeEntity;
import org.finra.herd.model.jpa.StorageEntity;
import org.finra.herd.model.jpa.StoragePlatformEntity;
import org.finra.herd.model.jpa.StorageUnitEntity;
import org.finra.herd.model.jpa.StorageUnitStatusEntity;
import org.finra.herd.service.BusinessObjectFormatService;
import org.finra.herd.service.MessageNotificationEventService;
import org.finra.herd.service.RelationalTableRegistrationHelperService;
import org.finra.herd.service.helper.AlternateKeyHelper;
import org.finra.herd.service.helper.BusinessObjectDataHelper;
import org.finra.herd.service.helper.BusinessObjectDataStatusDaoHelper;
import org.finra.herd.service.helper.BusinessObjectDefinitionDaoHelper;
import org.finra.herd.service.helper.BusinessObjectFormatDaoHelper;
import org.finra.herd.service.helper.BusinessObjectFormatHelper;
import org.finra.herd.service.helper.DataProviderDaoHelper;
import org.finra.herd.service.helper.NamespaceDaoHelper;
import org.finra.herd.service.helper.RelationalTableRegistrationHelper;
import org.finra.herd.service.helper.SearchIndexUpdateHelper;
import org.finra.herd.service.helper.StorageDaoHelper;
import org.finra.herd.service.helper.StorageHelper;
import org.finra.herd.service.helper.StorageUnitDaoHelper;
import org.finra.herd.service.helper.StorageUnitStatusDaoHelper;
/**
* An implementation of the helper service class for the relational table registration service.
*/
@Service
@Transactional(value = DaoSpringModuleConfig.HERD_TRANSACTION_MANAGER_BEAN_NAME)
public class RelationalTableRegistrationHelperServiceImpl implements RelationalTableRegistrationHelperService
{
private static final Logger LOGGER = LoggerFactory.getLogger(RelationalTableRegistrationHelperServiceImpl.class);
@Autowired
private AlternateKeyHelper alternateKeyHelper;
@Autowired
private BusinessObjectDataDao businessObjectDataDao;
@Autowired
private BusinessObjectDataHelper businessObjectDataHelper;
@Autowired
private BusinessObjectDataStatusDaoHelper businessObjectDataStatusDaoHelper;
@Autowired
private BusinessObjectDefinitionDao businessObjectDefinitionDao;
@Autowired
private BusinessObjectDefinitionDaoHelper businessObjectDefinitionDaoHelper;
@Autowired
private BusinessObjectFormatDao businessObjectFormatDao;
@Autowired
private BusinessObjectFormatDaoHelper businessObjectFormatDaoHelper;
@Autowired
private BusinessObjectFormatHelper businessObjectFormatHelper;
@Autowired
private BusinessObjectFormatService businessObjectFormatService;
@Autowired
private ConfigurationHelper configurationHelper;
@Autowired
private CredStashHelper credStashHelper;
@Autowired
private DataProviderDaoHelper dataProviderDaoHelper;
@Autowired
private JsonHelper jsonHelper;
@Autowired
private MessageNotificationEventService messageNotificationEventService;
@Autowired
private NamespaceDaoHelper namespaceDaoHelper;
@Autowired
private RelationalTableRegistrationHelper relationalTableRegistrationHelper;
@Autowired
private SearchIndexUpdateHelper searchIndexUpdateHelper;
@Autowired
private StorageDaoHelper storageDaoHelper;
@Autowired
private StorageHelper storageHelper;
@Autowired
private StorageUnitDaoHelper storageUnitDaoHelper;
@Autowired
private StorageUnitStatusDaoHelper storageUnitStatusDaoHelper;
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public RelationalStorageAttributesDto prepareForRelationalTableRegistration(
RelationalTableRegistrationCreateRequest relationalTableRegistrationCreateRequest, Boolean appendToExistingBusinessObjectDefinition)
{
return prepareForRelationalTableRegistrationImpl(relationalTableRegistrationCreateRequest, appendToExistingBusinessObjectDefinition);
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public RelationalTableRegistrationDto prepareForRelationalTableSchemaUpdate(BusinessObjectDataStorageUnitKey storageUnitKey)
{
return prepareForRelationalTableSchemaUpdateImpl(storageUnitKey);
}
@PublishNotificationMessages
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public BusinessObjectData registerRelationalTable(RelationalTableRegistrationCreateRequest relationalTableRegistrationCreateRequest,
List schemaColumns, Boolean appendToExistingBusinessObjectDefinition)
{
return registerRelationalTableImpl(relationalTableRegistrationCreateRequest, schemaColumns, appendToExistingBusinessObjectDefinition);
}
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List retrieveRelationalTableColumns(RelationalStorageAttributesDto relationalStorageAttributesDto, String relationalSchemaName,
String relationalTableName)
{
return retrieveRelationalTableColumnsImpl(relationalStorageAttributesDto, relationalSchemaName, relationalTableName);
}
@PublishNotificationMessages
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public BusinessObjectData updateRelationalTableSchema(RelationalTableRegistrationDto relationalTableRegistrationDto, List schemaColumns)
{
return updateRelationalTableSchemaImpl(relationalTableRegistrationDto, schemaColumns);
}
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void validateAndTrimRelationalTableRegistrationCreateRequest(RelationalTableRegistrationCreateRequest relationalTableRegistrationCreateRequest)
{
validateAndTrimRelationalTableRegistrationCreateRequestImpl(relationalTableRegistrationCreateRequest);
}
/**
* Gets a password value that should be used to connect to the relational storage.
*
* @param relationalStorageAttributesDto the relational storage attributes DTO
*
* @return the password value
*/
String getPassword(RelationalStorageAttributesDto relationalStorageAttributesDto)
{
// Default password value to null.
String password = null;
// Check if we need to get a password value from the credstash.
if (StringUtils.isNotBlank(relationalStorageAttributesDto.getJdbcUserCredentialName()))
{
final String credStashEncryptionContext = configurationHelper.getProperty(ConfigurationValue.CREDSTASH_RELATIONAL_STORAGE_ENCRYPTION_CONTEXT);
try
{
password = credStashHelper.getCredentialFromCredStash(credStashEncryptionContext, relationalStorageAttributesDto.getJdbcUserCredentialName());
}
catch (CredStashGetCredentialFailedException e)
{
throw new IllegalStateException(e);
}
}
return password;
}
/**
* Prepares for relational table registration by validating database entities per specified relational table registration create request. This method
* returns storage attributes required to perform relation table registration.
*
* @param relationalTableRegistrationCreateRequest the relational table registration create request
* @param appendToExistingBusinessObjectDefinition boolean flag that determines if the format should be appended to an existing business object definition
*
* @return the relational storage attributes DTO
*/
RelationalStorageAttributesDto prepareForRelationalTableRegistrationImpl(RelationalTableRegistrationCreateRequest relationalTableRegistrationCreateRequest,
Boolean appendToExistingBusinessObjectDefinition)
{
// Validate that specified namespace exists.
namespaceDaoHelper.getNamespaceEntity(relationalTableRegistrationCreateRequest.getNamespace());
// Create a business object definition key.
BusinessObjectDefinitionKey businessObjectDefinitionKey = new BusinessObjectDefinitionKey(relationalTableRegistrationCreateRequest.getNamespace(),
relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionName());
// Ensure that a business object definition with the specified key doesn't already exist.
if (BooleanUtils.isNotTrue(appendToExistingBusinessObjectDefinition) &&
businessObjectDefinitionDao.getBusinessObjectDefinitionByKey(businessObjectDefinitionKey) != null)
{
throw new AlreadyExistsException(String.format("Business object definition with name \"%s\" already exists for namespace \"%s\".",
businessObjectDefinitionKey.getBusinessObjectDefinitionName(), businessObjectDefinitionKey.getNamespace()));
}
// Get the latest format version for this business format, if it exists.
BusinessObjectFormatEntity latestVersionBusinessObjectFormatEntity = businessObjectFormatDao.getBusinessObjectFormatByAltKey(
new BusinessObjectFormatKey(relationalTableRegistrationCreateRequest.getNamespace(),
relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionName(),
relationalTableRegistrationCreateRequest.getBusinessObjectFormatUsage(), FileTypeEntity.RELATIONAL_TABLE_FILE_TYPE, null));
// If the latest version exists, fail with an already exists exception.
if (latestVersionBusinessObjectFormatEntity != null)
{
throw new AlreadyExistsException(String
.format("Format with file type \"%s\" and usage \"%s\" already exists for business object definition \"%s\".",
latestVersionBusinessObjectFormatEntity.getFileType().getCode(), latestVersionBusinessObjectFormatEntity.getUsage(),
latestVersionBusinessObjectFormatEntity.getBusinessObjectDefinition().getName()));
}
// Validate that specified data provider exists.
dataProviderDaoHelper.getDataProviderEntity(relationalTableRegistrationCreateRequest.getDataProviderName());
// Get the storage.
StorageEntity storageEntity = storageDaoHelper.getStorageEntity(relationalTableRegistrationCreateRequest.getStorageName());
// Only RELATIONAL storage platform is supported for the relational table registration feature.
Assert.isTrue(storageEntity.getStoragePlatform().getName().equals(StoragePlatformEntity.RELATIONAL), String.format(
"Cannot register relational table in \"%s\" storage of %s storage platform type. Only %s storage platform type is supported by this feature.",
storageEntity.getName(), storageEntity.getStoragePlatform().getName(), StoragePlatformEntity.RELATIONAL));
// Get and return the relational storage attributes required to access relation table schema.
return getRelationalStorageAttributes(storageEntity);
}
/**
* Prepares for relational table schema update by validating database entities per specified storage unit key. This method returns a relational table
* registration DTO which contains attributes required to retrieve the current relation table schema.
*
* @param storageUnitKey the storage unit key for the relational table registration
*
* @return the relational table registration DTO
*/
RelationalTableRegistrationDto prepareForRelationalTableSchemaUpdateImpl(BusinessObjectDataStorageUnitKey storageUnitKey)
{
// Log the business object format create request.
LOGGER.info("Checking relational table registration for schema update... storageUnitKey={}", jsonHelper.objectToJson(storageUnitKey));
// Get the storage unit.
StorageUnitEntity storageUnitEntity = storageUnitDaoHelper.getStorageUnitEntityByKey(storageUnitKey);
// Get the business object format entity for this relation table registration.
BusinessObjectFormatEntity businessObjectFormatEntity = storageUnitEntity.getBusinessObjectData().getBusinessObjectFormat();
// Get relational schema name from the business object format. This business object format attribute is required and must have a non-blank value.
String relationalSchemaName = businessObjectFormatDaoHelper.getBusinessObjectFormatAttributeValueByName(
configurationHelper.getProperty(ConfigurationValue.BUSINESS_OBJECT_FORMAT_ATTRIBUTE_NAME_RELATIONAL_SCHEMA_NAME), businessObjectFormatEntity, true,
true);
// Get relational table name from the business object format. This business object format attribute is required and must have a non-blank value.
String relationalTableName = businessObjectFormatDaoHelper.getBusinessObjectFormatAttributeValueByName(
configurationHelper.getProperty(ConfigurationValue.BUSINESS_OBJECT_FORMAT_ATTRIBUTE_NAME_RELATIONAL_TABLE_NAME), businessObjectFormatEntity, true,
true);
// Get relational storage attributes required to access relation table schema.
RelationalStorageAttributesDto relationalStorageAttributesDto = getRelationalStorageAttributes(storageUnitEntity.getStorage());
// Get business object format for the relational table registration.
BusinessObjectFormat businessObjectFormat = businessObjectFormatHelper.createBusinessObjectFormatFromEntity(businessObjectFormatEntity);
// Create and return a relational storage attributes DTO.
return new RelationalTableRegistrationDto(storageUnitKey, relationalStorageAttributesDto, relationalSchemaName, relationalTableName,
businessObjectFormat);
}
/**
* Creates a new relational table registration. The relation table registration includes creation of the following entities: - a business object
* definition
- a business object format with the specified schema columns
- a business object data
- a storage unit that links
* together the business object data with the storage specified in the create request
*
* @param relationalTableRegistrationCreateRequest the relational table registration create request
* @param schemaColumns the list of schema columns
* @param appendToExistingBusinessObjectDefinition boolean flag that determines if the format should be appended to an existing business object definition
*
* @return the information for the newly created business object data
*/
BusinessObjectData registerRelationalTableImpl(RelationalTableRegistrationCreateRequest relationalTableRegistrationCreateRequest,
List schemaColumns, Boolean appendToExistingBusinessObjectDefinition)
{
BusinessObjectDefinitionEntity businessObjectDefinitionEntity;
// If we are appending the new business object format to an already existing business object definition,
// then get the business object definition with the information in the relational table registration create request,
// else create a new business object definition with the information in the relational table registration create request.
if (BooleanUtils.isTrue(appendToExistingBusinessObjectDefinition))
{
// Get the existing business object definition
businessObjectDefinitionEntity = businessObjectDefinitionDaoHelper.getBusinessObjectDefinitionEntity(
new BusinessObjectDefinitionKey(relationalTableRegistrationCreateRequest.getNamespace(),
relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionName()));
}
else
{
// Create a business object definition.
businessObjectDefinitionEntity = businessObjectDefinitionDaoHelper.createBusinessObjectDefinitionEntity(
new BusinessObjectDefinitionCreateRequest(relationalTableRegistrationCreateRequest.getNamespace(),
relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionName(), relationalTableRegistrationCreateRequest.getDataProviderName(),
null, relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionDisplayName(), null));
}
// Notify the search index that a business object definition is created.
LOGGER.info("Create the business object definition in the search index associated with the business object definition being created." +
" businessObjectDefinitionId=\"{}\", searchIndexUpdateType=\"{}\"", businessObjectDefinitionEntity.getId(), SEARCH_INDEX_UPDATE_TYPE_CREATE);
searchIndexUpdateHelper.modifyBusinessObjectDefinitionInSearchIndex(businessObjectDefinitionEntity, SEARCH_INDEX_UPDATE_TYPE_CREATE);
// Build a business object format create request.
// Store the relational table name as a business object format attribute per attribute name configured in the system.
BusinessObjectFormatCreateRequest businessObjectFormatCreateRequest = new BusinessObjectFormatCreateRequest();
businessObjectFormatCreateRequest.setNamespace(relationalTableRegistrationCreateRequest.getNamespace());
businessObjectFormatCreateRequest.setBusinessObjectDefinitionName(relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionName());
businessObjectFormatCreateRequest.setBusinessObjectFormatUsage(relationalTableRegistrationCreateRequest.getBusinessObjectFormatUsage());
businessObjectFormatCreateRequest.setBusinessObjectFormatFileType(FileTypeEntity.RELATIONAL_TABLE_FILE_TYPE);
businessObjectFormatCreateRequest.setPartitionKey(BusinessObjectDataServiceImpl.NO_PARTITIONING_PARTITION_KEY);
businessObjectFormatCreateRequest.setAttributes(Arrays.asList(
new Attribute(configurationHelper.getProperty(ConfigurationValue.BUSINESS_OBJECT_FORMAT_ATTRIBUTE_NAME_RELATIONAL_SCHEMA_NAME),
relationalTableRegistrationCreateRequest.getRelationalSchemaName()),
new Attribute(configurationHelper.getProperty(ConfigurationValue.BUSINESS_OBJECT_FORMAT_ATTRIBUTE_NAME_RELATIONAL_TABLE_NAME),
relationalTableRegistrationCreateRequest.getRelationalTableName())));
businessObjectFormatCreateRequest.setSchema(new Schema(schemaColumns, null, "", null, null, null, null, null, null));
// Log the business object format create request.
LOGGER.info("Registering relational table... businessObjectFormatCreateRequest={}", jsonHelper.objectToJson(businessObjectFormatCreateRequest));
// Create a business object format.
BusinessObjectFormat businessObjectFormat = businessObjectFormatService.createBusinessObjectFormat(businessObjectFormatCreateRequest);
// Retrieve the newly created business object format entity.
BusinessObjectFormatEntity businessObjectFormatEntity =
businessObjectFormatDaoHelper.getBusinessObjectFormatEntity(businessObjectFormatHelper.getBusinessObjectFormatKey(businessObjectFormat));
// Allow non-backwards-compatible schema changes.
businessObjectFormatEntity.setAllowNonBackwardsCompatibleChanges(true);
businessObjectFormatDao.saveAndRefresh(businessObjectFormatEntity);
// Get a business object data status entity for the VALID status.
BusinessObjectDataStatusEntity businessObjectDataStatusEntity =
businessObjectDataStatusDaoHelper.getBusinessObjectDataStatusEntity(BusinessObjectDataStatusEntity.VALID);
// Create a business object data entity.
BusinessObjectDataEntity businessObjectDataEntity = new BusinessObjectDataEntity();
businessObjectDataEntity.setBusinessObjectFormat(businessObjectFormatEntity);
businessObjectDataEntity.setStatus(businessObjectDataStatusEntity);
businessObjectDataEntity.setVersion(0);
businessObjectDataEntity.setLatestVersion(true);
businessObjectDataEntity.setPartitionValue(BusinessObjectDataServiceImpl.NO_PARTITIONING_PARTITION_VALUE);
// Get a storage unit status entity for the ENABLED status.
StorageUnitStatusEntity storageUnitStatusEntity = storageUnitStatusDaoHelper.getStorageUnitStatusEntity(StorageUnitStatusEntity.ENABLED);
// Get the storage.
StorageEntity storageEntity = storageDaoHelper.getStorageEntity(relationalTableRegistrationCreateRequest.getStorageName());
// Create a storage unit entity.
StorageUnitEntity storageUnitEntity = new StorageUnitEntity();
storageUnitEntity.setStorage(storageEntity);
storageUnitEntity.setBusinessObjectData(businessObjectDataEntity);
storageUnitDaoHelper.setStorageUnitStatus(storageUnitEntity, storageUnitStatusEntity);
businessObjectDataEntity.setStorageUnits(Collections.singletonList(storageUnitEntity));
// Persist the newly created business object data entity.
businessObjectDataEntity = businessObjectDataDao.saveAndRefresh(businessObjectDataEntity);
// Create a status change notification to be sent on create business object data event.
messageNotificationEventService
.processBusinessObjectDataStatusChangeNotificationEvent(businessObjectDataHelper.getBusinessObjectDataKey(businessObjectDataEntity),
businessObjectDataStatusEntity.getCode(), null);
// Create and return business object data information from the newly created business object data entity.
return businessObjectDataHelper.createBusinessObjectDataFromEntity(businessObjectDataEntity);
}
/**
* Retrieves a list of actual schema columns for the specified relational table. This method uses actual JDBC connection to retrieve a description of table
* columns.
*
* @param relationalStorageAttributesDto the relational storage attributes DTO
* @param relationalSchemaName the name of the relational database schema
* @param relationalTableName the name of the relational table
*
* @return the list of schema columns for the specified relational table
*/
List retrieveRelationalTableColumnsImpl(RelationalStorageAttributesDto relationalStorageAttributesDto, String relationalSchemaName,
String relationalTableName)
{
// Get the JDBC password value.
String password = getPassword(relationalStorageAttributesDto);
// Create and initialize a driver manager data source (a simple implementation of the standard JDBC interface).
// We only support PostgreSQL database type.
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setUrl(relationalStorageAttributesDto.getJdbcUrl());
driverManagerDataSource.setUsername(relationalStorageAttributesDto.getJdbcUsername());
driverManagerDataSource.setPassword(password);
driverManagerDataSource.setDriverClassName(JdbcServiceImpl.DRIVER_POSTGRES);
// Connect to the database and retrieve the relational table columns.
try (Connection connection = driverManagerDataSource.getConnection())
{
DatabaseMetaData databaseMetaData = connection.getMetaData();
// Check if the specified relational table exists in the database.
try (ResultSet tables = databaseMetaData.getTables(null, relationalSchemaName, relationalTableName, null))
{
Assert.isTrue(tables.next(), String
.format("Relational table with \"%s\" name not found under \"%s\" schema at jdbc.url=\"%s\" for jdbc.username=\"%s\".", relationalTableName,
relationalSchemaName, driverManagerDataSource.getUrl(), driverManagerDataSource.getUsername()));
}
// Retrieve the relational table columns.
try (ResultSet columns = databaseMetaData.getColumns(null, relationalSchemaName, relationalTableName, null))
{
return relationalTableRegistrationHelper.getSchemaColumns(columns);
}
}
catch (SQLException e)
{
throw new IllegalArgumentException(String.format("Failed to retrieve description of a relational table with \"%s\" name under \"%s\" schema " +
"at jdbc.url=\"%s\" using jdbc.username=\"%s\". Reason: %s", relationalTableName, relationalSchemaName, driverManagerDataSource.getUrl(),
driverManagerDataSource.getUsername(), e.getMessage()), e);
}
}
/**
* Updates relational table schema for an already existing relational table registration.
*
* @param relationalTableRegistrationDto the relational table registration DTO
* @param schemaColumns the new relational table schema
*
* @return the information for the business object data created for the updated relational table registration
*/
BusinessObjectData updateRelationalTableSchemaImpl(RelationalTableRegistrationDto relationalTableRegistrationDto, List schemaColumns)
{
// Build a create request for a new version of the business object format.
BusinessObjectFormatCreateRequest businessObjectFormatCreateRequest = new BusinessObjectFormatCreateRequest();
businessObjectFormatCreateRequest.setNamespace(relationalTableRegistrationDto.getBusinessObjectFormat().getNamespace());
businessObjectFormatCreateRequest
.setBusinessObjectDefinitionName(relationalTableRegistrationDto.getBusinessObjectFormat().getBusinessObjectDefinitionName());
businessObjectFormatCreateRequest.setBusinessObjectFormatUsage(relationalTableRegistrationDto.getBusinessObjectFormat().getBusinessObjectFormatUsage());
businessObjectFormatCreateRequest
.setBusinessObjectFormatFileType(relationalTableRegistrationDto.getBusinessObjectFormat().getBusinessObjectFormatFileType());
businessObjectFormatCreateRequest.setPartitionKey(relationalTableRegistrationDto.getBusinessObjectFormat().getPartitionKey());
businessObjectFormatCreateRequest.setAttributes(relationalTableRegistrationDto.getBusinessObjectFormat().getAttributes());
businessObjectFormatCreateRequest.setSchema(new Schema(schemaColumns, null, "", null, null, null, null, null, null));
// Log the relational table registration DTO along with the business object format create request.
LOGGER.info("Updating relational table schema... relationalTableRegistrationDto={} businessObjectFormatCreateRequest={}",
jsonHelper.objectToJson(relationalTableRegistrationDto), jsonHelper.objectToJson(businessObjectFormatCreateRequest));
// Create a new version of the business object format.
BusinessObjectFormat businessObjectFormat = businessObjectFormatService.createBusinessObjectFormat(businessObjectFormatCreateRequest);
// Retrieve the newly created business object format entity.
BusinessObjectFormatEntity businessObjectFormatEntity =
businessObjectFormatDaoHelper.getBusinessObjectFormatEntity(businessObjectFormatHelper.getBusinessObjectFormatKey(businessObjectFormat));
// Get a business object data status entity for the VALID status.
BusinessObjectDataStatusEntity businessObjectDataStatusEntity =
businessObjectDataStatusDaoHelper.getBusinessObjectDataStatusEntity(BusinessObjectDataStatusEntity.VALID);
// Create a business object data entity.
BusinessObjectDataEntity businessObjectDataEntity = new BusinessObjectDataEntity();
businessObjectDataEntity.setBusinessObjectFormat(businessObjectFormatEntity);
businessObjectDataEntity.setStatus(businessObjectDataStatusEntity);
businessObjectDataEntity.setVersion(0);
businessObjectDataEntity.setLatestVersion(true);
businessObjectDataEntity.setPartitionValue(BusinessObjectDataServiceImpl.NO_PARTITIONING_PARTITION_VALUE);
// Get a storage unit status entity for the ENABLED status.
StorageUnitStatusEntity storageUnitStatusEntity = storageUnitStatusDaoHelper.getStorageUnitStatusEntity(StorageUnitStatusEntity.ENABLED);
// Get the storage.
StorageEntity storageEntity = storageDaoHelper.getStorageEntity(relationalTableRegistrationDto.getStorageUnitKey().getStorageName());
// Create a storage unit entity.
StorageUnitEntity storageUnitEntity = new StorageUnitEntity();
storageUnitEntity.setStorage(storageEntity);
storageUnitEntity.setBusinessObjectData(businessObjectDataEntity);
storageUnitDaoHelper.setStorageUnitStatus(storageUnitEntity, storageUnitStatusEntity);
businessObjectDataEntity.setStorageUnits(Collections.singletonList(storageUnitEntity));
// Persist the newly created business object data entity.
businessObjectDataEntity = businessObjectDataDao.saveAndRefresh(businessObjectDataEntity);
// Create a status change notification to be sent on create business object data event.
messageNotificationEventService
.processBusinessObjectDataStatusChangeNotificationEvent(businessObjectDataHelper.getBusinessObjectDataKey(businessObjectDataEntity),
businessObjectDataStatusEntity.getCode(), null);
// Create and return business object data information from the newly created business object data entity.
return businessObjectDataHelper.createBusinessObjectDataFromEntity(businessObjectDataEntity);
}
/**
* Validates a relational table registration create request. This method also trims the request parameters.
*
* @param relationalTableRegistrationCreateRequest the relational table registration create request
*/
void validateAndTrimRelationalTableRegistrationCreateRequestImpl(RelationalTableRegistrationCreateRequest relationalTableRegistrationCreateRequest)
{
Assert.notNull(relationalTableRegistrationCreateRequest, "A relational table registration create request must be specified.");
// Validate and trim required parameters.
relationalTableRegistrationCreateRequest
.setNamespace(alternateKeyHelper.validateStringParameter("namespace", relationalTableRegistrationCreateRequest.getNamespace()));
relationalTableRegistrationCreateRequest.setBusinessObjectDefinitionName(alternateKeyHelper
.validateStringParameter("business object definition name", relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionName()));
relationalTableRegistrationCreateRequest.setBusinessObjectFormatUsage(alternateKeyHelper
.validateStringParameter("business object format usage", relationalTableRegistrationCreateRequest.getBusinessObjectFormatUsage()));
relationalTableRegistrationCreateRequest.setDataProviderName(
alternateKeyHelper.validateStringParameter("data provider name", relationalTableRegistrationCreateRequest.getDataProviderName()));
relationalTableRegistrationCreateRequest.setRelationalSchemaName(
alternateKeyHelper.validateStringParameter("relational schema name", relationalTableRegistrationCreateRequest.getRelationalSchemaName()));
relationalTableRegistrationCreateRequest.setRelationalTableName(
alternateKeyHelper.validateStringParameter("relational table name", relationalTableRegistrationCreateRequest.getRelationalTableName()));
relationalTableRegistrationCreateRequest
.setStorageName(alternateKeyHelper.validateStringParameter("storage name", relationalTableRegistrationCreateRequest.getStorageName()));
// Trim optional business object definition display name, if specified.
if (relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionDisplayName() != null)
{
relationalTableRegistrationCreateRequest
.setBusinessObjectDefinitionDisplayName(relationalTableRegistrationCreateRequest.getBusinessObjectDefinitionDisplayName().trim());
}
}
/**
* Returns storage attributes required to access relation table schema.
*
* @param storageEntity the storage entity
*
* @return the relational storage attributes DTO
*/
private RelationalStorageAttributesDto getRelationalStorageAttributes(StorageEntity storageEntity)
{
// Get JDBC URL for this storage. This storage attribute is required and must have a non-blank value.
String jdbcUrl = storageHelper
.getStorageAttributeValueByName(configurationHelper.getProperty(ConfigurationValue.STORAGE_ATTRIBUTE_NAME_JDBC_URL), storageEntity, true, true);
// Get JDBC username for this storage. This storage attribute is not required and it is allowed to have a blank value.
String jdbcUsername = storageHelper
.getStorageAttributeValueByName(configurationHelper.getProperty(ConfigurationValue.STORAGE_ATTRIBUTE_NAME_JDBC_USERNAME), storageEntity, false,
false);
// Get JDBC user credential name for this storage. This storage attribute is not required and it is allowed to have a blank value.
String jdbcUserCredentialName = storageHelper
.getStorageAttributeValueByName(configurationHelper.getProperty(ConfigurationValue.STORAGE_ATTRIBUTE_NAME_JDBC_USER_CREDENTIAL_NAME), storageEntity,
false, false);
// Create and return a relational storage attributes DTO.
return new RelationalStorageAttributesDto(jdbcUrl, jdbcUsername, jdbcUserCredentialName);
}
}