Commit 5bb2dcbe by David Radley Committed by Madhan Neethiraj

ATLAS-1891: added RelationshipDef validation during typesystem updates

parent 4f16db45
...@@ -67,7 +67,7 @@ public enum AtlasErrorCode { ...@@ -67,7 +67,7 @@ public enum AtlasErrorCode {
INVALID_STRUCT_VALUE(400, "ATLAS-400-00-025", "not a valid struct value {0}"), INVALID_STRUCT_VALUE(400, "ATLAS-400-00-025", "not a valid struct value {0}"),
INSTANCE_LINEAGE_INVALID_PARAMS(400, "ATLAS-400-00-026", "Invalid lineage query parameters passed {0}: {1}"), INSTANCE_LINEAGE_INVALID_PARAMS(400, "ATLAS-400-00-026", "Invalid lineage query parameters passed {0}: {1}"),
ATTRIBUTE_UPDATE_NOT_SUPPORTED(400, "ATLAS-400-00-027", "{0}.{1} : attribute update not supported"), ATTRIBUTE_UPDATE_NOT_SUPPORTED(400, "ATLAS-400-00-027", "{0}.{1} : attribute update not supported"),
INVALID_VALUE(400, "ATLAS-400-00-028", "invalid value: {0}"), INVALID_VALUE(400, "ATLAS-400-00-028", "invalid value: {0}"),
BAD_REQUEST(400, "ATLAS-400-00-029", "{0}"), BAD_REQUEST(400, "ATLAS-400-00-029", "{0}"),
PARAMETER_PARSING_FAILED(400, "ATLAS-400-00-02A", "Parameter parsing failed at: {0}"), PARAMETER_PARSING_FAILED(400, "ATLAS-400-00-02A", "Parameter parsing failed at: {0}"),
MISSING_MANDATORY_ATTRIBUTE(400, "ATLAS-400-00-02B", "Mandatory field {0}.{1} has empty/null value"), MISSING_MANDATORY_ATTRIBUTE(400, "ATLAS-400-00-02B", "Mandatory field {0}.{1} has empty/null value"),
...@@ -80,7 +80,13 @@ public enum AtlasErrorCode { ...@@ -80,7 +80,13 @@ public enum AtlasErrorCode {
RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER(400, "ATLAS-400-00-033", "COMPOSITION relationshipDef {0} cannot have a SET cardinality and be a container"), RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER(400, "ATLAS-400-00-033", "COMPOSITION relationshipDef {0} cannot have a SET cardinality and be a container"),
RELATIONSHIPDEF_LIST_ON_END(400, "ATLAS-400-00-034", "relationshipDef {0} cannot have a LIST cardinality on an end"), RELATIONSHIPDEF_LIST_ON_END(400, "ATLAS-400-00-034", "relationshipDef {0} cannot have a LIST cardinality on an end"),
RELATIONSHIPDEF_INVALID_END_TYPE(400, "ATLAS-400-00-035", "relationshipDef {0} has invalid end type {1}"), RELATIONSHIPDEF_INVALID_END_TYPE(400, "ATLAS-400-00-035", "relationshipDef {0} has invalid end type {1}"),
INVALID_RELATIONSHIP_END_TYPE(400, "ATLAS-400-00-036", "invalid end type for relationship {0}: expected {1}, found {2}"), INVALID_RELATIONSHIP_END_TYPE(400, "ATLAS-400-00-036", "invalid update for relationshipDef {0}: new end type {1}, existing end type {2}"),
RELATIONSHIPDEF_INVALID_END1_UPDATE(400, "ATLAS-400-00-037", "invalid update for relationshipDef {0}: new end1 {1}, existing end1 {2}"),
RELATIONSHIPDEF_INVALID_END2_UPDATE(400, "ATLAS-400-00-038", "invalid update for relationshipDef {0}: new end2 {1}, existing end2 {2}"),
RELATIONSHIPDEF_INVALID_CATEGORY_UPDATE(400, "ATLAS-400-00-039", "invalid update for relationship {0}: new relationshipDef category {1}, existing relationshipDef category {2}"),
RELATIONSHIPDEF_INVALID_NAME_UPDATE(400, "ATLAS-400-00-040", "invalid relationshipDef rename for relationship guid {0}: new name {1}, existing name {2}"),
RELATIONSHIPDEF_END1_NAME_INVALID(400, "ATLAS-400-00-020", "{0}: invalid end1 name. Name must not contain query keywords"),
RELATIONSHIPDEF_END2_NAME_INVALID(400, "ATLAS-400-00-020", "{0}: invalid end2 name. Name must not contain query keywords"),
// All Not found enums go here // All Not found enums go here
TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"), TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"),
TYPE_GUID_NOT_FOUND(404, "ATLAS-404-00-002", "Given type guid {0} was invalid"), TYPE_GUID_NOT_FOUND(404, "ATLAS-404-00-002", "Given type guid {0} was invalid"),
...@@ -94,14 +100,14 @@ public enum AtlasErrorCode { ...@@ -94,14 +100,14 @@ public enum AtlasErrorCode {
INSTANCE_NOT_FOUND(404, "ATLAS-404-00-00B", "Given instance is invalid/not found: {0}"), INSTANCE_NOT_FOUND(404, "ATLAS-404-00-00B", "Given instance is invalid/not found: {0}"),
RELATIONSHIP_GUID_NOT_FOUND(404, "ATLAS-404-00-00C", "Given relationship guid {0} is invalid/not found"), RELATIONSHIP_GUID_NOT_FOUND(404, "ATLAS-404-00-00C", "Given relationship guid {0} is invalid/not found"),
RELATIONSHIP_CRUD_INVALID_PARAMS(404, "ATLAS-404-00-00D", "Invalid relationship creation/updation parameters passed : {0}"), RELATIONSHIP_CRUD_INVALID_PARAMS(404, "ATLAS-404-00-00D", "Invalid relationship creation/updation parameters passed : {0}"),
// All data conflict errors go here
// All data conflict errors go here
TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"), TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"),
TYPE_HAS_REFERENCES(409, "ATLAS-409-00-002", "Given type {0} has references"), TYPE_HAS_REFERENCES(409, "ATLAS-409-00-002", "Given type {0} has references"),
INSTANCE_ALREADY_EXISTS(409, "ATLAS-409-00-003", "failed to update entity: {0}"), INSTANCE_ALREADY_EXISTS(409, "ATLAS-409-00-003", "failed to update entity: {0}"),
RELATIONSHIP_ALREADY_EXISTS(409, "ATLAS-409-00-004", "relationship {0} already exists between entities {1} and {2}"), RELATIONSHIP_ALREADY_EXISTS(409, "ATLAS-409-00-004", "relationship {0} already exists between entities {1} and {2}"),
TYPE_HAS_RELATIONSHIPS(409, "ATLAS-409-00-005", "Given type {0} has associated relationshipDefs"),
// All internal errors go here // All internal errors go here
INTERNAL_ERROR(500, "ATLAS-500-00-001", "Internal server error {0}"), INTERNAL_ERROR(500, "ATLAS-500-00-001", "Internal server error {0}"),
INDEX_CREATION_FAILED(500, "ATLAS-500-00-002", "Index creation failed for {0}"), INDEX_CREATION_FAILED(500, "ATLAS-500-00-002", "Index creation failed for {0}"),
INDEX_ROLLBACK_FAILED(500, "ATLAS-500-00-003", "Index rollback failed for {0}"), INDEX_ROLLBACK_FAILED(500, "ATLAS-500-00-003", "Index rollback failed for {0}"),
...@@ -155,4 +161,4 @@ public enum AtlasErrorCode { ...@@ -155,4 +161,4 @@ public enum AtlasErrorCode {
public String getErrorCode() { public String getErrorCode() {
return errorCode; return errorCode;
} }
} }
\ No newline at end of file
...@@ -23,6 +23,8 @@ import org.apache.atlas.model.instance.AtlasEntityHeader; ...@@ -23,6 +23,8 @@ import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId; import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.typedef.*; import org.apache.atlas.model.typedef.*;
import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef; import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
...@@ -241,6 +243,18 @@ public class AtlasTypeUtil { ...@@ -241,6 +243,18 @@ public class AtlasTypeUtil {
return new AtlasEntityDef(name, description, version, Arrays.asList(attrDefs), superTypes); return new AtlasEntityDef(name, description, version, Arrays.asList(attrDefs), superTypes);
} }
public static AtlasRelationshipDef createRelationshipTypeDef(String name,
String description,
String version,
RelationshipCategory relationshipCategory,
PropagateTags propagateTags,
AtlasRelationshipEndDef endDef1,
AtlasRelationshipEndDef endDef2,
AtlasAttributeDef... attrDefs) {
return new AtlasRelationshipDef(name, description, version, relationshipCategory, propagateTags,
endDef1, endDef2, Arrays.asList(attrDefs));
}
public static AtlasTypesDef getTypesDef(List<AtlasEnumDef> enums, public static AtlasTypesDef getTypesDef(List<AtlasEnumDef> enums,
List<AtlasStructDef> structs, List<AtlasStructDef> structs,
List<AtlasClassificationDef> traits, List<AtlasClassificationDef> traits,
......
...@@ -412,11 +412,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ ...@@ -412,11 +412,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
AtlasTypesDef ret = updateGraphStore(typesDef, ttr); AtlasTypesDef ret = updateGraphStore(typesDef, ttr);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("<== AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={})", LOG.debug("<== AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
CollectionUtils.size(typesDef.getEnumDefs()), CollectionUtils.size(typesDef.getEnumDefs()),
CollectionUtils.size(typesDef.getStructDefs()), CollectionUtils.size(typesDef.getStructDefs()),
CollectionUtils.size(typesDef.getClassificationDefs()), CollectionUtils.size(typesDef.getClassificationDefs()),
CollectionUtils.size(typesDef.getEntityDefs())); CollectionUtils.size(typesDef.getEntityDefs()),
CollectionUtils.size(typesDef.getRelationshipDefs()));
} }
return ret; return ret;
...@@ -857,6 +858,7 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ ...@@ -857,6 +858,7 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
AtlasStructDefStore structDefStore = getStructDefStore(ttr); AtlasStructDefStore structDefStore = getStructDefStore(ttr);
AtlasClassificationDefStore classifiDefStore = getClassificationDefStore(ttr); AtlasClassificationDefStore classifiDefStore = getClassificationDefStore(ttr);
AtlasEntityDefStore entityDefStore = getEntityDefStore(ttr); AtlasEntityDefStore entityDefStore = getEntityDefStore(ttr);
AtlasRelationshipDefStore relationDefStore = getRelationshipDefStore(ttr);
if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) { if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
for (AtlasEnumDef enumDef : typesDef.getEnumDefs()) { for (AtlasEnumDef enumDef : typesDef.getEnumDefs()) {
...@@ -882,6 +884,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ ...@@ -882,6 +884,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
} }
} }
if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
ret.getRelationshipDefs().add(relationDefStore.update(relationshipDef));
}
}
return ret; return ret;
} }
......
...@@ -265,6 +265,11 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At ...@@ -265,6 +265,11 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name); throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
} }
// error if we are trying to delete an entityDef that has a relationshipDef
if (typeDefStore.hasIncomingEdgesWithLabel(ret, AtlasGraphUtilsV1.RELATIONSHIPTYPE_EDGE_LABEL)){
throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_RELATIONSHIPS, name);
}
typeDefStore.deleteTypeVertexOutEdges(ret); typeDefStore.deleteTypeVertexOutEdges(ret);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
...@@ -313,6 +318,11 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At ...@@ -313,6 +318,11 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid); throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
} }
// error if we are trying to delete an entityDef that has a relationshipDef
if (typeDefStore.hasIncomingEdgesWithLabel(ret, AtlasGraphUtilsV1.RELATIONSHIPTYPE_EDGE_LABEL)){
throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_RELATIONSHIPS, typeName);
}
typeDefStore.deleteTypeVertexOutEdges(ret); typeDefStore.deleteTypeVertexOutEdges(ret);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
......
...@@ -50,6 +50,7 @@ public class AtlasGraphUtilsV1 { ...@@ -50,6 +50,7 @@ public class AtlasGraphUtilsV1 {
public static final String PROPERTY_PREFIX = Constants.INTERNAL_PROPERTY_KEY_PREFIX + "type."; public static final String PROPERTY_PREFIX = Constants.INTERNAL_PROPERTY_KEY_PREFIX + "type.";
public static final String SUPERTYPE_EDGE_LABEL = PROPERTY_PREFIX + ".supertype"; public static final String SUPERTYPE_EDGE_LABEL = PROPERTY_PREFIX + ".supertype";
public static final String VERTEX_TYPE = "typeSystem"; public static final String VERTEX_TYPE = "typeSystem";
public static final String RELATIONSHIPTYPE_EDGE_LABEL = PROPERTY_PREFIX + ".relationshipType";
public static String getTypeDefPropertyKey(AtlasBaseTypeDef typeDef) { public static String getTypeDefPropertyKey(AtlasBaseTypeDef typeDef) {
...@@ -289,6 +290,22 @@ public class AtlasGraphUtilsV1 { ...@@ -289,6 +290,22 @@ public class AtlasGraphUtilsV1 {
return vertex; return vertex;
} }
public static boolean relationshipTypeHasInstanceEdges(String typeName) throws AtlasBaseException {
AtlasGraphQuery query = AtlasGraphProvider.getGraphInstance()
.query()
.has(Constants.TYPE_NAME_PROPERTY_KEY, AtlasGraphQuery.ComparisionOperator.EQUAL, typeName);
Iterator<AtlasEdge> results = query.edges().iterator();
boolean hasInstanceEdges = results != null && results.hasNext();
if (LOG.isDebugEnabled()) {
LOG.debug("relationshipType {} has instance edges {}", typeName, hasInstanceEdges);
}
return hasInstanceEdges;
}
private static String toString(AtlasElement element) { private static String toString(AtlasElement element) {
if (element instanceof AtlasVertex) { if (element instanceof AtlasVertex) {
return toString((AtlasVertex) element); return toString((AtlasVertex) element);
......
...@@ -17,13 +17,17 @@ ...@@ -17,13 +17,17 @@
*/ */
package org.apache.atlas.repository.store.graph.v1; package org.apache.atlas.repository.store.graph.v1;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.typedef.AtlasRelationshipDef; import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory; import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags; import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasRelationshipEndDef; import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
import org.apache.atlas.query.QueryParser;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasVertex; import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore; import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
import org.apache.atlas.type.AtlasRelationshipType; import org.apache.atlas.type.AtlasRelationshipType;
...@@ -34,6 +38,7 @@ import org.apache.commons.lang.StringUtils; ...@@ -34,6 +38,7 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
...@@ -44,6 +49,7 @@ import java.util.List; ...@@ -44,6 +49,7 @@ import java.util.List;
public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 implements AtlasRelationshipDefStore { public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 implements AtlasRelationshipDefStore {
private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipDefStoreV1.class); private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipDefStoreV1.class);
@Inject
public AtlasRelationshipDefStoreV1(AtlasTypeDefGraphStoreV1 typeDefStore, AtlasTypeRegistry typeRegistry) { public AtlasRelationshipDefStoreV1(AtlasTypeDefGraphStoreV1 typeDefStore, AtlasTypeRegistry typeRegistry) {
super(typeDefStore, typeRegistry); super(typeDefStore, typeRegistry);
} }
...@@ -62,21 +68,51 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme ...@@ -62,21 +68,51 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, relationshipDef.getName(), TypeCategory.RELATIONSHIP.name()); throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, relationshipDef.getName(), TypeCategory.RELATIONSHIP.name());
} }
AtlasVertex ret = typeDefStore.findTypeVertexByName(relationshipDef.getName()); AtlasVertex relationshipDefVertex = typeDefStore.findTypeVertexByName(relationshipDef.getName());
if (ret != null) { if (relationshipDefVertex != null) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_ALREADY_EXISTS, relationshipDef.getName()); throw new AtlasBaseException(AtlasErrorCode.TYPE_ALREADY_EXISTS, relationshipDef.getName());
} }
ret = typeDefStore.createTypeVertex(relationshipDef); relationshipDefVertex = typeDefStore.createTypeVertex(relationshipDef);
updateVertexPreCreate(relationshipDef, (AtlasRelationshipType) type, ret); updateVertexPreCreate(relationshipDef, (AtlasRelationshipType) type, relationshipDefVertex);
if (LOG.isDebugEnabled()) { final AtlasRelationshipEndDef endDef1 = relationshipDef.getEndDef1();
LOG.debug("<== AtlasRelationshipDefStoreV1.preCreate({}): {}", relationshipDef, ret); final String type1 = endDef1.getType();
final AtlasRelationshipEndDef endDef2 = relationshipDef.getEndDef2();
final String type2 = endDef2.getType();
final String name1 = endDef1.getName();
final String name2 = endDef2.getName();
AtlasVertex end1TypeVertex = typeDefStore.findTypeVertexByName(type1);
AtlasVertex end2TypeVertex = typeDefStore.findTypeVertexByName(type2);
// create an edge between the relationshipDef and each of the entityDef vertices.
AtlasEdge edge1 = typeDefStore.getOrCreateEdge(relationshipDefVertex, end1TypeVertex, AtlasGraphUtilsV1.RELATIONSHIPTYPE_EDGE_LABEL);
/*
Where edge1 and edge2 have the same names and types we do not need a second edge.
We are not invoking the equals method on the AtlasRelationshipedDef, as we only want 1 edge even if propagateTags or other properties are different.
*/
if (!type1.equals(type2) && name1.equals(name2)) {
AtlasEdge edge2 = typeDefStore.getOrCreateEdge(relationshipDefVertex, end2TypeVertex, AtlasGraphUtilsV1.RELATIONSHIPTYPE_EDGE_LABEL);
if (LOG.isDebugEnabled()) {
LOG.debug("AtlasRelationshipDefStoreV1.preCreate({}): created relationshipDef vertex {}," +
" edge1 as {}, edge2 as {} ", relationshipDef, relationshipDefVertex, edge1, edge2);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("AtlasRelationshipDefStoreV1.preCreate({}): created relationshipDef vertex {}," +
" and one edge as {} , because end1 and and end2 has same type and name", relationshipDef, relationshipDefVertex, edge1);
}
} }
return ret; LOG.debug("<== AtlasRelationshipDefStoreV1.preCreate({}): {}", relationshipDef, relationshipDefVertex);
return relationshipDefVertex;
} }
@Override @Override
...@@ -207,7 +243,7 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme ...@@ -207,7 +243,7 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name); throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
} }
updateVertexPreUpdate(relationshipDef, (AtlasRelationshipType) type, vertex); preUpdateCheck(relationshipDef, (AtlasRelationshipType) type, vertex);
AtlasRelationshipDef ret = toRelationshipDef(vertex); AtlasRelationshipDef ret = toRelationshipDef(vertex);
...@@ -239,8 +275,9 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme ...@@ -239,8 +275,9 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid); throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
} }
updateVertexPreUpdate(relationshipDef, (AtlasRelationshipType) type, vertex); preUpdateCheck(relationshipDef, (AtlasRelationshipType) type, vertex);
// TODO delete / create edges to entitytypes // updates should not effect the edges between the types as we do not allow updates that change the endpoints.
AtlasRelationshipDef ret = toRelationshipDef(vertex); AtlasRelationshipDef ret = toRelationshipDef(vertex);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
...@@ -262,11 +299,11 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme ...@@ -262,11 +299,11 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name); throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
} }
if (AtlasGraphUtilsV1.typeHasInstanceVertex(name)) { if (AtlasGraphUtilsV1.relationshipTypeHasInstanceEdges(name)) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, name); throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, name);
} }
// TODO delete the edges to the other types typeDefStore.deleteTypeVertexOutEdges(ret);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("<== AtlasRelationshipDefStoreV1.preDeleteByName({}): {}", name, ret); LOG.debug("<== AtlasRelationshipDefStoreV1.preDeleteByName({}): {}", name, ret);
...@@ -310,11 +347,11 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme ...@@ -310,11 +347,11 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
String typeName = AtlasGraphUtilsV1.getProperty(ret, Constants.TYPENAME_PROPERTY_KEY, String.class); String typeName = AtlasGraphUtilsV1.getProperty(ret, Constants.TYPENAME_PROPERTY_KEY, String.class);
if (AtlasGraphUtilsV1.typeHasInstanceVertex(typeName)) { if (AtlasGraphUtilsV1.relationshipTypeHasInstanceEdges(typeName)) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, typeName); throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, typeName);
} }
// TODO delete the edges to the other types typeDefStore.deleteTypeVertexOutEdges(ret);
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("<== AtlasRelationshipDefStoreV1.preDeleteByGuid({}): {}", guid, ret); LOG.debug("<== AtlasRelationshipDefStoreV1.preDeleteByGuid({}): {}", guid, ret);
...@@ -346,18 +383,91 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme ...@@ -346,18 +383,91 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
private void updateVertexPreCreate(AtlasRelationshipDef relationshipDef, AtlasRelationshipType relationshipType, private void updateVertexPreCreate(AtlasRelationshipDef relationshipDef, AtlasRelationshipType relationshipType,
AtlasVertex vertex) throws AtlasBaseException { AtlasVertex vertex) throws AtlasBaseException {
AtlasRelationshipEndDef end1 = relationshipDef.getEndDef1();
AtlasRelationshipEndDef end2 = relationshipDef.getEndDef2();
// check whether the names added on the relationship Ends are reserved if required.
final boolean allowReservedKeywords;
try {
allowReservedKeywords = ApplicationProperties.get().getBoolean(ALLOW_RESERVED_KEYWORDS, true);
} catch (AtlasException e) {
throw new AtlasBaseException(e);
}
if (!allowReservedKeywords) {
if (QueryParser.isKeyword(end1.getName())) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_END1_NAME_INVALID, end1.getName());
}
if (QueryParser.isKeyword(end2.getName())) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_END2_NAME_INVALID, end2.getName());
}
}
AtlasStructDefStoreV1.updateVertexPreCreate(relationshipDef, relationshipType, vertex, typeDefStore); AtlasStructDefStoreV1.updateVertexPreCreate(relationshipDef, relationshipType, vertex, typeDefStore);
// Update ends // Update ends
vertex.setProperty(Constants.RELATIONSHIPTYPE_END1_KEY, AtlasType.toJson(relationshipDef.getEndDef1())); setVertexPropertiesFromRelationshipDef(relationshipDef, vertex);
vertex.setProperty(Constants.RELATIONSHIPTYPE_END2_KEY, AtlasType.toJson(relationshipDef.getEndDef2()));
// Update RelationshipCategory
vertex.setProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, relationshipDef.getRelationshipCategory().name());
vertex.setProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, relationshipDef.getPropagateTags().name());
} }
private void updateVertexPreUpdate(AtlasRelationshipDef relationshipDef, AtlasRelationshipType relationshipType, private void preUpdateCheck(AtlasRelationshipDef newRelationshipDef, AtlasRelationshipType relationshipType,
AtlasVertex vertex) throws AtlasBaseException { AtlasVertex vertex) throws AtlasBaseException {
AtlasStructDefStoreV1.updateVertexPreUpdate(relationshipDef, relationshipType, vertex, typeDefStore); // We will not support an update to endpoints or category key
AtlasRelationshipDef existingRelationshipDef = toRelationshipDef(vertex);
preUpdateCheck(newRelationshipDef, existingRelationshipDef);
// we do allow change to tag propagation and the addition of new attributes.
AtlasStructDefStoreV1.updateVertexPreUpdate(newRelationshipDef, relationshipType, vertex, typeDefStore);
setVertexPropertiesFromRelationshipDef(newRelationshipDef, vertex);
}
/**
* Check ends are the same and relationshipCategory is the same.
*
* We do this by comparing 2 relationshipDefs to avoid exposing the AtlasVertex to unit testing.
*
* @param newRelationshipDef
* @param existingRelationshipDef
* @throws AtlasBaseException
*/
public static void preUpdateCheck(AtlasRelationshipDef newRelationshipDef, AtlasRelationshipDef existingRelationshipDef) throws AtlasBaseException {
// do not allow renames of the Def.
String existingName = existingRelationshipDef.getName();
String newName = newRelationshipDef.getName();
if (!existingName.equals(newName)) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_INVALID_NAME_UPDATE,
newRelationshipDef.getGuid(),existingName, newName);
}
RelationshipCategory existingRelationshipCategory = existingRelationshipDef.getRelationshipCategory();
RelationshipCategory newRelationshipCategory = newRelationshipDef.getRelationshipCategory();
if ( !existingRelationshipCategory.equals(newRelationshipCategory)){
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_INVALID_CATEGORY_UPDATE,
newRelationshipDef.getName(),newRelationshipCategory.name(),
existingRelationshipCategory.name() );
}
AtlasRelationshipEndDef existingEnd1 = existingRelationshipDef.getEndDef1();
AtlasRelationshipEndDef newEnd1 = newRelationshipDef.getEndDef1();
if ( !newEnd1.equals(existingEnd1) ) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END1_UPDATE,
newRelationshipDef.getName(), newEnd1.toString(), existingEnd1.toString());
}
AtlasRelationshipEndDef existingEnd2 = existingRelationshipDef.getEndDef2();
AtlasRelationshipEndDef newEnd2 = newRelationshipDef.getEndDef2();
if ( !newEnd2.equals(existingEnd2) ) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END2_UPDATE,
newRelationshipDef.getName(), newEnd2.toString(), existingEnd2.toString());
}
}
public static void setVertexPropertiesFromRelationshipDef(AtlasRelationshipDef relationshipDef, AtlasVertex vertex) {
vertex.setProperty(Constants.RELATIONSHIPTYPE_END1_KEY, AtlasType.toJson(relationshipDef.getEndDef1())); vertex.setProperty(Constants.RELATIONSHIPTYPE_END1_KEY, AtlasType.toJson(relationshipDef.getEndDef1()));
vertex.setProperty(Constants.RELATIONSHIPTYPE_END2_KEY, AtlasType.toJson(relationshipDef.getEndDef2())); vertex.setProperty(Constants.RELATIONSHIPTYPE_END2_KEY, AtlasType.toJson(relationshipDef.getEndDef2()));
// Update RelationshipCategory // Update RelationshipCategory
......
...@@ -242,6 +242,28 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore { ...@@ -242,6 +242,28 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
} }
} }
/**
* Look to see if there are any IN edges with the supplied label
* @param vertex
* @param label
* @return
* @throws AtlasBaseException
*/
boolean hasIncomingEdgesWithLabel(AtlasVertex vertex, String label) throws AtlasBaseException {
boolean foundEdges = false;
Iterator<AtlasEdge> inEdges = vertex.getEdges(AtlasEdgeDirection.IN).iterator();
while (inEdges.hasNext()) {
AtlasEdge edge = inEdges.next();
if (label.equals(edge.getLabel())) {
foundEdges = true;
break;
}
}
return foundEdges;
}
void deleteTypeVertex(AtlasVertex vertex) throws AtlasBaseException { void deleteTypeVertex(AtlasVertex vertex) throws AtlasBaseException {
Iterator<AtlasEdge> inEdges = vertex.getEdges(AtlasEdgeDirection.IN).iterator(); Iterator<AtlasEdge> inEdges = vertex.getEdges(AtlasEdgeDirection.IN).iterator();
......
...@@ -47,16 +47,9 @@ import org.apache.atlas.repository.graphdb.AtlasGraph; ...@@ -47,16 +47,9 @@ import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.impexp.ExportService; import org.apache.atlas.repository.impexp.ExportService;
import org.apache.atlas.repository.store.graph.AtlasEntityDefStore; import org.apache.atlas.repository.store.graph.AtlasEntityDefStore;
import org.apache.atlas.repository.store.graph.AtlasEntityStore; import org.apache.atlas.repository.store.graph.AtlasEntityStore;
import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
import org.apache.atlas.repository.store.graph.AtlasRelationshipStore; import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
import org.apache.atlas.repository.store.graph.v1.AtlasEntityChangeNotifier; import org.apache.atlas.repository.store.graph.v1.*;
import org.apache.atlas.repository.store.graph.v1.AtlasEntityDefStoreV1;
import org.apache.atlas.repository.store.graph.v1.AtlasEntityStoreV1;
import org.apache.atlas.repository.store.graph.v1.AtlasRelationshipStoreV1;
import org.apache.atlas.repository.store.graph.v1.AtlasTypeDefGraphStoreV1;
import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
import org.apache.atlas.repository.store.graph.v1.EntityGraphMapper;
import org.apache.atlas.repository.store.graph.v1.HardDeleteHandlerV1;
import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
import org.apache.atlas.repository.typestore.GraphBackedTypeStore; import org.apache.atlas.repository.typestore.GraphBackedTypeStore;
import org.apache.atlas.repository.typestore.ITypeStore; import org.apache.atlas.repository.typestore.ITypeStore;
import org.apache.atlas.repository.typestore.StoreBackedTypeCache; import org.apache.atlas.repository.typestore.StoreBackedTypeCache;
...@@ -136,6 +129,7 @@ public class TestModules { ...@@ -136,6 +129,7 @@ public class TestModules {
//For testing //For testing
bind(AtlasEntityDefStore.class).to(AtlasEntityDefStoreV1.class).asEagerSingleton(); bind(AtlasEntityDefStore.class).to(AtlasEntityDefStoreV1.class).asEagerSingleton();
bind(AtlasRelationshipDefStore.class).to(AtlasRelationshipDefStoreV1.class).asEagerSingleton();
bind(AtlasTypeRegistry.class).asEagerSingleton(); bind(AtlasTypeRegistry.class).asEagerSingleton();
bind(EntityGraphMapper.class).asEagerSingleton(); bind(EntityGraphMapper.class).asEagerSingleton();
bind(ExportService.class).asEagerSingleton(); bind(ExportService.class).asEagerSingleton();
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.repository.store.graph;
import com.google.inject.Inject;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException;
import org.apache.atlas.TestModules;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.repository.graph.AtlasGraphProvider;
import org.apache.atlas.repository.store.graph.v1.AtlasAbstractDefStoreV1;
import org.apache.atlas.repository.store.graph.v1.AtlasRelationshipDefStoreV1;
import org.apache.atlas.type.AtlasTypeUtil;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.fail;
/**
* Tests for AtlasRelationshipStoreV1
*/
@Guice(modules = TestModules.TestOnlyModule.class)
public class AtlasRelationshipDefStoreV1Test {
@Inject
private
AtlasRelationshipDefStore relationshipDefStore;
@DataProvider
public Object[][] invalidAttributeNameWithReservedKeywords(){
AtlasRelationshipDef invalidAttrNameType =
AtlasTypeUtil.createRelationshipTypeDef("Invalid_Attribute_Type", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeB", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("order", "string"),
AtlasTypeUtil.createRequiredAttrDef("limit", "string"));
return new Object[][] {{
invalidAttrNameType
}};
}
@DataProvider
public Object[][] updateValidProperties(){
AtlasRelationshipDef existingType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","0" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.ONE_TO_TWO,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef newType =
AtlasTypeUtil.createRelationshipTypeDef("basicType",
"description1", // updated
"1" , // updated
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH, // updated
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
return new Object[][] {{
existingType,
newType
}};
}
@DataProvider
public Object[][] updateRename(){
AtlasRelationshipDef existingType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef newType =
AtlasTypeUtil.createRelationshipTypeDef("basicType2", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
return new Object[][] {{
existingType,
newType
}};
}
@DataProvider
public Object[][] updateRelCat(){
AtlasRelationshipDef existingType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef newType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.AGGREGATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
return new Object[][] {{
existingType,
newType
}};
}
@DataProvider
public Object[][] updateEnd1(){
AtlasRelationshipDef existingType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef changeType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeE", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef changeAttr =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef changeCardinality =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
return new Object[][]{
{
existingType,
changeType
},
{
existingType,
changeAttr
},
{
existingType,
changeCardinality
}
};
}
@DataProvider
public Object[][] updateEnd2(){
AtlasRelationshipDef existingType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef changeType =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeE", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef changeAttr =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
AtlasRelationshipDef changeCardinality =
AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
AtlasRelationshipDef.PropagateTags.BOTH,
new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST),
AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
return new Object[][]{
{
existingType,
changeType
},
{
existingType,
changeAttr
},
{
existingType,
changeCardinality
}
};
}
@Test(dataProvider = "invalidAttributeNameWithReservedKeywords")
public void testCreateTypeWithReservedKeywords(AtlasRelationshipDef atlasRelationshipDef) throws AtlasException {
try {
ApplicationProperties.get().setProperty(AtlasAbstractDefStoreV1.ALLOW_RESERVED_KEYWORDS, false);
relationshipDefStore.create(atlasRelationshipDef, null);
} catch (AtlasBaseException e) {
Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.ATTRIBUTE_NAME_INVALID);
}
}
@Test(dataProvider = "updateValidProperties")
public void testupdateVertexPreUpdatepropagateTags(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef) throws AtlasBaseException {
AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
}
@Test(dataProvider = "updateRename")
public void testupdateVertexPreUpdateRename(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef) {
try {
AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
fail("expected error");
} catch (AtlasBaseException e) {
if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_NAME_UPDATE)){
fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
}
}
}
@Test(dataProvider = "updateRelCat")
public void testupdateVertexPreUpdateRelcat(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef) {
try {
AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
fail("expected error");
} catch (AtlasBaseException e) {
if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_CATEGORY_UPDATE)){
fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
}
}
}
@Test(dataProvider = "updateEnd1")
public void testupdateVertexPreUpdateEnd1(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef) {
try {
AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
fail("expected error");
} catch (AtlasBaseException e) {
if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END1_UPDATE)){
fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
}
}
}
@Test(dataProvider = "updateEnd2")
public void testupdateVertexPreUpdateEnd2(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef) {
try {
AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
fail("expected error");
} catch (AtlasBaseException e) {
if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END2_UPDATE)){
fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
}
}
}
@AfterClass
public void clear(){
AtlasGraphProvider.cleanup();
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.examples;
import java.io.Console;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasBaseClient;
import org.apache.atlas.AtlasClientV2;
import org.apache.atlas.AtlasException;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.configuration.Configuration;
import com.google.common.annotations.VisibleForTesting;
/**
* A driver that sets up types supplied in a file.
*/
public class CreateTypesFromJsonFileUtil extends AtlasBaseClient{
public static final String ATLAS_REST_ADDRESS = "atlas.rest.address";
public static void main(String[] args) throws Exception {
Console console = System.console();
if (console == null) {
System.err.println("No console.");
System.exit(1);
}
String[] basicAuthUsernamePassword = null;
if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
basicAuthUsernamePassword = AuthenticationUtil.getBasicAuthenticationInput();
}
AtlasClientV2 atlasClientV2 = getAtlasClientV2(args, basicAuthUsernamePassword);
String createFileName = console.readLine("Enter fileName containing TypeDefs for create:- ");
File createFile = new File(createFileName);
String createJsonStr = new String( Files.readAllBytes(createFile.toPath()), StandardCharsets.UTF_8);
System.err.println("create json is :\n" + createJsonStr);
runTypeCreation(createJsonStr,atlasClientV2);
// String updateFileName = console.readLine("Enter fileName containing TypeDefs for update:- ");
// File updateFile = new File(updateFileName);
// String updateJsonStr = new String( Files.readAllBytes(updateFile.toPath()), StandardCharsets.UTF_8);
// System.err.println("update json is :\n" + updateJsonStr);
// runTypeUpdate(updateJsonStr,atlasClientV2);
}
@VisibleForTesting
static void runTypeCreation(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
atlasClientV2.createAtlasTypeDefs(typesDef);
}
@VisibleForTesting
static void runTypeUpdate(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
atlasClientV2.updateAtlasTypeDefs(typesDef);
}
private static AtlasClientV2 getAtlasClientV2(String[] args, String[] basicAuthUsernamePassword) throws AtlasException {
String[] urls = getServerUrl(args);
AtlasClientV2 atlasClientV2;
if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
atlasClientV2 =new AtlasClientV2(urls,basicAuthUsernamePassword);
} else {
atlasClientV2 = new AtlasClientV2(urls);
}
return atlasClientV2;
}
static String[] getServerUrl(String[] args) throws AtlasException {
if (args.length > 0) {
return args[0].split(",");
}
Configuration configuration = ApplicationProperties.get();
String[] urls = configuration.getStringArray(ATLAS_REST_ADDRESS);
if (urls == null || urls.length == 0) {
System.out.println("Usage: quick_start.py <atlas endpoint of format <http/https>://<atlas-fqdn>:<atlas port> like http://localhost:21000>");
System.exit(-1);
}
return urls;
}
}
\ No newline at end of file
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.examples;
import com.google.common.annotations.VisibleForTesting;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasBaseClient;
import org.apache.atlas.AtlasClientV2;
import org.apache.atlas.AtlasException;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.configuration.Configuration;
import java.io.Console;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
/**
* A driver that sets up types supplied in a file.
*/
public class UpdateTypesFromJsonFileUtil extends AtlasBaseClient{
public static final String ATLAS_REST_ADDRESS = "atlas.rest.address";
public static void main(String[] args) throws Exception {
Console console = System.console();
if (console == null) {
System.err.println("No console.");
System.exit(1);
}
String[] basicAuthUsernamePassword = null;
if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
basicAuthUsernamePassword = AuthenticationUtil.getBasicAuthenticationInput();
}
AtlasClientV2 atlasClientV2 = getAtlasClientV2(args, basicAuthUsernamePassword);
String createFileName = console.readLine("Enter fileName containing TypeDefs for create:- ");
File createFile = new File(createFileName);
String createJsonStr = new String( Files.readAllBytes(createFile.toPath()), StandardCharsets.UTF_8);
System.err.println("create json is :\n" + createJsonStr);
runTypeCreation(createJsonStr,atlasClientV2);
// String updateFileName = console.readLine("Enter fileName containing TypeDefs for update:- ");
// File updateFile = new File(updateFileName);
// String updateJsonStr = new String( Files.readAllBytes(updateFile.toPath()), StandardCharsets.UTF_8);
// System.err.println("update json is :\n" + updateJsonStr);
// runTypeUpdate(updateJsonStr,atlasClientV2);
}
@VisibleForTesting
static void runTypeCreation(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
atlasClientV2.createAtlasTypeDefs(typesDef);
}
@VisibleForTesting
static void runTypeUpdate(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
atlasClientV2.updateAtlasTypeDefs(typesDef);
}
private static AtlasClientV2 getAtlasClientV2(String[] args, String[] basicAuthUsernamePassword) throws AtlasException {
String[] urls = getServerUrl(args);
AtlasClientV2 atlasClientV2;
if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
atlasClientV2 =new AtlasClientV2(urls,basicAuthUsernamePassword);
} else {
atlasClientV2 = new AtlasClientV2(urls);
}
return atlasClientV2;
}
static String[] getServerUrl(String[] args) throws AtlasException {
if (args.length > 0) {
return args[0].split(",");
}
Configuration configuration = ApplicationProperties.get();
String[] urls = configuration.getStringArray(ATLAS_REST_ADDRESS);
if (urls == null || urls.length == 0) {
System.out.println("Usage: quick_start.py <atlas endpoint of format <http/https>://<atlas-fqdn>:<atlas port> like http://localhost:21000>");
System.exit(-1);
}
return urls;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment