Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dataProduct : get inherited fields from corresponding Domain #19343

Merged
merged 3 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading