mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-27 07:28:30 +00:00
Issue-19197: Deleting Data Product should delete the data asset relationships (#19208)
* Issue-19197: Deleting Data Product should delete the data asset relationships * Issue-19197: Deleting Data Product should delete the data asset relationships * Minor: Fix the deleteByName * add tests for data product delete case * fix flaky tests * update data products fqn keyword mapping * Update table_index_mapping.json * fix flaky test * fix tests * fix flaky tests * fix flakiness --------- Co-authored-by: karanh37 <karanh37@gmail.com> Co-authored-by: Karan Hotchandani <33024356+karanh37@users.noreply.github.com>
This commit is contained in:
parent
8fdaea805f
commit
490ebdebc3
@ -1154,6 +1154,7 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
String updatedBy, UUID id, boolean recursive, boolean hardDelete) {
|
||||
DeleteResponse<T> response = deleteInternal(updatedBy, id, recursive, hardDelete);
|
||||
postDelete(response.entity());
|
||||
deleteFromSearch(response.entity(), hardDelete);
|
||||
return response;
|
||||
}
|
||||
|
||||
@ -1178,6 +1179,7 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
name = quoteFqn ? quoteName(name) : name;
|
||||
DeleteResponse<T> response = deleteInternalByName(updatedBy, name, recursive, hardDelete);
|
||||
postDelete(response.entity());
|
||||
deleteFromSearch(response.entity(), hardDelete);
|
||||
return response;
|
||||
}
|
||||
|
||||
@ -1188,12 +1190,12 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
|
||||
protected void postDelete(T entity) {}
|
||||
|
||||
public final void deleteFromSearch(T entity, EventType changeType) {
|
||||
public final void deleteFromSearch(T entity, boolean hardDelete) {
|
||||
if (supportsSearch) {
|
||||
if (changeType.equals(ENTITY_SOFT_DELETED)) {
|
||||
searchRepository.softDeleteOrRestoreEntity(entity, true);
|
||||
} else {
|
||||
if (hardDelete) {
|
||||
searchRepository.deleteEntity(entity);
|
||||
} else {
|
||||
searchRepository.softDeleteOrRestoreEntity(entity, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,7 +361,6 @@ public abstract class EntityResource<T extends EntityInterface, K extends Entity
|
||||
authorizer.authorize(securityContext, operationContext, getResourceContextById(id));
|
||||
DeleteResponse<T> response =
|
||||
repository.delete(securityContext.getUserPrincipal().getName(), id, recursive, hardDelete);
|
||||
repository.deleteFromSearch(response.entity(), response.changeType());
|
||||
if (hardDelete) {
|
||||
limits.invalidateCache(entityType);
|
||||
}
|
||||
@ -380,7 +379,6 @@ public abstract class EntityResource<T extends EntityInterface, K extends Entity
|
||||
DeleteResponse<T> response =
|
||||
repository.deleteByName(
|
||||
securityContext.getUserPrincipal().getName(), name, recursive, hardDelete);
|
||||
repository.deleteFromSearch(response.entity(), response.changeType());
|
||||
addHref(uriInfo, response.entity());
|
||||
return response.toResponse();
|
||||
}
|
||||
|
||||
@ -762,7 +762,7 @@ public class TestSuiteResource extends EntityResource<TestSuite, TestSuiteReposi
|
||||
}
|
||||
RestUtil.DeleteResponse<TestSuite> response =
|
||||
repository.deleteLogicalTestSuite(securityContext, testSuite, hardDelete);
|
||||
repository.deleteFromSearch(response.entity(), response.changeType());
|
||||
repository.deleteFromSearch(response.entity(), hardDelete);
|
||||
addHref(uriInfo, response.entity());
|
||||
return response.toResponse();
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ public interface SearchClient {
|
||||
|
||||
String DELETE = "delete";
|
||||
String GLOBAL_SEARCH_ALIAS = "all";
|
||||
String DATA_ASSET_SEARCH_ALIAS = "dataAsset";
|
||||
String GLOSSARY_TERM_SEARCH_INDEX = "glossary_term_search_index";
|
||||
String TAG_SEARCH_INDEX = "tag_search_index";
|
||||
String DEFAULT_UPDATE_SCRIPT = "for (k in params.keySet()) { ctx._source.put(k, params.get(k)) }";
|
||||
@ -74,6 +75,8 @@ public interface SearchClient {
|
||||
String REMOVE_TAGS_CHILDREN_SCRIPT =
|
||||
"for (int i = 0; i < ctx._source.tags.length; i++) { if (ctx._source.tags[i].tagFQN == params.fqn) { ctx._source.tags.remove(i) }}";
|
||||
|
||||
String REMOVE_DATA_PRODUCTS_CHILDREN_SCRIPT =
|
||||
"for (int i = 0; i < ctx._source.dataProducts.length; i++) { if (ctx._source.dataProducts[i].fullyQualifiedName == params.fqn) { ctx._source.dataProducts.remove(i) }}";
|
||||
String UPDATE_CERTIFICATION_SCRIPT =
|
||||
"if (ctx._source.certification != null && ctx._source.certification.tagLabel != null) {ctx._source.certification.tagLabel.style = params.style; ctx._source.certification.tagLabel.description = params.description; ctx._source.certification.tagLabel.tagFQN = params.tagFQN; ctx._source.certification.tagLabel.name = params.name; }";
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import static org.openmetadata.service.search.SearchClient.GLOBAL_SEARCH_ALIAS;
|
||||
import static org.openmetadata.service.search.SearchClient.PROPAGATE_ENTITY_REFERENCE_FIELD_SCRIPT;
|
||||
import static org.openmetadata.service.search.SearchClient.PROPAGATE_FIELD_SCRIPT;
|
||||
import static org.openmetadata.service.search.SearchClient.PROPAGATE_TEST_SUITES_SCRIPT;
|
||||
import static org.openmetadata.service.search.SearchClient.REMOVE_DATA_PRODUCTS_CHILDREN_SCRIPT;
|
||||
import static org.openmetadata.service.search.SearchClient.REMOVE_DOMAINS_CHILDREN_SCRIPT;
|
||||
import static org.openmetadata.service.search.SearchClient.REMOVE_OWNERS_SCRIPT;
|
||||
import static org.openmetadata.service.search.SearchClient.REMOVE_PROPAGATED_ENTITY_REFERENCE_FIELD_SCRIPT;
|
||||
@ -727,6 +728,13 @@ public class SearchRepository {
|
||||
indexMapping.getChildAliases(clusterAlias),
|
||||
List.of(new ImmutablePair<>(entityType + ".id", docId)));
|
||||
}
|
||||
case Entity.DATA_PRODUCT -> searchClient.updateChildren(
|
||||
GLOBAL_SEARCH_ALIAS,
|
||||
new ImmutablePair<>("dataProducts.id", docId),
|
||||
new ImmutablePair<>(
|
||||
REMOVE_DATA_PRODUCTS_CHILDREN_SCRIPT,
|
||||
Collections.singletonMap("fqn", entity.getFullyQualifiedName())));
|
||||
|
||||
case Entity.TAG, Entity.GLOSSARY_TERM -> searchClient.updateChildren(
|
||||
GLOBAL_SEARCH_ALIAS,
|
||||
new ImmutablePair<>("tags.tagFQN", entity.getFullyQualifiedName()),
|
||||
|
||||
@ -2212,7 +2212,7 @@ public class ElasticSearchClient implements SearchClient {
|
||||
private void updateElasticSearchByQuery(UpdateByQueryRequest updateByQueryRequest) {
|
||||
if (updateByQueryRequest != null && isClientAvailable) {
|
||||
updateByQueryRequest.setRefresh(true);
|
||||
LOG.debug(SENDING_REQUEST_TO_ELASTIC_SEARCH, updateByQueryRequest);
|
||||
LOG.info(SENDING_REQUEST_TO_ELASTIC_SEARCH, updateByQueryRequest);
|
||||
client.updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -236,7 +236,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -323,7 +323,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -245,7 +245,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -129,7 +129,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -301,7 +301,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -243,7 +243,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -152,7 +152,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -129,7 +129,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -243,7 +243,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -145,7 +145,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -128,7 +128,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -242,7 +242,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -438,7 +438,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -239,7 +239,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -139,7 +139,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -451,7 +451,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -192,7 +192,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -201,7 +201,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -348,7 +348,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -180,7 +180,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -130,7 +130,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -182,7 +182,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -234,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -201,7 +201,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -128,7 +128,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -239,7 +239,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -137,7 +137,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -116,7 +116,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -234,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -435,7 +435,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -231,7 +231,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -131,7 +131,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -446,7 +446,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -362,7 +362,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -140,7 +140,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -226,7 +226,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -344,7 +344,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -230,7 +230,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -117,7 +117,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -236,7 +236,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -224,7 +224,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -140,7 +140,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -117,7 +117,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -226,7 +226,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -131,7 +131,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -117,7 +117,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -224,7 +224,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -426,7 +426,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -221,7 +221,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -127,7 +127,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -442,7 +442,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -180,7 +180,7 @@
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
|
||||
@ -114,13 +114,13 @@ test.describe('Ingestion Bot ', () => {
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDomain(page, domain1.data);
|
||||
await addAssetsToDomain(page, domain1.data, domainAsset1);
|
||||
await addAssetsToDomain(page, domain1, domainAsset1);
|
||||
|
||||
// Add assets to domain 2
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDomain(page, domain2.data);
|
||||
await addAssetsToDomain(page, domain2.data, domainAsset2);
|
||||
await addAssetsToDomain(page, domain2, domainAsset2);
|
||||
});
|
||||
|
||||
await test.step(
|
||||
|
||||
@ -34,6 +34,7 @@ import {
|
||||
selectDomain,
|
||||
selectSubDomain,
|
||||
setupAssetsForDomain,
|
||||
verifyDataProductAssetsAfterDelete,
|
||||
verifyDomain,
|
||||
} from '../../utils/domain';
|
||||
import { sidebarClick } from '../../utils/sidebar';
|
||||
@ -61,7 +62,7 @@ test.describe('Domains', () => {
|
||||
await test.step('Add assets to domain', async () => {
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await addAssetsToDomain(page, domain.data, assets);
|
||||
await addAssetsToDomain(page, domain, assets);
|
||||
});
|
||||
|
||||
await test.step('Delete domain using delete modal', async () => {
|
||||
@ -100,7 +101,7 @@ test.describe('Domains', () => {
|
||||
await domain.create(apiContext);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await page.reload();
|
||||
await addAssetsToDomain(page, domain.data, assets);
|
||||
await addAssetsToDomain(page, domain, assets);
|
||||
|
||||
await test.step('Create DataProducts', async () => {
|
||||
await selectDomain(page, domain.data);
|
||||
@ -115,7 +116,11 @@ test.describe('Domains', () => {
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDataProduct(page, domain.data, dataProduct1.data);
|
||||
await addAssetsToDataProduct(page, dataProduct1.data, assets);
|
||||
await addAssetsToDataProduct(
|
||||
page,
|
||||
dataProduct1.data.fullyQualifiedName ?? '',
|
||||
assets
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('Remove assets from DataProducts', async () => {
|
||||
@ -220,7 +225,7 @@ test.describe('Domains', () => {
|
||||
await domain.create(apiContext);
|
||||
await page.reload();
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await addAssetsToDomain(page, domain.data, assets);
|
||||
await addAssetsToDomain(page, domain, assets);
|
||||
await page.getByTestId('documentation').click();
|
||||
const updatedDomainName = 'PW Domain Updated';
|
||||
|
||||
@ -264,6 +269,71 @@ test.describe('Domains', () => {
|
||||
await domain.delete(apiContext);
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test('Should clear assets from data products after deletion of data product in Domain', async ({
|
||||
page,
|
||||
}) => {
|
||||
const { afterAction, apiContext } = await getApiContext(page);
|
||||
const { assets, assetCleanup } = await setupAssetsForDomain(page);
|
||||
const domain = new Domain({
|
||||
name: 'PW_Domain_Delete_Testing',
|
||||
displayName: 'PW_Domain_Delete_Testing',
|
||||
description: 'playwright domain description',
|
||||
domainType: 'Aggregate',
|
||||
fullyQualifiedName: 'PW_Domain_Delete_Testing',
|
||||
});
|
||||
const dataProduct1 = new DataProduct(domain, 'PW_DataProduct_Sales');
|
||||
const dataProduct2 = new DataProduct(domain, 'PW_DataProduct_Finance');
|
||||
|
||||
const domain1 = new Domain({
|
||||
name: 'PW_Domain_Delete_Testing',
|
||||
displayName: 'PW_Domain_Delete_Testing',
|
||||
description: 'playwright domain description',
|
||||
domainType: 'Aggregate',
|
||||
fullyQualifiedName: 'PW_Domain_Delete_Testing',
|
||||
});
|
||||
const newDomainDP1 = new DataProduct(domain1, 'PW_DataProduct_Sales');
|
||||
const newDomainDP2 = new DataProduct(domain1, 'PW_DataProduct_Finance');
|
||||
|
||||
try {
|
||||
await domain.create(apiContext);
|
||||
await dataProduct1.create(apiContext);
|
||||
await dataProduct2.create(apiContext);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await page.reload();
|
||||
await addAssetsToDomain(page, domain, assets);
|
||||
await verifyDataProductAssetsAfterDelete(page, {
|
||||
domain,
|
||||
dataProduct1,
|
||||
dataProduct2,
|
||||
assets,
|
||||
});
|
||||
|
||||
await test.step(
|
||||
'Delete domain & recreate the same domain and data product',
|
||||
async () => {
|
||||
await domain.delete(apiContext);
|
||||
await domain1.create(apiContext);
|
||||
await newDomainDP1.create(apiContext);
|
||||
await newDomainDP2.create(apiContext);
|
||||
await page.reload();
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDataProduct(page, domain1.data, newDomainDP1.data);
|
||||
await checkAssetsCount(page, 0);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDataProduct(page, domain1.data, newDomainDP2.data);
|
||||
await checkAssetsCount(page, 0);
|
||||
}
|
||||
);
|
||||
} finally {
|
||||
await newDomainDP1.delete(apiContext);
|
||||
await newDomainDP2.delete(apiContext);
|
||||
await domain1.delete(apiContext);
|
||||
await assetCleanup();
|
||||
await afterAction();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Domains Rbac', () => {
|
||||
@ -343,13 +413,13 @@ test.describe('Domains Rbac', () => {
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDomain(page, domain1.data);
|
||||
await addAssetsToDomain(page, domain1.data, domainAssset1);
|
||||
await addAssetsToDomain(page, domain1, domainAssset1);
|
||||
|
||||
// Add assets to domain 2
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await selectDomain(page, domain2.data);
|
||||
await addAssetsToDomain(page, domain2.data, domainAssset2);
|
||||
await addAssetsToDomain(page, domain2, domainAssset2);
|
||||
});
|
||||
|
||||
await test.step('User with access to multiple domains', async () => {
|
||||
|
||||
@ -15,6 +15,7 @@ import { uuid } from '../../utils/common';
|
||||
import { EntityTypeEndpoint } from '../entity/Entity.interface';
|
||||
import { EntityClass } from '../entity/EntityClass';
|
||||
import { Domain } from './Domain';
|
||||
import { SubDomain } from './SubDomain';
|
||||
|
||||
type UserTeamRef = {
|
||||
name: string;
|
||||
@ -45,9 +46,10 @@ export class DataProduct extends EntityClass {
|
||||
|
||||
responseData: ResponseDataType = {} as ResponseDataType;
|
||||
|
||||
constructor(domain: Domain, name?: string) {
|
||||
constructor(domain: Domain, name?: string, subDomain?: SubDomain) {
|
||||
super(EntityTypeEndpoint.DATA_PRODUCT);
|
||||
this.data.domain = domain.data.name;
|
||||
this.data.domain =
|
||||
domain.data.name + (subDomain ? `.${subDomain?.data.name}` : ''); // fqn
|
||||
this.data.name = name ?? this.data.name;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
this.data.fullyQualifiedName = `\"${this.data.name}\"`;
|
||||
|
||||
@ -10,8 +10,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { expect, Page } from '@playwright/test';
|
||||
import test, { expect, Page } from '@playwright/test';
|
||||
import { get, isEmpty, isUndefined } from 'lodash';
|
||||
import { SidebarItem } from '../constant/sidebar';
|
||||
import { DataProduct } from '../support/domain/DataProduct';
|
||||
import { Domain } from '../support/domain/Domain';
|
||||
import { SubDomain } from '../support/domain/SubDomain';
|
||||
@ -27,8 +28,10 @@ import {
|
||||
INVALID_NAMES,
|
||||
NAME_MAX_LENGTH_VALIDATION_ERROR,
|
||||
NAME_VALIDATION_ERROR,
|
||||
redirectToHomePage,
|
||||
} from './common';
|
||||
import { addOwner } from './entity';
|
||||
import { sidebarClick } from './sidebar';
|
||||
|
||||
export const assignDomain = async (page: Page, domain: Domain['data']) => {
|
||||
await page.getByTestId('add-domain').click();
|
||||
@ -113,13 +116,45 @@ export const selectSubDomain = async (
|
||||
domain: Domain['data'],
|
||||
subDomain: SubDomain['data']
|
||||
) => {
|
||||
await page
|
||||
.getByRole('menuitem', { name: domain.displayName })
|
||||
.locator('span')
|
||||
.click();
|
||||
const menuItem = page.getByRole('menuitem', { name: domain.displayName });
|
||||
const isSelected = await menuItem.evaluate((element) => {
|
||||
return element.classList.contains('ant-menu-item-selected');
|
||||
});
|
||||
|
||||
if (!isSelected) {
|
||||
const subDomainRes = page.waitForResponse(
|
||||
'/api/v1/search/query?*&from=0&size=50&index=domain_search_index'
|
||||
);
|
||||
await menuItem.click();
|
||||
await subDomainRes;
|
||||
}
|
||||
|
||||
await page.getByTestId('subdomains').getByText('Sub Domains').click();
|
||||
const res = page.waitForResponse(
|
||||
'/api/v1/search/query?*&index=data_product_search_index'
|
||||
);
|
||||
await page.getByTestId(subDomain.name).click();
|
||||
await res;
|
||||
};
|
||||
|
||||
export const selectDataProductFromTab = async (
|
||||
page: Page,
|
||||
dataProduct: DataProduct['data']
|
||||
) => {
|
||||
const dpRes = page.waitForResponse(
|
||||
'/api/v1/search/query?*&from=0&size=50&index=data_product_search_index'
|
||||
);
|
||||
await page.getByText('Data Products').click();
|
||||
|
||||
await dpRes;
|
||||
|
||||
const dpDataRes = page.waitForResponse('/api/v1/dataProducts/name/*');
|
||||
|
||||
await page
|
||||
.getByTestId(`explore-card-${dataProduct.name}`)
|
||||
.getByTestId('entity-link')
|
||||
.click();
|
||||
await dpDataRes;
|
||||
};
|
||||
|
||||
export const selectDataProduct = async (
|
||||
@ -132,11 +167,7 @@ export const selectDataProduct = async (
|
||||
.locator('span')
|
||||
.click();
|
||||
|
||||
await page.getByText('Data Products').click();
|
||||
await page
|
||||
.getByTestId(`explore-card-${dataProduct.name}`)
|
||||
.getByTestId('entity-link')
|
||||
.click();
|
||||
await selectDataProductFromTab(page, dataProduct);
|
||||
};
|
||||
|
||||
const goToAssetsTab = async (page: Page, domain: Domain['data']) => {
|
||||
@ -280,10 +311,13 @@ export const createSubDomain = async (
|
||||
|
||||
export const addAssetsToDomain = async (
|
||||
page: Page,
|
||||
domain: Domain['data'],
|
||||
assets: EntityClass[]
|
||||
domain: Domain,
|
||||
assets: EntityClass[],
|
||||
navigateToAssetsTab = true
|
||||
) => {
|
||||
await goToAssetsTab(page, domain);
|
||||
if (navigateToAssetsTab) {
|
||||
await goToAssetsTab(page, domain.data);
|
||||
}
|
||||
await checkAssetsCount(page, 0);
|
||||
|
||||
await expect(page.getByTestId('no-data-placeholder')).toContainText(
|
||||
@ -309,14 +343,16 @@ export const addAssetsToDomain = async (
|
||||
await page.locator(`[data-testid="table-data-card_${fqn}"] input`).check();
|
||||
}
|
||||
|
||||
const assetsAddRes = page.waitForResponse(
|
||||
`/api/v1/domains/${encodeURIComponent(
|
||||
domain.fullyQualifiedName ?? ''
|
||||
)}/assets/add`
|
||||
);
|
||||
const assetsAddRes = page.waitForResponse(`/api/v1/domains/*/assets/add`);
|
||||
await page.getByTestId('save-btn').click();
|
||||
await assetsAddRes;
|
||||
|
||||
const countRes = page.waitForResponse(
|
||||
'/api/v1/search/query?q=*&index=all&from=0&size=15'
|
||||
);
|
||||
await page.reload();
|
||||
await countRes;
|
||||
|
||||
await checkAssetsCount(page, assets.length);
|
||||
};
|
||||
|
||||
@ -357,7 +393,7 @@ export const addServicesToDomain = async (
|
||||
|
||||
export const addAssetsToDataProduct = async (
|
||||
page: Page,
|
||||
dataProduct: DataProduct['data'],
|
||||
dataProductFqn: string,
|
||||
assets: EntityClass[]
|
||||
) => {
|
||||
await page.getByTestId('assets').click();
|
||||
@ -383,9 +419,7 @@ export const addAssetsToDataProduct = async (
|
||||
}
|
||||
|
||||
const assetsAddRes = page.waitForResponse(
|
||||
`/api/v1/dataProducts/${encodeURIComponent(
|
||||
dataProduct.fullyQualifiedName ?? ''
|
||||
)}/assets/add`
|
||||
`/api/v1/dataProducts/*/assets/add`
|
||||
);
|
||||
await page.getByTestId('save-btn').click();
|
||||
await assetsAddRes;
|
||||
@ -458,3 +492,89 @@ export const createDataProduct = async (
|
||||
await page.getByTestId('save-data-product').click();
|
||||
await saveRes;
|
||||
};
|
||||
|
||||
export const verifyDataProductAssetsAfterDelete = async (
|
||||
page: Page,
|
||||
{
|
||||
domain,
|
||||
dataProduct1,
|
||||
dataProduct2,
|
||||
assets,
|
||||
subDomain,
|
||||
}: {
|
||||
domain: Domain;
|
||||
dataProduct1: DataProduct;
|
||||
dataProduct2: DataProduct;
|
||||
assets: EntityClass[];
|
||||
subDomain?: SubDomain;
|
||||
}
|
||||
) => {
|
||||
const { apiContext } = await getApiContext(page);
|
||||
const newDataProduct1 = new DataProduct(domain, 'PW_DataProduct_Sales');
|
||||
|
||||
await test.step('Add assets to DataProduct Sales', async () => {
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
if (subDomain) {
|
||||
await selectSubDomain(page, domain.data, subDomain.data);
|
||||
await selectDataProductFromTab(page, dataProduct1.data);
|
||||
} else {
|
||||
await selectDataProduct(page, domain.data, dataProduct1.data);
|
||||
}
|
||||
await addAssetsToDataProduct(
|
||||
page,
|
||||
dataProduct1.responseData.fullyQualifiedName ?? '',
|
||||
assets.slice(0, 2)
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('Add assets to DataProduct Finance', async () => {
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
if (subDomain) {
|
||||
await selectSubDomain(page, domain.data, subDomain.data);
|
||||
await selectDataProductFromTab(page, dataProduct2.data);
|
||||
} else {
|
||||
await selectDataProduct(page, domain.data, dataProduct2.data);
|
||||
}
|
||||
await addAssetsToDataProduct(
|
||||
page,
|
||||
dataProduct2.responseData.fullyQualifiedName ?? '',
|
||||
[assets[2]]
|
||||
);
|
||||
});
|
||||
|
||||
await test.step(
|
||||
'Remove Data Product Sales and Create the same again',
|
||||
async () => {
|
||||
// Remove sales data product
|
||||
await dataProduct1.delete(apiContext);
|
||||
|
||||
// Create sales data product again
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
if (subDomain) {
|
||||
await selectSubDomain(page, domain.data, subDomain.data);
|
||||
} else {
|
||||
await selectDomain(page, domain.data);
|
||||
}
|
||||
|
||||
await createDataProduct(page, newDataProduct1.data);
|
||||
}
|
||||
);
|
||||
|
||||
await test.step(
|
||||
'Verify assets are not present in the newly created data product',
|
||||
async () => {
|
||||
await redirectToHomePage(page);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
if (subDomain) {
|
||||
await selectSubDomain(page, domain.data, subDomain.data);
|
||||
await selectDataProductFromTab(page, newDataProduct1.data);
|
||||
} else {
|
||||
await selectDataProduct(page, domain.data, newDataProduct1.data);
|
||||
}
|
||||
await checkAssetsCount(page, 0);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user