You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sa...@apache.org on 2019/11/06 13:23:47 UTC
[atlas] branch master updated: ATLAS-3497 Add audit entry for
adding/removing labels
This is an automated email from the ASF dual-hosted git repository.
sarath pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new 6050a8e ATLAS-3497 Add audit entry for adding/removing labels
6050a8e is described below
commit 6050a8e6f7d572174d36946b9bee6968777e2850
Author: Le Ma <lm...@cloudera.com>
AuthorDate: Thu Oct 31 14:56:49 2019 -0700
ATLAS-3497 Add audit entry for adding/removing labels
Signed-off-by: Sarath Subramanian <sa...@apache.org>
---
.../java/org/apache/atlas/EntityAuditEvent.java | 6 ++-
dashboardv2/public/js/utils/Enums.js | 4 +-
dashboardv3/public/js/utils/Enums.js | 4 +-
.../atlas/listener/EntityChangeListenerV2.java | 19 ++++++++
.../atlas/model/audit/EntityAuditEventV2.java | 6 ++-
.../repository/audit/EntityAuditListenerV2.java | 37 +++++++++++++++
.../converters/AtlasInstanceConverter.java | 4 ++
.../apache/atlas/repository/graph/GraphHelper.java | 10 +---
.../store/graph/v2/AtlasEntityChangeNotifier.java | 13 ++++++
.../store/graph/v2/EntityGraphMapper.java | 53 +++++++++++++++++-----
.../store/graph/v2/AtlasEntityStoreV2Test.java | 12 ++---
.../notification/EntityNotificationListenerV2.java | 10 ++++
12 files changed, 148 insertions(+), 30 deletions(-)
diff --git a/client/client-v1/src/main/java/org/apache/atlas/EntityAuditEvent.java b/client/client-v1/src/main/java/org/apache/atlas/EntityAuditEvent.java
index fcd6a62..1b452a9 100644
--- a/client/client-v1/src/main/java/org/apache/atlas/EntityAuditEvent.java
+++ b/client/client-v1/src/main/java/org/apache/atlas/EntityAuditEvent.java
@@ -49,7 +49,7 @@ public class EntityAuditEvent implements Serializable {
ENTITY_CREATE, ENTITY_UPDATE, ENTITY_DELETE, TAG_ADD, TAG_DELETE, TAG_UPDATE,
PROPAGATED_TAG_ADD, PROPAGATED_TAG_DELETE, PROPAGATED_TAG_UPDATE,
ENTITY_IMPORT_CREATE, ENTITY_IMPORT_UPDATE, ENTITY_IMPORT_DELETE,
- TERM_ADD, TERM_DELETE;
+ TERM_ADD, TERM_DELETE, LABEL_ADD, LABEL_DELETE;
public static EntityAuditAction fromString(String strValue) {
switch (strValue) {
@@ -84,6 +84,10 @@ public class EntityAuditEvent implements Serializable {
return TERM_ADD;
case "TERM_DELETE":
return TERM_DELETE;
+ case "LABEL_ADD":
+ return LABEL_ADD;
+ case "LABEL_DELETE":
+ return LABEL_DELETE;
}
throw new IllegalArgumentException("No enum constant " + EntityAuditAction.class.getCanonicalName() + "." + strValue);
diff --git a/dashboardv2/public/js/utils/Enums.js b/dashboardv2/public/js/utils/Enums.js
index c7316d5..74a08d9 100644
--- a/dashboardv2/public/js/utils/Enums.js
+++ b/dashboardv2/public/js/utils/Enums.js
@@ -35,7 +35,9 @@ define(['require'], function(require) {
ENTITY_IMPORT_UPDATE: "Entity Updated by import",
ENTITY_IMPORT_DELETE: "Entity Deleted by import",
TERM_ADD: "Term Added",
- TERM_DELETE: "Term Deleted"
+ TERM_DELETE: "Term Deleted",
+ LABEL_ADD: "Label Added",
+ LABEL_DELETE: "Label Deleted"
}
Enums.entityStateReadOnly = {
diff --git a/dashboardv3/public/js/utils/Enums.js b/dashboardv3/public/js/utils/Enums.js
index c7316d5..74a08d9 100644
--- a/dashboardv3/public/js/utils/Enums.js
+++ b/dashboardv3/public/js/utils/Enums.js
@@ -35,7 +35,9 @@ define(['require'], function(require) {
ENTITY_IMPORT_UPDATE: "Entity Updated by import",
ENTITY_IMPORT_DELETE: "Entity Deleted by import",
TERM_ADD: "Term Added",
- TERM_DELETE: "Term Deleted"
+ TERM_DELETE: "Term Deleted",
+ LABEL_ADD: "Label Added",
+ LABEL_DELETE: "Label Deleted"
}
Enums.entityStateReadOnly = {
diff --git a/intg/src/main/java/org/apache/atlas/listener/EntityChangeListenerV2.java b/intg/src/main/java/org/apache/atlas/listener/EntityChangeListenerV2.java
index 106c797..444167e 100644
--- a/intg/src/main/java/org/apache/atlas/listener/EntityChangeListenerV2.java
+++ b/intg/src/main/java/org/apache/atlas/listener/EntityChangeListenerV2.java
@@ -26,6 +26,7 @@ import org.apache.atlas.model.instance.AtlasRelatedObjectId;
import org.apache.atlas.model.instance.AtlasRelationship;
import java.util.List;
+import java.util.Set;
/**
* Entity change notification listener V2.
@@ -121,4 +122,22 @@ public interface EntityChangeListenerV2 {
* @param isImport
*/
void onRelationshipsDeleted(List<AtlasRelationship> relationships, boolean isImport) throws AtlasBaseException;
+
+ /**
+ * This is upon add new labels to an entity.
+ *
+ * @param entity the entity
+ * @param labels labels that needs to be added to an entity
+ * @throws AtlasBaseException if the listener notification fails
+ */
+ void onLabelsAdded(AtlasEntity entity, Set<String> labels) throws AtlasBaseException;
+
+ /**
+ * This is upon deleting labels from an entity.
+ *
+ * @param entity the entity
+ * @param labels labels that needs to be deleted for an entity
+ * @throws AtlasBaseException if the listener notification fails
+ */
+ void onLabelsDeleted(AtlasEntity entity, Set<String> labels) throws AtlasBaseException;
}
\ No newline at end of file
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 649f11f..e9cc7cd 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
@@ -50,7 +50,7 @@ public class EntityAuditEventV2 implements Serializable {
ENTITY_IMPORT_CREATE, ENTITY_IMPORT_UPDATE, ENTITY_IMPORT_DELETE,
CLASSIFICATION_ADD, CLASSIFICATION_DELETE, CLASSIFICATION_UPDATE,
PROPAGATED_CLASSIFICATION_ADD, PROPAGATED_CLASSIFICATION_DELETE, PROPAGATED_CLASSIFICATION_UPDATE,
- TERM_ADD, TERM_DELETE;
+ TERM_ADD, TERM_DELETE, LABEL_ADD, LABEL_DELETE;
public static EntityAuditActionV2 fromString(String strValue) {
switch (strValue) {
@@ -85,6 +85,10 @@ public class EntityAuditEventV2 implements Serializable {
return TERM_ADD;
case "TERM_DELETE":
return TERM_DELETE;
+ case "LABEL_ADD":
+ return LABEL_ADD;
+ case "LABEL_DELETE":
+ return LABEL_DELETE;
}
throw new IllegalArgumentException("No enum constant " + EntityAuditActionV2.class.getCanonicalName() + "." + strValue);
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 20624da..43a9b84 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
@@ -47,6 +47,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.CLASSIFICATION_ADD;
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.CLASSIFICATION_DELETE;
@@ -57,6 +58,8 @@ import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.ENTITY_IMPORT_DELETE;
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.ENTITY_IMPORT_UPDATE;
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.ENTITY_UPDATE;
+import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.LABEL_ADD;
+import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.LABEL_DELETE;
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.PROPAGATED_CLASSIFICATION_ADD;
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.PROPAGATED_CLASSIFICATION_DELETE;
import static org.apache.atlas.model.audit.EntityAuditEventV2.EntityAuditActionV2.PROPAGATED_CLASSIFICATION_UPDATE;
@@ -241,6 +244,40 @@ public class EntityAuditListenerV2 implements EntityChangeListenerV2 {
}
}
+ @Override
+ public void onLabelsAdded(AtlasEntity entity, Set<String> labels) throws AtlasBaseException {
+ if (CollectionUtils.isNotEmpty(labels)) {
+ MetricRecorder metric = RequestContext.get().startMetricRecord("entityAudit");
+
+ List<EntityAuditEventV2> events = new ArrayList<>();
+
+ String addedLabels = StringUtils.join(labels, " ");
+
+ events.add(createEvent(entity, LABEL_ADD, "Added labels: " + addedLabels));
+
+ auditRepository.putEventsV2(events);
+
+ RequestContext.get().endMetricRecord(metric);
+ }
+ }
+
+ @Override
+ public void onLabelsDeleted(AtlasEntity entity, Set<String> labels) throws AtlasBaseException {
+ if (CollectionUtils.isNotEmpty(labels)) {
+ MetricRecorder metric = RequestContext.get().startMetricRecord("entityAudit");
+
+ List<EntityAuditEventV2> events = new ArrayList<>();
+
+ String deletedLabels = StringUtils.join(labels, " ");
+
+ events.add(createEvent(entity, LABEL_DELETE, "Deleted labels: " + deletedLabels));
+
+ auditRepository.putEventsV2(events);
+
+ RequestContext.get().endMetricRecord(metric);
+ }
+ }
+
private EntityAuditEventV2 createEvent(AtlasEntity entity, EntityAuditActionV2 action, String details) {
return new EntityAuditEventV2(entity.getGuid(), RequestContext.get().getRequestTime(),
RequestContext.get().getUser(), action, details, entity);
diff --git a/repository/src/main/java/org/apache/atlas/repository/converters/AtlasInstanceConverter.java b/repository/src/main/java/org/apache/atlas/repository/converters/AtlasInstanceConverter.java
index 1f0cc86..01e339d 100644
--- a/repository/src/main/java/org/apache/atlas/repository/converters/AtlasInstanceConverter.java
+++ b/repository/src/main/java/org/apache/atlas/repository/converters/AtlasInstanceConverter.java
@@ -394,6 +394,10 @@ public class AtlasInstanceConverter {
return EntityAuditEvent.EntityAuditAction.PROPAGATED_TAG_DELETE;
case PROPAGATED_CLASSIFICATION_UPDATE:
return EntityAuditEvent.EntityAuditAction.PROPAGATED_TAG_UPDATE;
+ case LABEL_ADD:
+ return EntityAuditEvent.EntityAuditAction.LABEL_ADD;
+ case LABEL_DELETE:
+ return EntityAuditEvent.EntityAuditAction.LABEL_DELETE;
}
return null;
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
index 173165a..1e7acf1 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
@@ -1851,16 +1851,10 @@ public final class GraphHelper {
}
private static Set<String> parseLabelsString(String labels) {
- Set<String> ret = null;
+ Set<String> ret = new HashSet<>();
if (StringUtils.isNotEmpty(labels)) {
- ret = new HashSet<>();
-
- for (String label : labels.split("\\" + LABEL_NAME_DELIMITER)) {
- if (StringUtils.isNotEmpty(label)) {
- ret.add(label);
- }
- }
+ ret.addAll(Arrays.asList(StringUtils.split(labels, "\\" + LABEL_NAME_DELIMITER)));
}
return ret;
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityChangeNotifier.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityChangeNotifier.java
index c910d9e..3389d24 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityChangeNotifier.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityChangeNotifier.java
@@ -256,6 +256,19 @@ public class AtlasEntityChangeNotifier {
}
}
+ public void onLabelsUpdatedFromEntity(String entityGuid, Set<String> addedLabels, Set<String> deletedLabels) throws AtlasBaseException {
+ doFullTextMapping(entityGuid);
+
+ if (isV2EntityNotificationEnabled) {
+ AtlasEntity entity = instanceConverter.getAndCacheEntity(entityGuid);
+
+ for (EntityChangeListenerV2 listener : entityChangeListenersV2) {
+ listener.onLabelsDeleted(entity, deletedLabels);
+ listener.onLabelsAdded(entity, addedLabels);
+ }
+ }
+ }
+
public void notifyPropagatedEntities() throws AtlasBaseException {
RequestContext context = RequestContext.get();
Map<String, List<AtlasClassification>> addedPropagations = context.getAddedPropagations();
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 2c2fc59..a114d25 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
@@ -92,6 +92,7 @@ import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdg
import static org.apache.atlas.repository.graph.GraphHelper.getClassificationVertex;
import static org.apache.atlas.repository.graph.GraphHelper.getDefaultRemovePropagations;
import static org.apache.atlas.repository.graph.GraphHelper.getDelimitedClassificationNames;
+import static org.apache.atlas.repository.graph.GraphHelper.getLabels;
import static org.apache.atlas.repository.graph.GraphHelper.getMapElementsProperty;
import static org.apache.atlas.repository.graph.GraphHelper.getStatus;
import static org.apache.atlas.repository.graph.GraphHelper.getTraitLabel;
@@ -331,15 +332,28 @@ public class EntityGraphMapper {
}
}
- public void setLabels(AtlasVertex vertex, Set<String> labels) {
- if (CollectionUtils.isNotEmpty(labels)) {
- AtlasGraphUtilsV2.setEncodedProperty(vertex, LABELS_PROPERTY_KEY, getLabelString(labels));
+ public void setLabels(AtlasVertex vertex, Set<String> labels) throws AtlasBaseException {
+ final Set<String> currentLabels = getLabels(vertex);
+ final Set<String> addedLabels;
+ final Set<String> removedLabels;
+
+ if (CollectionUtils.isEmpty(currentLabels)) {
+ addedLabels = labels;
+ removedLabels = null;
+ } else if (CollectionUtils.isEmpty(labels)) {
+ addedLabels = null;
+ removedLabels = labels;
} else {
- vertex.removeProperty(LABELS_PROPERTY_KEY);
+ addedLabels = new HashSet<String>(CollectionUtils.subtract(labels, currentLabels));
+ removedLabels = new HashSet<String>(CollectionUtils.subtract(currentLabels, labels));
}
+
+ updateLabels(vertex, labels);
+
+ entityChangeNotifier.onLabelsUpdatedFromEntity(GraphHelper.getGuid(vertex), addedLabels, removedLabels);
}
- public void addLabels(AtlasVertex vertex, Set<String> labels) {
+ public void addLabels(AtlasVertex vertex, Set<String> labels) throws AtlasBaseException {
if (CollectionUtils.isNotEmpty(labels)) {
final Set<String> existingLabels = GraphHelper.getLabels(vertex);
final Set<String> updatedLabels;
@@ -347,25 +361,40 @@ public class EntityGraphMapper {
if (CollectionUtils.isEmpty(existingLabels)) {
updatedLabels = labels;
} else {
- updatedLabels = existingLabels;
+ updatedLabels = new HashSet<>(existingLabels);
updatedLabels.addAll(labels);
}
-
- setLabels(vertex, updatedLabels);
+ if (!updatedLabels.equals(existingLabels)) {
+ updateLabels(vertex, updatedLabels);
+ updatedLabels.removeAll(existingLabels);
+ entityChangeNotifier.onLabelsUpdatedFromEntity(GraphHelper.getGuid(vertex), updatedLabels, null);
+ }
}
}
- public void removeLabels(AtlasVertex vertex, Set<String> labels) {
+ public void removeLabels(AtlasVertex vertex, Set<String> labels) throws AtlasBaseException {
if (CollectionUtils.isNotEmpty(labels)) {
final Set<String> existingLabels = GraphHelper.getLabels(vertex);
- Set<String> updatedLabels = null;
+ Set<String> updatedLabels;
if (CollectionUtils.isNotEmpty(existingLabels)) {
- updatedLabels = existingLabels;
+ updatedLabels = new HashSet<>(existingLabels);
updatedLabels.removeAll(labels);
+
+ if (!updatedLabels.equals(existingLabels)) {
+ updateLabels(vertex, updatedLabels);
+ existingLabels.removeAll(updatedLabels);
+ entityChangeNotifier.onLabelsUpdatedFromEntity(GraphHelper.getGuid(vertex), null, existingLabels);
+ }
}
+ }
+ }
- setLabels(vertex, updatedLabels);
+ private void updateLabels(AtlasVertex vertex, Set<String> labels) {
+ if (CollectionUtils.isNotEmpty(labels)) {
+ AtlasGraphUtilsV2.setEncodedProperty(vertex, LABELS_PROPERTY_KEY, getLabelString(labels));
+ } else {
+ vertex.removeProperty(LABELS_PROPERTY_KEY);
}
}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
index aba988d..51d55b9 100644
--- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
@@ -1147,19 +1147,19 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
AtlasEntity tblEntity = getEntityFromStore(tblEntityGuid);
- Assert.assertNull(tblEntity.getLabels());
+ Assert.assertTrue(tblEntity.getLabels().isEmpty());
}
@Test (dependsOnMethods = "clearLabelsToEntity")
- public void nullLabelsToEntity() throws AtlasBaseException {
+ public void emptyLabelsToEntity() throws AtlasBaseException {
entityStore.setLabels(tblEntityGuid, null);
AtlasEntity tblEntity = getEntityFromStore(tblEntityGuid);
- Assert.assertNull(tblEntity.getLabels());
+ Assert.assertTrue(tblEntity.getLabels().isEmpty());
}
- @Test (dependsOnMethods = "nullLabelsToEntity")
+ @Test (dependsOnMethods = "emptyLabelsToEntity")
public void invalidLabelLengthToEntity() throws AtlasBaseException {
Set<String> labels = new HashSet<>();
labels.add(randomAlphanumeric(50));
@@ -1173,7 +1173,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
}
@Test (dependsOnMethods = "invalidLabelLengthToEntity")
- public void invalidLabelCharactersToEntity() throws AtlasBaseException {
+ public void invalidLabelCharactersToEntity() {
Set<String> labels = new HashSet<>();
labels.add("label-1_100_45");
labels.add("LABEL-1_200-55");
@@ -1227,6 +1227,6 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
labels.add("label_3_add");
entityStore.removeLabels(tblEntityGuid, labels);
tblEntity = getEntityFromStore(tblEntityGuid);
- Assert.assertNull(tblEntity.getLabels());
+ Assert.assertTrue(tblEntity.getLabels().isEmpty());
}
}
\ No newline at end of file
diff --git a/webapp/src/main/java/org/apache/atlas/notification/EntityNotificationListenerV2.java b/webapp/src/main/java/org/apache/atlas/notification/EntityNotificationListenerV2.java
index b2211fc..48f0cd3 100644
--- a/webapp/src/main/java/org/apache/atlas/notification/EntityNotificationListenerV2.java
+++ b/webapp/src/main/java/org/apache/atlas/notification/EntityNotificationListenerV2.java
@@ -128,6 +128,16 @@ public class EntityNotificationListenerV2 implements EntityChangeListenerV2 {
// do nothing -> notification not sent out for term removal from entities
}
+ @Override
+ public void onLabelsDeleted(AtlasEntity entity, Set<String> labels) throws AtlasBaseException {
+ // do nothing -> notification not sent out for label removal to entities
+ }
+
+ @Override
+ public void onLabelsAdded(AtlasEntity entity, Set<String> labels) throws AtlasBaseException {
+ // do nothing -> notification not sent out for label assignment to entities
+ }
+
private void notifyEntityEvents(List<AtlasEntity> entities, OperationType operationType) throws AtlasBaseException {
MetricRecorder metric = RequestContext.get().startMetricRecord("entityNotification");
List<EntityNotificationV2> messages = new ArrayList<>();