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 2018/03/27 05:29:02 UTC
atlas git commit: ATLAS-2510: Add support to disable/enable
propagated classification in entity
Repository: atlas
Updated Branches:
refs/heads/master 993180309 -> 0f689faaa
ATLAS-2510: Add support to disable/enable propagated classification in entity
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/0f689faa
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/0f689faa
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/0f689faa
Branch: refs/heads/master
Commit: 0f689faaa5ef6433ecb39d9f0ee8c4cf8a48b8eb
Parents: 9931803
Author: Sarath Subramanian <ss...@hortonworks.com>
Authored: Mon Mar 26 22:28:39 2018 -0700
Committer: Sarath Subramanian <ss...@hortonworks.com>
Committed: Mon Mar 26 22:28:39 2018 -0700
----------------------------------------------------------------------
.../org/apache/atlas/repository/Constants.java | 1 +
.../java/org/apache/atlas/AtlasErrorCode.java | 1 +
.../model/instance/AtlasClassification.java | 1 +
.../atlas/model/instance/AtlasEntity.java | 23 ++-
.../org/apache/atlas/query/GremlinClause.java | 2 +-
.../atlas/repository/graph/GraphHelper.java | 162 +++++++++++--------
.../store/graph/AtlasEntityStore.java | 2 +
.../store/graph/v1/AtlasEntityStoreV1.java | 17 ++
.../store/graph/v1/DeleteHandlerV1.java | 13 +-
.../store/graph/v1/EntityGraphMapper.java | 64 +++++++-
.../store/graph/v1/EntityGraphRetriever.java | 74 ++++++---
.../atlas/query/GremlinQueryComposerTest.java | 12 +-
.../org/apache/atlas/web/rest/EntityREST.java | 46 ++++++
13 files changed, 306 insertions(+), 112 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/common/src/main/java/org/apache/atlas/repository/Constants.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java b/common/src/main/java/org/apache/atlas/repository/Constants.java
index 605742d..310dddb 100644
--- a/common/src/main/java/org/apache/atlas/repository/Constants.java
+++ b/common/src/main/java/org/apache/atlas/repository/Constants.java
@@ -121,6 +121,7 @@ public final class Constants {
public static final String CLASSIFICATION_VERTEX_PROPAGATE_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "propagate";
public static final String CLASSIFICATION_EDGE_NAME_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "name";
public static final String CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "isPropagated";
+ public static final String CLASSIFICATION_EDGE_STATE_PROPERTY_KEY = STATE_PROPERTY_KEY;
public static final String CLASSIFICATION_LABEL = "classifiedAs";
private Constants() {
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 4a86670..997ac68 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -127,6 +127,7 @@ public enum AtlasErrorCode {
CLASSIFICATION_NOT_ASSOCIATED_WITH_ENTITY(400, "ATLAS-400-00-06D", "Classification {0} is not associated with entity"),
NO_CLASSIFICATIONS_FOUND_FOR_ENTITY(400, "ATLAS-400-00-06E", "No classifications associated with entity: {0}"),
INVALID_CLASSIFICATION_PARAMS(400, "ATLAS-400-00-06F", "Invalid classification parameters passed for {0} operation for entity: {1}"),
+ PROPAGATED_CLASSIFICATION_NOT_ASSOCIATED_WITH_ENTITY(400, "ATLAS-400-00-070", "Propagated classification {0} is not associated with entity"),
UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/intg/src/main/java/org/apache/atlas/model/instance/AtlasClassification.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasClassification.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasClassification.java
index 008314b..bf4f469 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasClassification.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasClassification.java
@@ -57,6 +57,7 @@ public class AtlasClassification extends AtlasStruct implements Serializable {
private boolean propagate = true;
private List<TimeBoundary> validityPeriods = null;
+ public enum PropagationState { ACTIVE, DELETED }
public AtlasClassification() {
this(null, null);
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
index fce46da..3954319 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
@@ -67,7 +67,6 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
public static final String KEY_UPDATE_TIME = "updateTime";
public static final String KEY_VERSION = "version";
-
/**
* Status of the entity - can be active or deleted. Deleted entities are not removed from Atlas store.
*/
@@ -83,6 +82,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
private Map<String, Object> relationshipAttributes;
private List<AtlasClassification> classifications;
+ private List<AtlasClassification> propagationDisabledClassifications;
@JsonIgnore
private static AtomicLong s_nextId = new AtomicLong(System.nanoTime());
@@ -165,6 +165,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
setUpdateTime(other.getUpdateTime());
setVersion(other.getVersion());
setClassifications(other.getClassifications());
+ setPropagationDisabledClassifications(other.getPropagationDisabledClassifications());
}
}
@@ -259,6 +260,14 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
public void setClassifications(List<AtlasClassification> classifications) { this.classifications = classifications; }
+ public List<AtlasClassification> getPropagationDisabledClassifications() {
+ return propagationDisabledClassifications;
+ }
+
+ public void setPropagationDisabledClassifications(List<AtlasClassification> propagationDisabledClassifications) {
+ this.propagationDisabledClassifications = propagationDisabledClassifications;
+ }
+
public void addClassifications(List<AtlasClassification> classifications) {
List<AtlasClassification> c = this.classifications;
@@ -279,6 +288,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
setCreateTime(null);
setUpdateTime(null);
setClassifications(null);
+ setPropagationDisabledClassifications(null);
}
private static String nextInternalId() {
@@ -306,7 +316,9 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
sb.append(", classifications=[");
AtlasBaseTypeDef.dumpObjects(classifications, sb);
sb.append(']');
- sb.append(", ");
+ sb.append(", propagationDisabledClassifications=[");
+ AtlasBaseTypeDef.dumpObjects(propagationDisabledClassifications, sb);
+ sb.append(']');
sb.append('}');
return sb;
@@ -327,13 +339,14 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
Objects.equals(updateTime, that.updateTime) &&
Objects.equals(version, that.version) &&
Objects.equals(relationshipAttributes, that.relationshipAttributes) &&
- Objects.equals(classifications, that.classifications);
+ Objects.equals(classifications, that.classifications) &&
+ Objects.equals(propagationDisabledClassifications, that.propagationDisabledClassifications);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), guid, status, createdBy, updatedBy, createTime, updateTime, version,
- relationshipAttributes, classifications);
+ relationshipAttributes, classifications, propagationDisabledClassifications);
}
@Override
@@ -715,4 +728,4 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
super(list, startIndex, pageSize, totalCount, sortType, sortBy);
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/main/java/org/apache/atlas/query/GremlinClause.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/query/GremlinClause.java b/repository/src/main/java/org/apache/atlas/query/GremlinClause.java
index 454b343..087bcc6 100644
--- a/repository/src/main/java/org/apache/atlas/query/GremlinClause.java
+++ b/repository/src/main/java/org/apache/atlas/query/GremlinClause.java
@@ -46,7 +46,7 @@ enum GremlinClause {
TEXT_CONTAINS("has('%s', org.janusgraph.core.attribute.Text.textRegex(%s))"),
TEXT_PREFIX("has('%s', org.janusgraph.core.attribute.Text.textPrefix(%s))"),
TEXT_SUFFIX("has('%s', org.janusgraph.core.attribute.Text.textRegex(\".*\" + %s))"),
- TRAIT("outE('classifiedAs').has('__name', within('%s')).outV()"),
+ TRAIT("outE('classifiedAs').has('__name', within('%s')).has('__state', 'ACTIVE').outV()"),
SELECT_NOOP_FN("def f(r){ r }; "),
SELECT_FN("def f(r){ t=[[%s]]; %s r.each({t.add([%s])}); t.unique(); }; "),
SELECT_ONLY_AGG_FN("def f(r){ t=[[%s]]; %s t.add([%s]); t;}; "),
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
----------------------------------------------------------------------
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 bfb5a71..0c63cec 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
@@ -26,6 +26,7 @@ import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException;
import org.apache.atlas.RequestContextV1;
import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntity.Status;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.instance.AtlasRelationship;
@@ -73,8 +74,9 @@ import java.util.Objects;
import java.util.Set;
import java.util.UUID;
-import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY;
+import static org.apache.atlas.repository.Constants.CLASSIFICATION_EDGE_STATE_PROPERTY_KEY;
+import static org.apache.atlas.repository.Constants.CLASSIFICATION_ENTITY_GUID;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_LABEL;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_EDGE_NAME_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_VERTEX_PROPAGATE_KEY;
@@ -190,6 +192,7 @@ public final class GraphHelper {
if (ret != null) {
AtlasGraphUtilsV1.setProperty(ret, CLASSIFICATION_EDGE_NAME_PROPERTY_KEY, getTypeName(classificationVertex));
AtlasGraphUtilsV1.setProperty(ret, CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY, isPropagated);
+ AtlasGraphUtilsV1.setProperty(ret, CLASSIFICATION_EDGE_STATE_PROPERTY_KEY, AtlasClassification.PropagationState.ACTIVE);
}
return ret;
@@ -299,26 +302,6 @@ public final class GraphHelper {
return (AtlasEdge) findElement(false, args);
}
- public static boolean edgeExists(AtlasVertex outVertex, AtlasVertex inVertex, String edgeLabel) {
- boolean ret = false;
- Iterator<AtlasEdge> edges = getAdjacentEdgesByLabel(inVertex, AtlasEdgeDirection.IN, edgeLabel);
-
- while (edges != null && edges.hasNext()) {
- AtlasEdge edge = edges.next();
-
- if (edge.getOutVertex().equals(outVertex)) {
- Status edgeState = getStatus(edge);
-
- if (edgeState == null || edgeState == ACTIVE) {
- ret = true;
- break;
- }
- }
- }
-
- return ret;
- }
-
private AtlasElement findElement(boolean isVertexSearch, Object... args) throws EntityNotFoundException {
AtlasGraphQuery query = graph.query();
@@ -395,54 +378,83 @@ public final class GraphHelper {
}
public static AtlasVertex getClassificationVertex(AtlasVertex entityVertex, String classificationName) {
- AtlasVertex ret = null;
- AtlasEdge edge = getClassificationEdge(entityVertex, classificationName);
+ AtlasVertex ret = null;
+ Iterable edges = entityVertex.query().direction(AtlasEdgeDirection.OUT).label(CLASSIFICATION_LABEL)
+ .has(CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY, false)
+ .has(CLASSIFICATION_EDGE_NAME_PROPERTY_KEY, classificationName).edges();
+ if (edges != null) {
+ Iterator<AtlasEdge> iterator = edges.iterator();
- if (edge != null) {
- ret = edge.getInVertex();
+ if (iterator.hasNext()) {
+ AtlasEdge edge = iterator.next();
+
+ ret = (edge != null) ? edge.getInVertex() : null;
+ }
}
return ret;
}
- public static AtlasEdge getClassificationEdge(AtlasVertex entityVertex, String classificationName) {
+ public static AtlasEdge getClassificationEdge(AtlasVertex entityVertex, AtlasVertex classificationVertex) {
AtlasEdge ret = null;
Iterable edges = entityVertex.query().direction(AtlasEdgeDirection.OUT).label(CLASSIFICATION_LABEL)
.has(CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY, false)
- .has(CLASSIFICATION_EDGE_NAME_PROPERTY_KEY, classificationName).edges();
+ .has(CLASSIFICATION_EDGE_NAME_PROPERTY_KEY, getTypeName(classificationVertex)).edges();
if (edges != null) {
Iterator<AtlasEdge> iterator = edges.iterator();
if (iterator.hasNext()) {
AtlasEdge edge = iterator.next();
- ret = (edge != null) ? edge : null;
+ ret = (edge != null && edge.getInVertex().equals(classificationVertex)) ? edge : null;
}
}
return ret;
}
- public static List<String> getPropagatedEntities(AtlasVertex classificationVertex) {
- List<String> ret = new ArrayList<>();
- List<AtlasVertex> entityVertices = getPropagatedEntityVertices(classificationVertex);
+ public static AtlasEdge getPropagatedClassificationEdge(AtlasVertex entityVertex, String classificationName, String associatedEntityGuid) {
+ AtlasEdge ret = null;
+ Iterable edges = entityVertex.query().direction(AtlasEdgeDirection.OUT).label(CLASSIFICATION_LABEL)
+ .has(CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY, true)
+ .has(CLASSIFICATION_EDGE_NAME_PROPERTY_KEY, classificationName).edges();
+ if (edges != null) {
+ Iterator<AtlasEdge> iterator = edges.iterator();
- if (CollectionUtils.isNotEmpty(entityVertices)) {
- for (AtlasVertex entityVertex : entityVertices) {
- ret.add(getGuid(entityVertex));
+ while (iterator.hasNext()) {
+ AtlasEdge edge = iterator.next();
+ AtlasVertex classificationVertex = (edge != null) ? edge.getInVertex() : null;
+
+ if (classificationVertex != null) {
+ String guid = AtlasGraphUtilsV1.getProperty(classificationVertex, CLASSIFICATION_ENTITY_GUID, String.class);
+
+ if (StringUtils.equals(guid, associatedEntityGuid)) {
+ ret = edge;
+ break;
+ }
+ }
}
}
return ret;
}
- public static List<AtlasVertex> getPropagatedEntityVertices(AtlasVertex classificationVertex) {
- List<AtlasVertex> ret = new ArrayList<>();
- List<AtlasEdge> propagatedEdges = getPropagatedEdges(classificationVertex);
+ public static AtlasEdge getPropagatedClassificationEdge(AtlasVertex entityVertex, AtlasVertex classificationVertex) {
+ AtlasEdge ret = null;
+ Iterable edges = entityVertex.query().direction(AtlasEdgeDirection.OUT).label(CLASSIFICATION_LABEL)
+ .has(CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY, true)
+ .has(CLASSIFICATION_EDGE_NAME_PROPERTY_KEY, getTypeName(classificationVertex)).edges();
+
+ if (edges != null && classificationVertex != null) {
+ Iterator<AtlasEdge> iterator = edges.iterator();
+
+ while (iterator != null && iterator.hasNext()) {
+ AtlasEdge edge = iterator.next();
- if (CollectionUtils.isNotEmpty(propagatedEdges)) {
- for (AtlasEdge propagatedEdge : propagatedEdges) {
- ret.add(propagatedEdge.getOutVertex());
+ if (edge != null && edge.getInVertex().equals(classificationVertex)) {
+ ret = edge;
+ break;
+ }
}
}
@@ -676,21 +688,28 @@ public final class GraphHelper {
vertex.addProperty(actualPropertyName, value);
}
- /**
- * Adds an additional value to a multi-property (LIST).
- *
- * @param vertex
- * @param propertyName
- * @param value
- */
- public static void addListProperty(AtlasVertex vertex, String propertyName, Object value) {
- String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
+ public static void addToPropagatedTraitNames(AtlasVertex entityVertex, String classificationName) {
+ String actualPropertyName = GraphHelper.encodePropertyKey(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY);
if (LOG.isDebugEnabled()) {
- LOG.debug("Adding property {} = \"{}\" to vertex {}", actualPropertyName, value, string(vertex));
+ LOG.debug("Adding property {} = \"{}\" to vertex {}", actualPropertyName, classificationName, string(entityVertex));
}
- vertex.addListProperty(actualPropertyName, value);
+ entityVertex.addListProperty(actualPropertyName, classificationName);
+ }
+
+ public static void removeFromPropagatedTraitNames(AtlasVertex entityVertex, String classificationName) {
+ if (entityVertex != null && StringUtils.isNotEmpty(classificationName)) {
+ List<String> propagatedTraitNames = getTraitNames(entityVertex, true);
+
+ propagatedTraitNames.remove(classificationName);
+
+ entityVertex.removeProperty(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY);
+
+ for (String propagatedTraitName : propagatedTraitNames) {
+ addToPropagatedTraitNames(entityVertex, propagatedTraitName);
+ }
+ }
}
/**
@@ -1014,6 +1033,33 @@ public final class GraphHelper {
return (getState(element) == Id.EntityState.DELETED) ? AtlasRelationship.Status.DELETED : AtlasRelationship.Status.ACTIVE;
}
+ public static AtlasClassification.PropagationState getClassificationEdgeState(AtlasEdge edge) {
+ AtlasClassification.PropagationState ret = null;
+
+ if (edge != null) {
+ String state = edge.getProperty(Constants.CLASSIFICATION_EDGE_STATE_PROPERTY_KEY, String.class);
+
+ ret = (StringUtils.isEmpty(state)) ? AtlasClassification.PropagationState.ACTIVE :
+ AtlasClassification.PropagationState.valueOf(state);
+ }
+
+ return ret;
+ }
+
+ public static boolean isPropagatedClassificationEdge(AtlasEdge edge) {
+ boolean ret = false;
+
+ if (edge != null) {
+ Boolean isPropagated = edge.getProperty(Constants.CLASSIFICATION_EDGE_IS_PROPAGATED_PROPERTY_KEY, Boolean.class);
+
+ if (isPropagated != null) {
+ ret = isPropagated.booleanValue();
+ }
+ }
+
+ return ret;
+ }
+
public static PropagateTags getPropagateTags(AtlasElement element) {
String propagateTags = element.getProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, String.class);
@@ -1661,18 +1707,4 @@ public final class GraphHelper {
private static boolean verticesEquals(AtlasVertex vertexA, AtlasVertex vertexB) {
return StringUtils.equals(getGuid(vertexB), getGuid(vertexA));
}
-
- public static void removePropagatedTraitNameFromVertex(AtlasVertex entityVertex, String propagatedTraitName) {
- List<String> propagatedTraitNames = getTraitNames(entityVertex, true);
-
- if (CollectionUtils.isNotEmpty(propagatedTraitNames) && propagatedTraitNames.contains(propagatedTraitName)) {
- propagatedTraitNames.remove(propagatedTraitName);
-
- entityVertex.removeProperty(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY);
-
- for (String pTraitName : propagatedTraitNames) {
- GraphHelper.addListProperty(entityVertex, PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, pTraitName);
- }
- }
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
index 79e8e3e..eb825c4 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
@@ -157,4 +157,6 @@ public interface AtlasEntityStore {
List<AtlasClassification> getClassifications(String guid) throws AtlasBaseException;
AtlasClassification getClassification(String guid, String classificationName) throws AtlasBaseException;
+
+ void setPropagatedClassificationState(String guid, String classificationName, String sourceEntityGuid, boolean disablePropagation) throws AtlasBaseException;
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
index b5461d4..6fe8570 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
@@ -468,6 +468,23 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
@Override
@GraphTransaction
+ public void setPropagatedClassificationState(String entityGuid, String classificationName, String sourceEntityGuid, boolean disablePropagation) throws AtlasBaseException {
+ AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(entityGuid);
+
+ AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION, entityHeader, new AtlasClassification(classificationName)),
+ "change propagated classification state: guid=", entityGuid, ", classification=", classificationName);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Toggle propagated classification={}, sourceEntityGuid={} for entity={}, disablePropagation={}", classificationName, sourceEntityGuid, entityGuid, disablePropagation);
+ }
+
+ GraphTransactionInterceptor.lockObjectAndReleasePostCommit(entityGuid);
+
+ entityGraphMapper.setPropagatedClassificationState(entityGuid, classificationName, sourceEntityGuid, disablePropagation);
+ }
+
+ @Override
+ @GraphTransaction
public void deleteClassifications(final String guid, final List<String> classificationNames) throws AtlasBaseException {
if (StringUtils.isEmpty(guid)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "Guid(s) not specified");
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
index 19ac620..6386bcb 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
@@ -41,18 +41,19 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdg
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
+import static org.apache.atlas.model.instance.AtlasClassification.PropagationState.ACTIVE;
import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_LABEL;
import static org.apache.atlas.repository.Constants.PROPAGATED_TRAIT_NAMES_PROPERTY_KEY;
import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX;
-import static org.apache.atlas.repository.graph.GraphHelper.addListProperty;
-import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdge;
+import static org.apache.atlas.repository.graph.GraphHelper.addToPropagatedTraitNames;
+import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdgeState;
import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdges;
import static org.apache.atlas.repository.graph.GraphHelper.getPropagatedEdges;
import static org.apache.atlas.repository.graph.GraphHelper.getTraitNames;
@@ -367,7 +368,9 @@ public abstract class DeleteHandlerV1 {
getTypeName(propagatedEntityVertex), GraphHelper.getGuid(propagatedEntityVertex), CLASSIFICATION_LABEL);
}
- removeFromPropagatedTraitNames(propagatedEntityVertex, classificationName);
+ if (getClassificationEdgeState(propagatedEdge) == ACTIVE) {
+ removeFromPropagatedTraitNames(propagatedEntityVertex, classificationName);
+ }
deleteEdge(propagatedEdge, true);
@@ -390,7 +393,7 @@ public abstract class DeleteHandlerV1 {
entityVertex.removeProperty(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY);
for (String propagatedTraitName : propagatedTraitNames) {
- addListProperty(entityVertex, PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, propagatedTraitName);
+ addToPropagatedTraitNames(entityVertex, propagatedTraitName);
}
}
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
index c76f640..737e933 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
@@ -25,6 +25,7 @@ import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TimeBoundary;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.atlas.model.instance.AtlasClassification.PropagationState;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
import org.apache.atlas.model.instance.AtlasEntityHeader;
@@ -74,20 +75,23 @@ import static org.apache.atlas.model.instance.EntityMutations.EntityOperation.DE
import static org.apache.atlas.model.instance.EntityMutations.EntityOperation.PARTIAL_UPDATE;
import static org.apache.atlas.model.instance.EntityMutations.EntityOperation.UPDATE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality.SET;
+import static org.apache.atlas.repository.Constants.CLASSIFICATION_EDGE_STATE_PROPERTY_KEY;
+import static org.apache.atlas.repository.Constants.CLASSIFICATION_ENTITY_GUID;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_LABEL;
-import static org.apache.atlas.repository.Constants.PROPAGATED_TRAIT_NAMES_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.STATE_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.TRAIT_NAMES_PROPERTY_KEY;
-import static org.apache.atlas.repository.graph.GraphHelper.addListProperty;
+import static org.apache.atlas.repository.graph.GraphHelper.addToPropagatedTraitNames;
import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdge;
+import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdgeState;
import static org.apache.atlas.repository.graph.GraphHelper.getClassificationVertex;
-import static org.apache.atlas.repository.graph.GraphHelper.getPropagatedEntities;
+import static org.apache.atlas.repository.graph.GraphHelper.getPropagatedClassificationEdge;
import static org.apache.atlas.repository.graph.GraphHelper.getTraitLabel;
import static org.apache.atlas.repository.graph.GraphHelper.getTraitNames;
import static org.apache.atlas.repository.graph.GraphHelper.getTypeName;
import static org.apache.atlas.repository.graph.GraphHelper.getTypeNames;
import static org.apache.atlas.repository.graph.GraphHelper.isPropagationEnabled;
import static org.apache.atlas.repository.graph.GraphHelper.isRelationshipEdge;
+import static org.apache.atlas.repository.graph.GraphHelper.removeFromPropagatedTraitNames;
import static org.apache.atlas.repository.graph.GraphHelper.string;
import static org.apache.atlas.repository.graph.GraphHelper.updateModificationMetadata;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getIdFromVertex;
@@ -1443,10 +1447,10 @@ public class EntityGraphMapper {
// remove classifications from associated entity
if (LOG.isDebugEnabled()) {
LOG.debug("Removing classification: [{}] from: [{}][{}] with edge label: [{}]", classificationName,
- getTypeName(entityVertex), entityGuid, CLASSIFICATION_LABEL);
+ getTypeName(entityVertex), entityGuid, CLASSIFICATION_LABEL);
}
- AtlasEdge edge = getClassificationEdge(entityVertex, classificationName);
+ AtlasEdge edge = getClassificationEdge(entityVertex, classificationVertex);
deleteHandler.deleteEdgeReference(edge, CLASSIFICATION, false, true, entityVertex);
@@ -1626,6 +1630,46 @@ public class EntityGraphMapper {
}
}
+ public void setPropagatedClassificationState(String entityGuid, String classificationName, String sourceEntityGuid, boolean disablePropagation) throws AtlasBaseException {
+ AtlasVertex entityVertex = AtlasGraphUtilsV1.findByGuid(entityGuid);
+
+ if (entityVertex == null) {
+ throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, entityGuid);
+ }
+
+ AtlasEdge propagatedEdge = getPropagatedClassificationEdge(entityVertex, classificationName, sourceEntityGuid);
+
+ if (propagatedEdge == null) {
+ throw new AtlasBaseException(AtlasErrorCode.PROPAGATED_CLASSIFICATION_NOT_ASSOCIATED_WITH_ENTITY, classificationName);
+ }
+
+ PropagationState currentState = getClassificationEdgeState(propagatedEdge);
+ PropagationState updatedState = (disablePropagation) ? PropagationState.DELETED : PropagationState.ACTIVE;
+
+ if (currentState != updatedState) {
+ AtlasGraphUtilsV1.setProperty(propagatedEdge, CLASSIFICATION_EDGE_STATE_PROPERTY_KEY, updatedState);
+
+ if (disablePropagation) {
+ removeFromPropagatedTraitNames(entityVertex, classificationName);
+ } else {
+ addToPropagatedTraitNames(entityVertex, classificationName);
+ }
+
+ updateModificationMetadata(entityVertex);
+
+ AtlasEntityWithExtInfo entityWithExtInfo = instanceConverter.getAndCacheEntity(entityGuid);
+ AtlasEntity entity = (entityWithExtInfo != null) ? entityWithExtInfo.getEntity() : null;
+
+ if (updatedState == PropagationState.DELETED) {
+ entityChangeNotifier.onClassificationDeletedFromEntity(entity, Collections.singletonList(classificationName));
+ } else {
+ AtlasClassification classification = entityRetriever.toAtlasClassification(propagatedEdge.getInVertex());
+
+ entityChangeNotifier.onClassificationAddedToEntity(entity, Collections.singletonList(classification));
+ }
+ }
+ }
+
private List<AtlasVertex> addTagPropagation(AtlasVertex classificationVertex, List<AtlasVertex> propagatedEntityVertices) {
List<AtlasVertex> ret = null;
@@ -1634,6 +1678,12 @@ public class EntityGraphMapper {
AtlasClassificationType classificationType = typeRegistry.getClassificationTypeByName(classificationName);
for (AtlasVertex propagatedEntityVertex : propagatedEntityVertices) {
+ AtlasEdge existingEdge = getPropagatedClassificationEdge(propagatedEntityVertex, classificationVertex);
+
+ if (existingEdge != null) {
+ continue;
+ }
+
String entityTypeName = getTypeName(propagatedEntityVertex);
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName);
@@ -1651,7 +1701,7 @@ public class EntityGraphMapper {
graphHelper.addClassificationEdge(propagatedEntityVertex, classificationVertex, true);
- addListProperty(propagatedEntityVertex, PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, classificationName);
+ addToPropagatedTraitNames(propagatedEntityVertex, classificationName);
}
}
}
@@ -1679,7 +1729,7 @@ public class EntityGraphMapper {
// map all the attributes to this newly created AtlasVertex
mapAttributes(classification, traitInstanceVertex, operation, context);
- AtlasEdge ret = getClassificationEdge(parentInstanceVertex, getTypeName(traitInstanceVertex));
+ AtlasEdge ret = getClassificationEdge(parentInstanceVertex, traitInstanceVertex);
if (ret == null) {
ret = graphHelper.addClassificationEdge(parentInstanceVertex, traitInstanceVertex, false);
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
index 8fe635a..59513f5 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
@@ -22,6 +22,7 @@ import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TimeBoundary;
import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.atlas.model.instance.AtlasClassification.PropagationState;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityExtInfo;
@@ -36,7 +37,6 @@ import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.RepositoryException;
import org.apache.atlas.repository.graph.GraphHelper;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
@@ -69,22 +69,28 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static org.apache.atlas.model.instance.AtlasClassification.PropagationState.ACTIVE;
+import static org.apache.atlas.model.instance.AtlasClassification.PropagationState.DELETED;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.*;
import static org.apache.atlas.repository.Constants.*;
import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX;
-import static org.apache.atlas.repository.graph.GraphHelper.addListProperty;
-import static org.apache.atlas.repository.graph.GraphHelper.edgeExists;
+import static org.apache.atlas.repository.graph.GraphHelper.addToPropagatedTraitNames;
import static org.apache.atlas.repository.graph.GraphHelper.getAdjacentEdgesByLabel;
+import static org.apache.atlas.repository.graph.GraphHelper.getAllClassificationEdges;
import static org.apache.atlas.repository.graph.GraphHelper.getAllTraitNames;
import static org.apache.atlas.repository.graph.GraphHelper.getAssociatedEntityVertex;
+import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdge;
+import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEdgeState;
import static org.apache.atlas.repository.graph.GraphHelper.getGuid;
import static org.apache.atlas.repository.graph.GraphHelper.getIncomingEdgesByLabel;
import static org.apache.atlas.repository.graph.GraphHelper.getOutGoingEdgesByLabel;
import static org.apache.atlas.repository.graph.GraphHelper.getPropagateTags;
+import static org.apache.atlas.repository.graph.GraphHelper.getPropagatedClassificationEdge;
import static org.apache.atlas.repository.graph.GraphHelper.getRelationshipGuid;
import static org.apache.atlas.repository.graph.GraphHelper.getTypeName;
+import static org.apache.atlas.repository.graph.GraphHelper.isPropagatedClassificationEdge;
import static org.apache.atlas.repository.graph.GraphHelper.isPropagationEnabled;
-import static org.apache.atlas.repository.graph.GraphHelper.removePropagatedTraitNameFromVertex;
+import static org.apache.atlas.repository.graph.GraphHelper.removeFromPropagatedTraitNames;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getIdFromVertex;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.BOTH;
@@ -446,7 +452,8 @@ public final class EntityGraphRetriever {
public List<AtlasClassification> getAllClassifications(AtlasVertex entityVertex) throws AtlasBaseException {
List<AtlasClassification> ret = new ArrayList<>();
- Iterable edges = entityVertex.query().direction(AtlasEdgeDirection.OUT).label(CLASSIFICATION_LABEL).edges();
+ Iterable edges = entityVertex.query().direction(AtlasEdgeDirection.OUT).label(CLASSIFICATION_LABEL)
+ .has(CLASSIFICATION_EDGE_STATE_PROPERTY_KEY, ACTIVE.name()).edges();
if (edges != null) {
Iterator<AtlasEdge> iterator = edges.iterator();
@@ -487,9 +494,26 @@ public final class EntityGraphRetriever {
}
private void mapClassifications(AtlasVertex entityVertex, AtlasEntity entity) throws AtlasBaseException {
- final List<AtlasClassification> classifications = getAllClassifications(entityVertex);
+ List<AtlasEdge> edges = getAllClassificationEdges(entityVertex);
- entity.setClassifications(classifications);
+ if (CollectionUtils.isNotEmpty(edges)) {
+ List<AtlasClassification> allClassifications = new ArrayList<>();
+ List<AtlasClassification> propagationDisabledClassifications = new ArrayList<>();
+
+ for (AtlasEdge edge : edges) {
+ PropagationState edgeState = getClassificationEdgeState(edge);
+ AtlasVertex classificationVertex = edge.getInVertex();
+
+ if (edgeState == ACTIVE) {
+ allClassifications.add(toAtlasClassification(classificationVertex));
+ } else if (edgeState == DELETED && isPropagatedClassificationEdge(edge)) {
+ propagationDisabledClassifications.add(toAtlasClassification(classificationVertex));
+ }
+ }
+
+ entity.setClassifications(allClassifications);
+ entity.setPropagationDisabledClassifications(propagationDisabledClassifications);
+ }
}
private Object mapVertexToAttribute(AtlasVertex entityVertex, AtlasAttribute attribute, AtlasEntityExtInfo entityExtInfo) throws AtlasBaseException {
@@ -964,17 +988,17 @@ public final class EntityGraphRetriever {
AtlasClassificationType classificationType = typeRegistry.getClassificationTypeByName(classificationName);
for (AtlasVertex impactedEntityVertex : impactedEntityVertices) {
- if (edgeExists(impactedEntityVertex, classificationVertex, classificationName)) {
+ if (getClassificationEdge(impactedEntityVertex, classificationVertex) != null) {
if (LOG.isDebugEnabled()) {
LOG.debug(" --> Classification edge already exists from [{}] --> [{}][{}] using edge label: [{}]",
- getTypeName(impactedEntityVertex), getTypeName(classificationVertex), getTypeName(associatedEntityVertex), classificationName);
+ getTypeName(impactedEntityVertex), getTypeName(classificationVertex), getTypeName(associatedEntityVertex), classificationName);
}
continue;
- } else if (edgeExists(impactedEntityVertex, classificationVertex, CLASSIFICATION_LABEL)) {
+ } else if (getPropagatedClassificationEdge(impactedEntityVertex, classificationVertex) != null) {
if (LOG.isDebugEnabled()) {
LOG.debug(" --> Propagated classification edge already exists from [{}] --> [{}][{}] using edge label: [{}]",
- getTypeName(impactedEntityVertex), getTypeName(classificationVertex), getTypeName(associatedEntityVertex), CLASSIFICATION_LABEL);
+ getTypeName(impactedEntityVertex), getTypeName(classificationVertex), getTypeName(associatedEntityVertex), CLASSIFICATION_LABEL);
}
continue;
@@ -997,9 +1021,15 @@ public final class EntityGraphRetriever {
getTypeName(impactedEntityVertex), getTypeName(classificationVertex), getTypeName(associatedEntityVertex), CLASSIFICATION_LABEL);
}
+ AtlasEdge existingEdge = getPropagatedClassificationEdge(impactedEntityVertex, classificationVertex);
+
+ if (existingEdge != null) {
+ continue;
+ }
+
graphHelper.addClassificationEdge(impactedEntityVertex, classificationVertex, true);
- addListProperty(impactedEntityVertex, PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, classificationName);
+ addToPropagatedTraitNames(impactedEntityVertex, classificationName);
}
}
}
@@ -1035,20 +1065,18 @@ public final class EntityGraphRetriever {
}
// remove propagated classification edge and classificationName from propagatedTraitNames vertex property
- if (edgeExists(impactedEntityVertex, classificationVertex, CLASSIFICATION_LABEL)) {
- try {
- if (LOG.isDebugEnabled()) {
- LOG.debug(" --> Removing propagated classification edge from [{}] --> [{}][{}] with edge label: [{}]",
- getTypeName(impactedEntityVertex), getTypeName(classificationVertex), getTypeName(associatedEntityVertex), CLASSIFICATION_LABEL);
- }
+ AtlasEdge propagatedEdge = getPropagatedClassificationEdge(impactedEntityVertex, classificationVertex);
- AtlasEdge propagatedEdge = graphHelper.getOrCreateEdge(impactedEntityVertex, classificationVertex, CLASSIFICATION_LABEL);
+ if (propagatedEdge != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(" --> Removing propagated classification edge from [{}] --> [{}][{}] with edge label: [{}]",
+ getTypeName(impactedEntityVertex), getTypeName(classificationVertex), getTypeName(associatedEntityVertex), CLASSIFICATION_LABEL);
+ }
- graphHelper.removeEdge(propagatedEdge);
+ graphHelper.removeEdge(propagatedEdge);
- removePropagatedTraitNameFromVertex(impactedEntityVertex, classificationName);
- } catch (RepositoryException e) {
- throw new AtlasBaseException(AtlasErrorCode.INTERNAL_ERROR, e);
+ if (getClassificationEdgeState(propagatedEdge) == ACTIVE) {
+ removeFromPropagatedTraitNames(impactedEntityVertex, classificationName);
}
} else {
if (LOG.isDebugEnabled()) {
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java b/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
index 9b4c91d..fa2332e 100644
--- a/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
+++ b/repository/src/test/java/org/apache/atlas/query/GremlinQueryComposerTest.java
@@ -36,13 +36,13 @@ import static org.testng.Assert.fail;
public class GremlinQueryComposerTest {
@Test
public void classification() {
- String expected = "g.V().outE('classifiedAs').has('__name', within('PII')).outV().dedup().limit(25).toList()";
+ String expected = "g.V().outE('classifiedAs').has('__name', within('PII')).has('__state', 'ACTIVE').outV().dedup().limit(25).toList()";
verify("PII", expected);
}
@Test()
public void dimension() {
- String expected = "g.V().has('__typeName', 'Table').outE('classifiedAs').has('__name', within('Dimension')).outV().dedup().limit(25).toList()";
+ String expected = "g.V().has('__typeName', 'Table').outE('classifiedAs').has('__name', within('Dimension')).has('__state', 'ACTIVE').outV().dedup().limit(25).toList()";
verify("Table isa Dimension", expected);
verify("Table is Dimension", expected);
verify("Table where Table is Dimension", expected);
@@ -295,14 +295,14 @@ public class GremlinQueryComposerTest {
@Test
public void keywordsInWhereClause() {
verify("Table as t where t has name and t isa Dimension",
- "g.V().has('__typeName', 'Table').as('t').and(__.has('Table.name'),__.outE('classifiedAs').has('__name', within('Dimension')).outV()).dedup().limit(25).toList()");
+ "g.V().has('__typeName', 'Table').as('t').and(__.has('Table.name'),__.outE('classifiedAs').has('__name', within('Dimension')).has('__state', 'ACTIVE').outV()).dedup().limit(25).toList()");
verify("Table as t where t has name and t.name = 'sales_fact'",
"g.V().has('__typeName', 'Table').as('t').and(__.has('Table.name'),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
verify("Table as t where t is Dimension and t.name = 'sales_fact'",
- "g.V().has('__typeName', 'Table').as('t').and(__.outE('classifiedAs').has('__name', within('Dimension')).outV(),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
- verify("Table isa 'Dimension' and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.outE('classifiedAs').has('__name', within('Dimension')).outV(),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
+ "g.V().has('__typeName', 'Table').as('t').and(__.outE('classifiedAs').has('__name', within('Dimension')).has('__state', 'ACTIVE').outV(),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
+ verify("Table isa 'Dimension' and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.outE('classifiedAs').has('__name', within('Dimension')).has('__state', 'ACTIVE').outV(),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
verify("Table has name and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.has('Table.name'),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
- verify("Table is 'Dimension' and Table has owner and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.outE('classifiedAs').has('__name', within('Dimension')).outV(),__.has('Table.owner'),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
+ verify("Table is 'Dimension' and Table has owner and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.outE('classifiedAs').has('__name', within('Dimension')).has('__state', 'ACTIVE').outV(),__.has('Table.owner'),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
verify("Table has name and Table has owner and name = 'sales_fact'", "g.V().has('__typeName', 'Table').and(__.has('Table.name'),__.has('Table.owner'),__.has('Table.name', eq('sales_fact'))).dedup().limit(25).toList()");
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/0f689faa/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
index fdafa2c..17a6ece 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
@@ -475,6 +475,52 @@ public class EntityREST {
}
}
+
+ /**
+ * Disable/Enable propagated classification for an existing entity represented by its guid.
+ * @param guid globally unique identifier for the entity
+ * @param classificationName name of the propagated classification
+ * @param sourceEntityGuid source entity guid of the propagated classification
+ * @param disablePropagation disable/enable propagation
+ */
+ @PUT
+ @Path("/guid/{guid}/propagatedClassifications/{classificationName}")
+ @Produces(Servlets.JSON_MEDIA_TYPE)
+ public void setPropagatedClassificationState(@PathParam("guid") String guid,
+ @PathParam("classificationName") final String classificationName,
+ @QueryParam("sourceEntityGuid") String sourceEntityGuid,
+ @QueryParam("disablePropagation") boolean disablePropagation) throws AtlasBaseException {
+ Servlets.validateQueryParamLength("guid", guid);
+ Servlets.validateQueryParamLength("classificationName", classificationName);
+ Servlets.validateQueryParamLength("sourceEntityGuid", sourceEntityGuid);
+
+ AtlasPerfTracer perf = null;
+
+ try {
+ if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityREST.setPropagatedClassificationState(" + guid + "," + classificationName + "," + sourceEntityGuid + "," + disablePropagation + ")");
+ }
+
+ if (StringUtils.isEmpty(guid)) {
+ throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+ }
+
+ if (StringUtils.isEmpty(classificationName)) {
+ throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "propagated classification not specified");
+ }
+
+ if (StringUtils.isEmpty(sourceEntityGuid)) {
+ throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, sourceEntityGuid);
+ }
+
+ ensureClassificationType(classificationName);
+
+ entitiesStore.setPropagatedClassificationState(guid, classificationName, sourceEntityGuid, disablePropagation);
+ } finally {
+ AtlasPerfTracer.log(perf);
+ }
+ }
+
/******************************************************************/
/** Bulk API operations **/
/******************************************************************/