Skip to content

Commit

Permalink
dataProduct : get inherited fields from corresponding Domain (#19343)
Browse files Browse the repository at this point in the history
* dataProduct : get inherited fields from corresponding Domain

* add tests

---------

Co-authored-by: karanh37 <[email protected]>
  • Loading branch information
sonika-shah and karanh37 authored Jan 14, 2025
1 parent 94cbadb commit 788dfc3
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -26,6 +28,7 @@
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;
Expand Down Expand Up @@ -93,6 +96,22 @@ public void storeRelationships(DataProduct entity) {
}
}

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
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;
Expand Down Expand Up @@ -177,6 +179,74 @@ void testValidateDataProducts() {
.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 {
Expand All @@ -200,6 +270,15 @@ public CreateDataProduct createRequest(String name) {
.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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ public CreateDomain createRequest(String name) {
.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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { uuid } from '../../utils/common';
type UserTeamRef = {
name: string;
type: string;
fullyQualifiedName?: string;
id?: string;
};

type ResponseDataType = {
Expand All @@ -26,7 +28,7 @@ type ResponseDataType = {
id?: string;
fullyQualifiedName?: string;
owners?: UserTeamRef[];
experts?: UserTeamRef[];
experts?: string[];
};

export class Domain {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { Domain } from './Domain';
type UserTeamRef = {
name: string;
type: string;
fullyQualifiedName?: string;
id?: string;
};

type ResponseDataType = {
Expand All @@ -27,7 +29,7 @@ type ResponseDataType = {
id?: string;
fullyQualifiedName?: string;
owners?: UserTeamRef[];
experts?: UserTeamRef[];
experts?: string[];
parent?: string;
};

Expand Down

0 comments on commit 788dfc3

Please sign in to comment.