From 6caa81bfdc405540cb2452743450db16c224674a Mon Sep 17 00:00:00 2001 From: aarshi Date: Fri, 5 Jan 2024 20:34:23 +0530 Subject: [PATCH 1/4] Add classificationDetails --- .../atlas/model/audit/EntityAuditEventV2.java | 26 +++++++++++++++++-- .../apache/atlas/type/AtlasTypeRegistry.java | 4 +++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/intg/src/main/java/org/apache/atlas/model/audit/EntityAuditEventV2.java b/intg/src/main/java/org/apache/atlas/model/audit/EntityAuditEventV2.java index 065be47cfc..1947147e38 100644 --- a/intg/src/main/java/org/apache/atlas/model/audit/EntityAuditEventV2.java +++ b/intg/src/main/java/org/apache/atlas/model/audit/EntityAuditEventV2.java @@ -136,6 +136,9 @@ public static EntityAuditActionV2 fromString(String strValue) { private AtlasEntityHeader entityDetail; private Map headers; + private List> classificationDetails; + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + private String classificationDetail; public EntityAuditEventV2() { } @@ -291,12 +294,13 @@ public boolean equals(Object o) { Objects.equals(created, that.created) && Objects.equals(typeName, that.typeName) && Objects.equals(entityQualifiedName, that.entityQualifiedName) && - Objects.equals(headers, that.headers); + Objects.equals(headers, that.headers) && + Objects.equals(classificationDetails, that.classificationDetails); } @Override public int hashCode() { - return Objects.hash(entityId, timestamp, user, action, details, eventKey, entity, type, detail, created, entityQualifiedName, typeName, headers); + return Objects.hash(entityId, timestamp, user, action, details, eventKey, entity, type, detail, created, entityQualifiedName, typeName, headers, classificationDetails); } @Override @@ -316,6 +320,7 @@ public String toString() { sb.append(", detail=").append(detail); sb.append(", created=").append(created); sb.append(", headers=").append(headers); + sb.append(", classificationDetails").append(classificationDetails); sb.append('}'); return sb.toString(); @@ -347,6 +352,7 @@ public void clear() { detail = null; created = 0L; headers = null; + classificationDetails = null; } private String getJsonPartFromDetails() { @@ -416,4 +422,20 @@ public static void sortEvents(List events, String sortByColu events.sort(sortOrderDesc ? comparator.reversed() : comparator); } + + public List> getClassificationDetails() { + return classificationDetails; + } + + public void setClassificationDetails(List> classificationDetails) { + this.classificationDetails = classificationDetails; + } + + public String getClassificationDetail() { + return classificationDetail; + } + + public void setClassificationDetail(String classificationDetail) { + this.classificationDetail = classificationDetail; + } } \ No newline at end of file diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java index 4cb7e4a185..0e2638cf2e 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java @@ -85,6 +85,10 @@ public AtlasType getType(String typeName) throws AtlasBaseException { LOG.debug("==> AtlasTypeRegistry.getType({})", typeName); } + if (typeName == null) { + return null; + } + AtlasType ret = registryData.allTypes.getTypeByName(typeName); if (ret == null) { From 14d471d05fef398aa4b81dc9244514d872fde7c4 Mon Sep 17 00:00:00 2001 From: aarshi Date: Fri, 5 Jan 2024 20:46:07 +0530 Subject: [PATCH 2/4] Update EntityListerner --- .../audit/ESBasedAuditRepository.java | 15 +- .../audit/EntityAuditListenerV2.java | 151 ++++++++++-------- 2 files changed, 93 insertions(+), 73 deletions(-) diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/ESBasedAuditRepository.java b/repository/src/main/java/org/apache/atlas/repository/audit/ESBasedAuditRepository.java index cbab135606..2fefbc08df 100644 --- a/repository/src/main/java/org/apache/atlas/repository/audit/ESBasedAuditRepository.java +++ b/repository/src/main/java/org/apache/atlas/repository/audit/ESBasedAuditRepository.java @@ -84,6 +84,7 @@ public class ESBasedAuditRepository extends AbstractStorageBasedAuditRepository private static final String USER = "user"; private static final String DETAIL = "detail"; private static final String ENTITY = "entity"; + private static final String CLASSIFICATION_DETAIL= "classificationDetail"; private static final String bulkMetadata = String.format("{ \"index\" : { \"_index\" : \"%s\" } }%n", INDEX_NAME); /* @@ -134,7 +135,8 @@ public void putEventsV2(List events) throws AtlasBaseExcepti event.getEntityQualifiedName(), event.getEntity().getTypeName(), created, - "" + event.getEntity().getUpdateTime().getTime()); + "" + event.getEntity().getUpdateTime().getTime(), + event.getClassificationDetail()); bulkRequestBody.append(bulkMetadata); bulkRequestBody.append(bulkItem); @@ -174,7 +176,7 @@ private String getQueryTemplate(Map requestContextHeaders) { StringBuilder template = new StringBuilder(); template.append("'{'\"entityId\":\"{0}\",\"action\":\"{1}\",\"detail\":{2},\"user\":\"{3}\", \"eventKey\":\"{4}\", " + - "\"entityQualifiedName\": {5}, \"typeName\": \"{6}\",\"created\":{7}, \"timestamp\":{8}"); + "\"entityQualifiedName\": {5}, \"typeName\": \"{6}\",\"created\":{7}, \"timestamp\":{8}, \"classificationDetail\":{9}"); if (MapUtils.isNotEmpty(requestContextHeaders)) { template.append(",") @@ -226,7 +228,14 @@ private EntityAuditSearchResult getResultFromResponse(String responseString) thr EntityAuditEventV2 event = new EntityAuditEventV2(); event.setEntityId(entityGuid); event.setAction(EntityAuditEventV2.EntityAuditActionV2.fromString((String) source.get(ACTION))); - event.setDetail((Map) source.get(DETAIL)); + if (source.get(DETAIL) != null) { + if (source.get(DETAIL) instanceof Map) { + event.setDetail((Map) source.get(DETAIL)); + } + } + if (source.get(CLASSIFICATION_DETAIL) instanceof List) { + event.setClassificationDetails((List>) source.get(CLASSIFICATION_DETAIL)); + } event.setUser((String) source.get(USER)); event.setCreated((long) source.get(CREATED)); if (source.get(TIMESTAMP) != null) { diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditListenerV2.java b/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditListenerV2.java index 301bd8a40f..4f80f887a3 100644 --- a/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditListenerV2.java +++ b/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditListenerV2.java @@ -204,17 +204,11 @@ public void onClassificationsAdded(AtlasEntity entity, List MetricRecorder metric = RequestContext.get().startMetricRecord("entityAudit"); FixedBufferList classificationsAdded = getAuditEventsList(); - for (AtlasClassification classification : classifications) { - if (entity.getGuid().equals(classification.getEntityGuid())) { - createEvent(classificationsAdded.next(), entity, CLASSIFICATION_ADD, "Added classification: " + AtlasType.toJson(classification)); - } else { - createEvent(classificationsAdded.next(), entity, PROPAGATED_CLASSIFICATION_ADD, "Added propagated classification: " + AtlasType.toJson(classification)); - } - } + Map> entityClassifications = new HashMap<>(); + Map> propagatedClassifications = new HashMap<>(); + getClassificationsFromEntity(classifications, entity, entityClassifications, propagatedClassifications); + emitAddClassificationEvent(classificationsAdded, entityClassifications, propagatedClassifications); - for (EntityAuditRepository auditRepository: auditRepositories) { - auditRepository.putEventsV2(classificationsAdded.toList()); - } RequestContext.get().endMetricRecord(metric); } } @@ -227,20 +221,10 @@ public void onClassificationsAdded(List entities, List events = getAuditEventsList(); - for (AtlasClassification classification : classifications) { - for (AtlasEntity entity : entities) { - if (entity.getGuid().equals(classification.getEntityGuid())) { - createEvent(events.next(), entity, CLASSIFICATION_ADD, "Added classification: " + AtlasType.toJson(classification)); - } else { - createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_ADD, "Added propagated classification: " + AtlasType.toJson(classification)); - } - } - } - - for (EntityAuditRepository auditRepository: auditRepositories) { - auditRepository.putEventsV2(events.toList()); - } - + Map> entityClassifications = new HashMap<>(); + Map> propagatedClassifications = new HashMap<>(); + getClassificationsFromEntities(classifications, entities,entityClassifications, propagatedClassifications ); + emitAddClassificationEvent(events, entityClassifications, propagatedClassifications); RequestContext.get().endMetricRecord(metric); } @@ -253,21 +237,51 @@ public void onClassificationsUpdated(AtlasEntity entity, List events = getAuditEventsList(); String guid = entity.getGuid(); - for (AtlasClassification classification : classifications) { - if (guid.equals(classification.getEntityGuid())) { - createEvent(events.next(), entity, CLASSIFICATION_UPDATE, "Updated classification: " + AtlasType.toJson(classification)); - } else { + Map> entityClassifications = new HashMap<>(); + Map> propagatedClassifications = new HashMap<>(); + getClassificationsFromEntity(classifications, entity, entityClassifications, propagatedClassifications); + + List addedClassification = new ArrayList<>(0); + List deletedClassification = new ArrayList<>(0); + List updatedClassification = new ArrayList<>(0); + + if (CollectionUtils.isNotEmpty(propagatedClassifications.get(entity))) { + propagatedClassifications.get(entity).forEach(classification -> { if (isPropagatedClassificationAdded(guid, classification)) { - createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_ADD, "Added propagated classification: " + AtlasType.toJson(classification)); + addedClassification.add(classification); } else if (isPropagatedClassificationDeleted(guid, classification)) { - createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_DELETE, "Deleted propagated classification: " + getDeleteClassificationString(classification.getTypeName())); + deletedClassification.add(new AtlasClassification(classification.getTypeName())); } else { - createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_UPDATE, "Updated propagated classification: " + AtlasType.toJson(classification)); + updatedClassification.add(classification); } - } + }); } - for (EntityAuditRepository auditRepository: auditRepositories) { + if (CollectionUtils.isNotEmpty(addedClassification)) { + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(addedClassification)); + createEvent(auditEvent, entity, PROPAGATED_CLASSIFICATION_ADD, "Added propagated classifications: " + AtlasType.toJson(new AtlasClassification())); + } + + if (CollectionUtils.isNotEmpty(deletedClassification)) { + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(deletedClassification)); + createEvent(auditEvent, entity, PROPAGATED_CLASSIFICATION_DELETE, "Deleted propagated classifications: " + AtlasType.toJson(new AtlasClassification())); + } + + if (CollectionUtils.isNotEmpty(updatedClassification)) { + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(updatedClassification)); + createEvent(auditEvent, entity, PROPAGATED_CLASSIFICATION_UPDATE, "Updated propagated classifications: " + AtlasType.toJson(new AtlasClassification())); + } + + if (entityClassifications.get(entity) != null) { + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(entityClassifications.get(entity))); + createEvent(auditEvent, entity, CLASSIFICATION_UPDATE, "Updated classifications: " + AtlasType.toJson(new AtlasClassification())); + } + + for (EntityAuditRepository auditRepository : auditRepositories) { auditRepository.putEventsV2(events.toList()); } @@ -301,18 +315,10 @@ public void onClassificationsDeleted(AtlasEntity entity, List events = getAuditEventsList(); - - for (AtlasClassification classification : classifications) { - if (StringUtils.equals(entity.getGuid(), classification.getEntityGuid())) { - createEvent(events.next(), entity, CLASSIFICATION_DELETE, "Deleted classification: " + getDeleteClassificationString(classification.getTypeName())); - } else { - createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_DELETE, "Deleted propagated classification: " + getDeleteClassificationString(classification.getTypeName())); - } - } - - for (EntityAuditRepository auditRepository: auditRepositories) { - auditRepository.putEventsV2(events.toList()); - } + Map>> entityClassifications = new HashMap<>(); + Map>> propagatedClassifications = new HashMap<>(); + getClassificationTextFromEntity(classifications, entity, entityClassifications, propagatedClassifications); + emitDeleteClassificationEvent(events, entityClassifications, propagatedClassifications); RequestContext.get().endMetricRecord(metric); } @@ -324,20 +330,10 @@ public void onClassificationsDeleted(List entities, List events = getAuditEventsList(); - - for (AtlasClassification classification : classifications) { - for (AtlasEntity entity : entities) { - if (StringUtils.equals(entity.getGuid(), classification.getEntityGuid())) { - createEvent(events.next(), entity, CLASSIFICATION_DELETE, "Deleted classification: " + getDeleteClassificationString(classification.getTypeName())); - } else { - createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_DELETE, "Deleted propagated classification: " + getDeleteClassificationString(classification.getTypeName())); - } - } - } - - for (EntityAuditRepository auditRepository : auditRepositories) { - auditRepository.putEventsV2(events.toList()); - } + Map>> entityClassifications = new HashMap<>(); + Map>> propagatedClassifications = new HashMap<>(); + getClassificationsTextFromEntities(classifications, entities, entityClassifications, propagatedClassifications); + emitDeleteClassificationEvent(events, entityClassifications, propagatedClassifications); RequestContext.get().endMetricRecord(metric); } @@ -776,22 +772,22 @@ public static String getV2AuditPrefix(EntityAuditActionV2 action) { ret = "Purged: "; break; case CLASSIFICATION_ADD: - ret = "Added classification: "; + ret = "Added classifications: "; break; case CLASSIFICATION_DELETE: - ret = "Deleted classification: "; + ret = "Deleted classifications: "; break; case CLASSIFICATION_UPDATE: - ret = "Updated classification: "; + ret = "Updated classifications: "; break; case PROPAGATED_CLASSIFICATION_ADD: - ret = "Added propagated classification: "; + ret = "Added propagated classifications: "; break; case PROPAGATED_CLASSIFICATION_DELETE: - ret = "Deleted propagated classification: "; + ret = "Deleted propagated classifications: "; break; case PROPAGATED_CLASSIFICATION_UPDATE: - ret = "Updated propagated classification: "; + ret = "Updated propagated classifications: "; break; case ENTITY_IMPORT_CREATE: ret = "Created by import: "; @@ -843,18 +839,24 @@ private void getClassificationsFromEntity(List classificati } } } + private void getClassificationsFromEntities(List classifications, List entities, Map> entityClassifications, Map> propagatedClassifications) { - for (AtlasEntity entity : entities){ + for (AtlasEntity entity : entities) { getClassificationsFromEntity(classifications, entity, entityClassifications, propagatedClassifications); } } + private void emitAddClassificationEvent(FixedBufferList events, Map> entityClassifications, Map> propagatedClassifications) throws AtlasBaseException { entityClassifications.forEach((entity, eClassifications) -> { - createEvent(events.next(), entity, CLASSIFICATION_ADD, "Added classifications: " + AtlasType.toJson(eClassifications)); + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(eClassifications)); + createEvent(auditEvent, entity, CLASSIFICATION_ADD, "Added classifications: " + null); }); propagatedClassifications.forEach((entity, pClassifications) -> { - createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_ADD, "Added propagated classifications: " + AtlasType.toJson(pClassifications)); + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(pClassifications)); + createEvent(auditEvent, entity, PROPAGATED_CLASSIFICATION_ADD, "Added propagated classifications: " + null); }); for (EntityAuditRepository auditRepository : auditRepositories) { auditRepository.putEventsV2(events.toList()); @@ -876,14 +878,23 @@ private void getClassificationTextFromEntity(List classific } } } + private void getClassificationsTextFromEntities(List classifications, List entities, Map>> entityClassifications, Map>> propagatedClassifications) { for (AtlasEntity entity : entities) { getClassificationTextFromEntity(classifications, entity, entityClassifications, propagatedClassifications); } } private void emitDeleteClassificationEvent(FixedBufferList events, Map>> entityClassifications, Map>> propagatedClassifications) throws AtlasBaseException { - entityClassifications.forEach((entity, eClassifications) -> createEvent(events.next(), entity, CLASSIFICATION_DELETE, "Deleted classifications: " + AtlasType.toJson(eClassifications))); - propagatedClassifications.forEach((entity, pClassifications) -> createEvent(events.next(), entity, PROPAGATED_CLASSIFICATION_DELETE, "Deleted propagated classifications: " + AtlasType.toJson(pClassifications))); + entityClassifications.forEach((entity, eClassifications) -> { + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(eClassifications)); + createEvent(auditEvent, entity, CLASSIFICATION_DELETE, "Deleted classifications: " + null); + }); + propagatedClassifications.forEach((entity, pClassifications) -> { + EntityAuditEventV2 auditEvent = events.next(); + auditEvent.setClassificationDetail(AtlasJson.toV1Json(pClassifications)); + createEvent(auditEvent, entity, PROPAGATED_CLASSIFICATION_DELETE, "Deleted propagated classifications: " + null); + }); for (EntityAuditRepository auditRepository : auditRepositories) { auditRepository.putEventsV2(events.toList()); From 40a37b100d8b4d061ee26ae080d9515b776383ef Mon Sep 17 00:00:00 2001 From: aarshi Date: Fri, 5 Jan 2024 21:09:50 +0530 Subject: [PATCH 3/4] Update EntityGraphMapper --- .../store/graph/v2/EntityGraphMapper.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java index acaaa4345e..453a529cc9 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java @@ -2948,17 +2948,21 @@ public void addClassifications(final EntityMutationContext context, String guid, if (CollectionUtils.isNotEmpty(entitiesToPropagateTo)) { notificationVertices.addAll(entitiesToPropagateTo); } - if (RequestContext.get().isDelayTagNotifications()) { for (AtlasClassification classification : addedClassifications.keySet()) { - Set vertices = addedClassifications.get(classification); + Set vertices = addedClassifications.get(classification); RequestContext.get().addAddedClassificationAndVertices(classification, new ArrayList<>(vertices)); } } else { + Map> entityClassification = new HashMap<>(); for (AtlasClassification classification : addedClassifications.keySet()) { Set vertices = addedClassifications.get(classification); List propagatedEntities = updateClassificationText(classification, vertices); - entityChangeNotifier.onClassificationsAddedToEntities(propagatedEntities, Collections.singletonList(classification), false); + propagatedEntities.forEach(entity -> entityClassification.computeIfAbsent(entity, key -> new ArrayList<>()).add(classification)); + } + + for (Map.Entry> atlasEntityListEntry : entityClassification.entrySet()) { + entityChangeNotifier.onClassificationAddedToEntity(atlasEntityListEntry.getKey(), atlasEntityListEntry.getValue()); } } @@ -3209,14 +3213,17 @@ public void deleteClassification(String entityGuid, String classificationName) t entityVertex.setProperty(CLASSIFICATION_NAMES_KEY, getClassificationNamesString(traitNames)); updateModificationMetadata(entityVertex); + Map> entityClassification = new HashMap<>(); if (RequestContext.get().isDelayTagNotifications()) { RequestContext.get().addDeletedClassificationAndVertices(classification, new ArrayList<>(entityVertices)); } else if (CollectionUtils.isNotEmpty(entityVertices)) { List propagatedEntities = updateClassificationText(classification, entityVertices); + propagatedEntities.forEach(entity -> entityClassification.computeIfAbsent(entity, key -> new ArrayList<>()).add(classification)); //Sending audit request for all entities at once - entityChangeNotifier.onClassificationsDeletedFromEntities(propagatedEntities, Collections.singletonList(classification)); - + for (Map.Entry> atlasEntityListEntry : entityClassification.entrySet()) { + entityChangeNotifier.onClassificationDeletedFromEntity(atlasEntityListEntry.getKey(), atlasEntityListEntry.getValue()); + } } AtlasPerfTracer.log(perf); } From a6b6b6ed01104660bba06a0cac12dc3dd7c5f6c5 Mon Sep 17 00:00:00 2001 From: aarshi Date: Fri, 5 Jan 2024 21:19:08 +0530 Subject: [PATCH 4/4] Update ClassificationAssociator --- .../graph/v2/ClassificationAssociator.java | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/ClassificationAssociator.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/ClassificationAssociator.java index 292ce1de09..637ba84acc 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/ClassificationAssociator.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/ClassificationAssociator.java @@ -193,42 +193,20 @@ public void setClassifications(Map map) throws AtlasB AtlasPerfMetrics.MetricRecorder recorder = RequestContext.get().startMetricRecord("commitChanges.notify"); Map> deleted = RequestContext.get().getDeletedClassificationAndVertices(); - Set allVertices = new HashSet<>(); - if (MapUtils.isNotEmpty(deleted)) { - for (AtlasClassification deletedClassification : deleted.keySet()) { - Collection vertices = deleted.get(deletedClassification); - List propagatedEntities = new ArrayList<>(); - - for (Object obj : vertices) { - AtlasVertex vertex = (AtlasVertex) obj; - AtlasEntity entity = instanceConverter.getAndCacheEntity(GraphHelper.getGuid(vertex), IGNORE_REL); - - allVertices.add(vertex); - propagatedEntities.add(entity); - } - entityChangeNotifier.onClassificationsDeletedFromEntities(propagatedEntities, Collections.singletonList(deletedClassification)); + Map> entityClassification = getEntityClassificationsMapping(deleted); + for (Map.Entry> atlasEntityListEntry : entityClassification.entrySet()) { + entityChangeNotifier.onClassificationDeletedFromEntity(atlasEntityListEntry.getKey(), atlasEntityListEntry.getValue()); } } Map> added = RequestContext.get().getAddedClassificationAndVertices(); if (MapUtils.isNotEmpty(added)) { - for (AtlasClassification addedClassification : added.keySet()) { - Collection vertices = added.get(addedClassification); - List propagatedEntities = new ArrayList<>(); - - for (Object obj : vertices) { - AtlasVertex vertex = (AtlasVertex) obj; - AtlasEntity entity = instanceConverter.getAndCacheEntity(GraphHelper.getGuid(vertex), IGNORE_REL); - - allVertices.add(vertex); - propagatedEntities.add(entity); - } - entityChangeNotifier.onClassificationsAddedToEntities(propagatedEntities, Collections.singletonList(addedClassification), false); + Map> entityClassification = getEntityClassificationsMapping(added); + for (Map.Entry> atlasEntityListEntry : entityClassification.entrySet()) { + entityChangeNotifier.onClassificationAddedToEntity(atlasEntityListEntry.getKey(), atlasEntityListEntry.getValue()); } } - - entityGraphMapper.updateClassificationText(null, allVertices); transactionInterceptHelper.intercept(); RequestContext.get().endMetricRecord(recorder); RequestContext.get().setDelayTagNotifications(false); @@ -308,14 +286,12 @@ private void deleteClassifications(String entityGuid, String typeName, List