mirror of
				https://github.com/open-metadata/OpenMetadata.git
				synced 2025-11-03 20:19:31 +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> (cherry picked from commit 788dfc331f0dae238c0c27a226e6208cc5031b17)
This commit is contained in:
		
							parent
							
								
									25b0fb39e9
								
							
						
					
					
						commit
						12a9da0864
					
				@ -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