mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-07 16:11:30 +00:00
dataProduct : get inherited fields from corresponding Domain (#19343)
* dataProduct : get inherited fields from corresponding Domain * add tests --------- Co-authored-by: karanh37 <karanh37@gmail.com>
This commit is contained in:
parent
94cbadb772
commit
788dfc331f
@ -14,7 +14,9 @@
|
||||
package org.openmetadata.service.jdbi3;
|
||||
|
||||
import static org.openmetadata.common.utils.CommonUtil.listOrEmpty;
|
||||
import static org.openmetadata.schema.type.Include.ALL;
|
||||
import static org.openmetadata.service.Entity.DATA_PRODUCT;
|
||||
import static org.openmetadata.service.Entity.DOMAIN;
|
||||
import static org.openmetadata.service.Entity.FIELD_ASSETS;
|
||||
import static org.openmetadata.service.util.EntityUtil.entityReferenceMatch;
|
||||
|
||||
@ -26,6 +28,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.jdbi.v3.sqlobject.transaction.Transaction;
|
||||
import org.openmetadata.schema.EntityInterface;
|
||||
import org.openmetadata.schema.entity.domains.DataProduct;
|
||||
import org.openmetadata.schema.entity.domains.Domain;
|
||||
import org.openmetadata.schema.type.EntityReference;
|
||||
import org.openmetadata.schema.type.Include;
|
||||
import org.openmetadata.schema.type.Relationship;
|
||||
@ -93,6 +96,22 @@ public class DataProductRepository extends EntityRepository<DataProduct> {
|
||||
}
|
||||
}
|
||||
|
||||
public final EntityReference getDomain(Domain domain) {
|
||||
return getFromEntityRef(domain.getId(), Relationship.CONTAINS, DOMAIN, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInheritedFields(DataProduct dataProduct, Fields fields) {
|
||||
// If dataProduct does not have owners and experts, inherit them from its domain
|
||||
EntityReference parentRef =
|
||||
dataProduct.getDomain() != null ? dataProduct.getDomain() : getDomain(dataProduct);
|
||||
if (parentRef != null) {
|
||||
Domain parent = Entity.getEntity(DOMAIN, parentRef.getId(), "owners,experts", ALL);
|
||||
inheritOwners(dataProduct, fields, parent);
|
||||
inheritExperts(dataProduct, fields, parent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityUpdater getUpdater(DataProduct original, DataProduct updated, Operation operation) {
|
||||
return new DataProductUpdater(original, updated, operation);
|
||||
|
@ -23,8 +23,10 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
import org.openmetadata.schema.EntityInterface;
|
||||
import org.openmetadata.schema.api.domains.CreateDataProduct;
|
||||
import org.openmetadata.schema.api.domains.CreateDomain;
|
||||
import org.openmetadata.schema.entity.data.Topic;
|
||||
import org.openmetadata.schema.entity.domains.DataProduct;
|
||||
import org.openmetadata.schema.entity.domains.Domain;
|
||||
import org.openmetadata.schema.entity.type.Style;
|
||||
import org.openmetadata.schema.type.ChangeDescription;
|
||||
import org.openmetadata.schema.type.EntityReference;
|
||||
@ -177,6 +179,74 @@ public class DataProductResourceTest extends EntityResourceTest<DataProduct, Cre
|
||||
.hasMessage(String.format("dataProduct instance for %s not found", rdnUUID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_inheritOwnerExpertsFromDomain(TestInfo test) throws IOException {
|
||||
DomainResourceTest domainResourceTest = new DomainResourceTest();
|
||||
|
||||
// Create parent domain
|
||||
CreateDomain parentDomainReq =
|
||||
domainResourceTest
|
||||
.createRequest(test, 1)
|
||||
.withOwners(List.of(USER1_REF))
|
||||
.withExperts(List.of(USER2.getFullyQualifiedName()));
|
||||
Domain parentDomain = domainResourceTest.createEntity(parentDomainReq, ADMIN_AUTH_HEADERS);
|
||||
parentDomain = domainResourceTest.getEntity(parentDomain.getId(), "*", ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Create data product corresponding to parent domain
|
||||
CreateDataProduct create =
|
||||
createRequestWithoutExpertsOwners(getEntityName(test, 1))
|
||||
.withDomain(parentDomain.getFullyQualifiedName());
|
||||
DataProduct dataProduct = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
|
||||
assertOwners(dataProduct.getOwners(), parentDomain.getOwners());
|
||||
assertEntityReferences(dataProduct.getExperts(), parentDomain.getExperts());
|
||||
|
||||
// Create subdomain with no owners and experts
|
||||
CreateDomain subDomainReq =
|
||||
domainResourceTest
|
||||
.createRequestWithoutOwnersExperts(getEntityName(test, 2))
|
||||
.withDomain(parentDomain.getFullyQualifiedName());
|
||||
Domain subDomain = domainResourceTest.createEntity(subDomainReq, ADMIN_AUTH_HEADERS);
|
||||
subDomain = domainResourceTest.getEntity(subDomain.getId(), "*", ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Create data product corresponding to subdomain
|
||||
CreateDataProduct subDomainDataProductCreate =
|
||||
createRequestWithoutExpertsOwners(getEntityName(test, 2))
|
||||
.withDomain(subDomain.getFullyQualifiedName());
|
||||
DataProduct subDomainDataProduct =
|
||||
createAndCheckEntity(subDomainDataProductCreate, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Subdomain and its data product should inherit owners and experts from parent domain
|
||||
assertOwners(subDomain.getOwners(), parentDomain.getOwners());
|
||||
assertEntityReferences(subDomain.getExperts(), parentDomain.getExperts());
|
||||
assertOwners(subDomainDataProduct.getOwners(), parentDomain.getOwners());
|
||||
assertEntityReferences(subDomainDataProduct.getExperts(), parentDomain.getExperts());
|
||||
|
||||
// Add owner and expert to subdomain
|
||||
Domain updateSubDomainOwner =
|
||||
JsonUtils.readValue(JsonUtils.pojoToJson(subDomain), Domain.class);
|
||||
updateSubDomainOwner.setOwners(List.of(TEAM11_REF));
|
||||
domainResourceTest.patchEntity(
|
||||
subDomain.getId(),
|
||||
JsonUtils.pojoToJson(subDomain),
|
||||
updateSubDomainOwner,
|
||||
ADMIN_AUTH_HEADERS);
|
||||
subDomain = domainResourceTest.getEntity(subDomain.getId(), "*", ADMIN_AUTH_HEADERS);
|
||||
|
||||
Domain updateSubDomainExpert =
|
||||
JsonUtils.readValue(JsonUtils.pojoToJson(subDomain), Domain.class);
|
||||
updateSubDomainExpert.setExperts(List.of(USER1_REF));
|
||||
domainResourceTest.patchEntity(
|
||||
subDomain.getId(),
|
||||
JsonUtils.pojoToJson(subDomain),
|
||||
updateSubDomainExpert,
|
||||
ADMIN_AUTH_HEADERS);
|
||||
subDomain = domainResourceTest.getEntity(subDomain.getId(), "*", ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Data product of subdomain should also have the same changes as its corresponding domain
|
||||
assertOwners(subDomainDataProduct.getOwners(), subDomain.getOwners());
|
||||
assertEntityReferences(subDomainDataProduct.getExperts(), subDomain.getExperts());
|
||||
}
|
||||
|
||||
private void entityInDataProduct(
|
||||
EntityInterface entity, EntityInterface product, boolean inDataProduct)
|
||||
throws HttpResponseException {
|
||||
@ -200,6 +270,15 @@ public class DataProductResourceTest extends EntityResourceTest<DataProduct, Cre
|
||||
.withAssets(TEST_TABLE1 != null ? listOf(TEST_TABLE1.getEntityReference()) : null);
|
||||
}
|
||||
|
||||
public CreateDataProduct createRequestWithoutExpertsOwners(String name) {
|
||||
return new CreateDataProduct()
|
||||
.withName(name)
|
||||
.withDescription(name)
|
||||
.withDomain(DOMAIN.getFullyQualifiedName())
|
||||
.withStyle(new Style().withColor("#40E0D0").withIconURL("https://dataProductIcon"))
|
||||
.withAssets(TEST_TABLE1 != null ? listOf(TEST_TABLE1.getEntityReference()) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateCreatedEntity(
|
||||
DataProduct createdEntity, CreateDataProduct request, Map<String, String> authHeaders) {
|
||||
|
@ -153,6 +153,14 @@ public class DomainResourceTest extends EntityResourceTest<Domain, CreateDomain>
|
||||
.withExperts(listOf(USER1.getFullyQualifiedName()));
|
||||
}
|
||||
|
||||
public CreateDomain createRequestWithoutOwnersExperts(String name) {
|
||||
return new CreateDomain()
|
||||
.withName(name)
|
||||
.withDomainType(DomainType.AGGREGATE)
|
||||
.withDescription("name")
|
||||
.withStyle(new Style().withColor("#FFA07A").withIconURL("https://domainIcon"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateCreatedEntity(
|
||||
Domain createdEntity, CreateDomain request, Map<String, String> authHeaders) {
|
||||
|
@ -334,6 +334,61 @@ test.describe('Domains', () => {
|
||||
await afterAction();
|
||||
}
|
||||
});
|
||||
|
||||
test('Should inherit owners and experts from parent domain', async ({
|
||||
page,
|
||||
}) => {
|
||||
const { afterAction, apiContext } = await getApiContext(page);
|
||||
const user1 = new UserClass();
|
||||
const user2 = new UserClass();
|
||||
let domain;
|
||||
let dataProduct;
|
||||
try {
|
||||
await user1.create(apiContext);
|
||||
await user2.create(apiContext);
|
||||
|
||||
domain = new Domain({
|
||||
name: 'PW_Domain_Inherit_Testing',
|
||||
displayName: 'PW_Domain_Inherit_Testing',
|
||||
description: 'playwright domain description',
|
||||
domainType: 'Aggregate',
|
||||
fullyQualifiedName: 'PW_Domain_Inherit_Testing',
|
||||
owners: [
|
||||
{
|
||||
name: user1.responseData.name,
|
||||
type: 'user',
|
||||
fullyQualifiedName: user1.responseData.fullyQualifiedName ?? '',
|
||||
id: user1.responseData.id,
|
||||
},
|
||||
],
|
||||
experts: [user2.responseData.name],
|
||||
});
|
||||
dataProduct = new DataProduct(domain);
|
||||
await domain.create(apiContext);
|
||||
await dataProduct.create(apiContext);
|
||||
|
||||
await page.reload();
|
||||
await redirectToHomePage(page);
|
||||
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDomain(page, domain.data);
|
||||
await selectDataProduct(page, domain.data, dataProduct.data);
|
||||
|
||||
await expect(
|
||||
page.getByTestId('domain-owner-name').getByTestId('owner-label')
|
||||
).toContainText(user1.responseData.displayName);
|
||||
|
||||
await expect(
|
||||
page.getByTestId('domain-expert-name').getByTestId('owner-label')
|
||||
).toContainText(user2.responseData.displayName);
|
||||
} finally {
|
||||
await dataProduct?.delete(apiContext);
|
||||
await domain?.delete(apiContext);
|
||||
await user1.delete(apiContext);
|
||||
await user2.delete(apiContext);
|
||||
await afterAction();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Domains Rbac', () => {
|
||||
|
@ -16,6 +16,8 @@ import { uuid } from '../../utils/common';
|
||||
type UserTeamRef = {
|
||||
name: string;
|
||||
type: string;
|
||||
fullyQualifiedName?: string;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
type ResponseDataType = {
|
||||
@ -26,7 +28,7 @@ type ResponseDataType = {
|
||||
id?: string;
|
||||
fullyQualifiedName?: string;
|
||||
owners?: UserTeamRef[];
|
||||
experts?: UserTeamRef[];
|
||||
experts?: string[];
|
||||
};
|
||||
|
||||
export class Domain {
|
||||
|
@ -17,6 +17,8 @@ import { Domain } from './Domain';
|
||||
type UserTeamRef = {
|
||||
name: string;
|
||||
type: string;
|
||||
fullyQualifiedName?: string;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
type ResponseDataType = {
|
||||
@ -27,7 +29,7 @@ type ResponseDataType = {
|
||||
id?: string;
|
||||
fullyQualifiedName?: string;
|
||||
owners?: UserTeamRef[];
|
||||
experts?: UserTeamRef[];
|
||||
experts?: string[];
|
||||
parent?: string;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user