This is an automated email from the ASF dual-hosted git repository. machristie pushed a commit to branch custos-integration in repository https://gitbox.apache.org/repos/asf/airavata-data-catalog.git
commit 8bbbbfdb1052a20a054294ed6d1ed21702799526 Author: Marcus Christie <[email protected]> AuthorDate: Wed Mar 29 12:04:45 2023 -0400 Create the data product sharing entity if it doesn't exist Also integrates the owning user into the DataProduct data model. For #12 --- .../datacatalog/api/mapper/DataProductMapper.java | 10 +++++-- .../datacatalog/api/mapper/UserInfoMapper.java | 22 +++++++++++++++ .../datacatalog/api/model/DataProductEntity.java | 13 ++++++++- .../airavata/datacatalog/api/model/UserEntity.java | 14 +++++++++ .../api/service/DataCatalogAPIService.java | 17 +++++++++-- .../api/service/DataCatalogService.java | 3 +- .../api/service/impl/DataCatalogServiceImpl.java | 15 +++++++--- .../api/sharing/SharingManagerImpl.java | 33 ++++++++++++++++++---- .../stubs/src/main/proto/DataCatalogAPI.proto | 14 +++++---- 9 files changed, 120 insertions(+), 21 deletions(-) diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/mapper/DataProductMapper.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/mapper/DataProductMapper.java index 82b17f7..218727f 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/mapper/DataProductMapper.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/mapper/DataProductMapper.java @@ -27,6 +27,9 @@ public class DataProductMapper { @Autowired MetadataSchemaRepository metadataSchemaRepository; + @Autowired + UserInfoMapper userInfoMapper; + public void mapModelToEntity(DataProduct dataProduct, DataProductEntity dataProductEntity) { dataProductEntity.setName(dataProduct.getName()); @@ -34,8 +37,9 @@ public class DataProductMapper { if (dataProduct.hasParentDataProductId() && !dataProduct.getParentDataProductId().isEmpty()) { DataProductEntity parentDataProductEntity = dataProductRepository .findByExternalId(dataProduct.getParentDataProductId()) - .orElseThrow(() -> new EntityNotFoundException("Could not find the parent data product with the ID: " - + dataProduct.getParentDataProductId())); + .orElseThrow( + () -> new EntityNotFoundException("Could not find the parent data product with the ID: " + + dataProduct.getParentDataProductId())); dataProductEntity.setParentDataProductEntity(parentDataProductEntity); } if (dataProduct.hasMetadata()) { @@ -80,5 +84,7 @@ public class DataProductMapper { throw new RuntimeException(e); } } + + userInfoMapper.mapEntityToModel(dataProductEntity.getOwner(), dataProductBuilder.getOwnerBuilder()); } } diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/mapper/UserInfoMapper.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/mapper/UserInfoMapper.java new file mode 100644 index 0000000..e968cbf --- /dev/null +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/mapper/UserInfoMapper.java @@ -0,0 +1,22 @@ +package org.apache.airavata.datacatalog.api.mapper; + +import org.apache.airavata.datacatalog.api.UserInfo; +import org.apache.airavata.datacatalog.api.model.UserEntity; +import org.springframework.stereotype.Component; + +/** + * Map from {@link org.apache.airavata.datacatalog.api.model.UserEntity} to + * {@link org.apache.airavata.datacatalog.api.UserInfo}. For the reverse, see + * {@link org.apache.airavata.datacatalog.api.sharing.SharingManager#resolveUser(UserInfo)} + */ +@Component +public class UserInfoMapper { + + public void mapEntityToModel(UserEntity userEntity, UserInfo.Builder userInfoBuilder) { + + userInfoBuilder + .setUserId(userEntity.getExternalId()) + .setTenantId(userEntity.getTenant().getExternalId()); + + } +} diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java index 5e3802f..b33e86f 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java @@ -52,7 +52,10 @@ public class DataProductEntity { @JoinTable(name = "data_product_metadata_schema", joinColumns = @JoinColumn(name = "data_product_id"), inverseJoinColumns = @JoinColumn(name = "metadata_schema_id")) private Set<MetadataSchemaEntity> metadataSchemas = new HashSet<>(); - // TODO: ManyToOne mapping to owner: UserEntity + @ManyToOne(optional = false) + @JoinColumn(name = "owner_id", referencedColumnName = "user_id", nullable = false, updatable = false) + private UserEntity owner; + public Long getDataProductId() { return dataProductId; } @@ -109,6 +112,14 @@ public class DataProductEntity { this.metadataSchemas.remove(metadataSchema); } + public UserEntity getOwner() { + return owner; + } + + public void setOwner(UserEntity owner) { + this.owner = owner; + } + @Override public int hashCode() { final int prime = 31; diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/UserEntity.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/UserEntity.java index cdc24f1..20a4a3c 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/UserEntity.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/UserEntity.java @@ -6,6 +6,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; @@ -32,6 +34,10 @@ public class UserEntity { @Column(name = "name", nullable = false) private String name; + @ManyToOne(optional = false) + @JoinColumn(name = "tenant_id", referencedColumnName = "tenant_id", nullable = false, updatable = false) + private TenantEntity tenant; + public Long getUserId() { return userId; } @@ -56,6 +62,14 @@ public class UserEntity { this.name = name; } + public TenantEntity getTenant() { + return tenant; + } + + public void setTenant(TenantEntity tenant) { + this.tenant = tenant; + } + @Override public int hashCode() { final int prime = 31; diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java index efadaf5..92c02a7 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java @@ -39,6 +39,7 @@ import org.apache.airavata.datacatalog.api.MetadataSchemaGetResponse; import org.apache.airavata.datacatalog.api.exception.EntityNotFoundException; import org.apache.airavata.datacatalog.api.exception.MetadataSchemaSqlParseException; import org.apache.airavata.datacatalog.api.exception.MetadataSchemaSqlValidateException; +import org.apache.airavata.datacatalog.api.exception.SharingException; import org.apache.airavata.datacatalog.api.query.MetadataSchemaQueryResult; import org.lognet.springboot.grpc.GRpcService; import org.slf4j.Logger; @@ -62,10 +63,20 @@ public class DataCatalogAPIService extends DataCatalogAPIServiceGrpc.DataCatalog logger.info("Creating data product {}", request.getDataProduct()); - DataProduct result = dataCatalogService.createDataProduct(request.getDataProduct()); + // Set the owner as the requesting user + DataProduct dataProduct = request.getDataProduct().toBuilder().setOwner(request.getUserInfo()).build(); + + DataProduct result; + try { + result = dataCatalogService.createDataProduct(dataProduct); + responseObserver.onNext(DataProductCreateResponse.newBuilder().setDataProduct(result).build()); + responseObserver.onCompleted(); + } catch (SharingException e) { + logger.error("Sharing error when trying to create data product", e); + responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).asException()); + responseObserver.onCompleted(); + } - responseObserver.onNext(DataProductCreateResponse.newBuilder().setDataProduct(result).build()); - responseObserver.onCompleted(); } @Override diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogService.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogService.java index 0b6220d..be6ff66 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogService.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogService.java @@ -7,6 +7,7 @@ import org.apache.airavata.datacatalog.api.MetadataSchema; import org.apache.airavata.datacatalog.api.MetadataSchemaField; import org.apache.airavata.datacatalog.api.exception.MetadataSchemaSqlParseException; import org.apache.airavata.datacatalog.api.exception.MetadataSchemaSqlValidateException; +import org.apache.airavata.datacatalog.api.exception.SharingException; import org.apache.airavata.datacatalog.api.query.MetadataSchemaQueryResult; /** @@ -14,7 +15,7 @@ import org.apache.airavata.datacatalog.api.query.MetadataSchemaQueryResult; */ public interface DataCatalogService { - DataProduct createDataProduct(DataProduct dataProduct); + DataProduct createDataProduct(DataProduct dataProduct) throws SharingException; DataProduct updateDataProduct(DataProduct dataProduct); diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/impl/DataCatalogServiceImpl.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/impl/DataCatalogServiceImpl.java index 1f664a1..8ca0ddf 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/impl/DataCatalogServiceImpl.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/impl/DataCatalogServiceImpl.java @@ -8,21 +8,25 @@ import org.apache.airavata.datacatalog.api.DataProduct; import org.apache.airavata.datacatalog.api.MetadataSchema; import org.apache.airavata.datacatalog.api.MetadataSchemaField; import org.apache.airavata.datacatalog.api.MetadataSchemaFieldListResponse; +import org.apache.airavata.datacatalog.api.Permission; import org.apache.airavata.datacatalog.api.exception.EntityNotFoundException; import org.apache.airavata.datacatalog.api.exception.MetadataSchemaSqlParseException; import org.apache.airavata.datacatalog.api.exception.MetadataSchemaSqlValidateException; +import org.apache.airavata.datacatalog.api.exception.SharingException; import org.apache.airavata.datacatalog.api.mapper.DataProductMapper; import org.apache.airavata.datacatalog.api.mapper.MetadataSchemaFieldMapper; import org.apache.airavata.datacatalog.api.mapper.MetadataSchemaMapper; import org.apache.airavata.datacatalog.api.model.DataProductEntity; import org.apache.airavata.datacatalog.api.model.MetadataSchemaEntity; import org.apache.airavata.datacatalog.api.model.MetadataSchemaFieldEntity; +import org.apache.airavata.datacatalog.api.model.UserEntity; import org.apache.airavata.datacatalog.api.query.MetadataSchemaQueryExecutor; import org.apache.airavata.datacatalog.api.query.MetadataSchemaQueryResult; import org.apache.airavata.datacatalog.api.repository.DataProductRepository; import org.apache.airavata.datacatalog.api.repository.MetadataSchemaFieldRepository; import org.apache.airavata.datacatalog.api.repository.MetadataSchemaRepository; import org.apache.airavata.datacatalog.api.service.DataCatalogService; +import org.apache.airavata.datacatalog.api.sharing.SharingManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -54,17 +58,20 @@ public class DataCatalogServiceImpl implements DataCatalogService { @Autowired MetadataSchemaQueryExecutor metadataSchemaQueryExecutor; + @Autowired + SharingManager sharingManager; + @Override - public DataProduct createDataProduct(DataProduct dataProduct) { + public DataProduct createDataProduct(DataProduct dataProduct) throws SharingException { - // TODO: SharingManager.resolveUser + UserEntity owner = sharingManager.resolveUser(dataProduct.getOwner()); DataProductEntity dataProductEntity = new DataProductEntity(); dataProductEntity.setExternalId(UUID.randomUUID().toString()); + dataProductEntity.setOwner(owner); dataProductMapper.mapModelToEntity(dataProduct, dataProductEntity); DataProductEntity savedDataProductEntity = dataProductRepository.save(dataProductEntity); - // TODO: SharingManager.grantPermissionToUser(userInfo, dataProduct, - // Permission.OWNER) + sharingManager.grantPermissionToUser(dataProduct.getOwner(), dataProduct, Permission.OWNER); return toDataProduct(savedDataProductEntity); } diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/sharing/SharingManagerImpl.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/sharing/SharingManagerImpl.java index 59cb17b..18e16c3 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/sharing/SharingManagerImpl.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/sharing/SharingManagerImpl.java @@ -12,6 +12,7 @@ import org.apache.airavata.datacatalog.api.exception.SharingException; import org.apache.airavata.datacatalog.api.model.TenantEntity; import org.apache.airavata.datacatalog.api.model.UserEntity; import org.apache.airavata.datacatalog.api.repository.TenantRepository; +import org.apache.custos.sharing.core.Entity; import org.apache.custos.sharing.core.EntityType; import org.apache.custos.sharing.core.PermissionType; import org.apache.custos.sharing.core.exceptions.CustosSharingException; @@ -116,8 +117,13 @@ public class SharingManagerImpl implements SharingManager { List<String> userIds = new ArrayList<>(); userIds.add(userInfo.getUserId()); try { - custosSharingImpl.shareEntity(userInfo.getTenantId(), - dataProduct.getDataProductId(), permission.name(), userIds, true, Constants.USER, null); + createDataProductEntityIfMissing(dataProduct); + // OWNER permission can't be assigned but it is granted when the data product is + // created + if (permission != Permission.OWNER) { + custosSharingImpl.shareEntity(userInfo.getTenantId(), + dataProduct.getDataProductId(), permission.name(), userIds, true, Constants.USER, null); + } } catch (CustosSharingException e) { throw new SharingException(e); } @@ -168,7 +174,7 @@ public class SharingManagerImpl implements SharingManager { @Override public boolean hasPublicAccess(DataProduct dataProduct, Permission permission) throws SharingException { try { - return custosSharingImpl.userHasAccess(dataProduct.getTenantId(), dataProduct.getDataProductId(), + return custosSharingImpl.userHasAccess(dataProduct.getOwner().getTenantId(), dataProduct.getDataProductId(), permission.name(), PUBLIC_ACCESS_GROUP); } catch (CustosSharingException e) { @@ -183,7 +189,7 @@ public class SharingManagerImpl implements SharingManager { List<String> userIds = new ArrayList<>(); userIds.add(PUBLIC_ACCESS_GROUP); try { - custosSharingImpl.shareEntity(dataProduct.getTenantId(), + custosSharingImpl.shareEntity(dataProduct.getOwner().getTenantId(), dataProduct.getDataProductId(), permission.name(), userIds, true, Constants.GROUP, null); } catch (CustosSharingException e) { throw new SharingException(e); @@ -196,10 +202,27 @@ public class SharingManagerImpl implements SharingManager { List<String> userIds = new ArrayList<>(); userIds.add(PUBLIC_ACCESS_GROUP); try { - custosSharingImpl.revokePermission(dataProduct.getTenantId(), + custosSharingImpl.revokePermission(dataProduct.getOwner().getTenantId(), dataProduct.getDataProductId(), permission.name(), userIds); } catch (CustosSharingException e) { throw new SharingException(e); } } + + private void createDataProductEntityIfMissing(DataProduct dataProduct) throws CustosSharingException { + + Entity dataProductEntity = Entity.newBuilder() + .setId(dataProduct.getDataProductId()) + .setParentId(dataProduct.getParentDataProductId()) + .setName(dataProduct.getName()) + .setType(DATA_PRODUCT_ENTITY_TYPE_ID) + .setOwnerId(dataProduct.getOwner().getUserId()) + .build(); + + String tenantId = dataProduct.getOwner().getTenantId(); + if (!custosSharingImpl.isEntityExists(tenantId, dataProduct.getDataProductId())) { + custosSharingImpl.createEntity(dataProductEntity, tenantId); + } + } + } diff --git a/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto b/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto index a32a714..4c0c2d2 100644 --- a/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto +++ b/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto @@ -63,7 +63,7 @@ message DataProduct { string name = 3; optional string metadata = 4; repeated string metadata_schemas = 5; - string tenant_id = 6; + UserInfo owner = 6; } enum FieldValueType { @@ -84,25 +84,29 @@ message MetadataSchemaField { } message DataProductCreateRequest { - DataProduct data_product = 1; + UserInfo user_info = 1; + DataProduct data_product = 2; } message DataProductCreateResponse { DataProduct data_product = 1; } message DataProductUpdateRequest { - DataProduct data_product = 1; + UserInfo user_info = 1; + DataProduct data_product = 2; } message DataProductUpdateResponse { DataProduct data_product = 1; } message DataProductGetRequest { - string data_product_id = 1; + UserInfo user_info = 1; + string data_product_id = 2; } message DataProductGetResponse { DataProduct data_product = 1; } message DataProductDeleteRequest { - string data_product_id = 1; + UserInfo user_info = 1; + string data_product_id = 2; } message DataProductDeleteResponse { }
