Commit 6b9399e0 by David Radley Committed by Madhan Neethiraj

ATLAS-1852: create relationship-def

parent e0072e5f
......@@ -57,6 +57,11 @@ public final class Constants {
public static final String TYPEVERSION_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "type.version";
public static final String TYPEOPTIONS_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "type.options";
// relationship def constants
public static final String RELATIONSHIPTYPE_ENDPOINT1_KEY = "endPointDef1";
public static final String RELATIONSHIPTYPE_ENDPOINT2_KEY = "endPointDef2";
public static final String RELATIONSHIPTYPE_CATEGORY_KEY = "relationshipCategory";
public static final String RELATIONSHIPTYPE_TAG_PROPAGATION_KEY = "tagPropagation";
/**
* Trait names property key and index name.
*/
......@@ -92,6 +97,7 @@ public final class Constants {
public static final String QUALIFIED_NAME = "Referenceable.qualifiedName";
public static final String TYPE_NAME_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "typeName";
private Constants() {
}
......
......@@ -71,7 +71,14 @@ public enum AtlasErrorCode {
BAD_REQUEST(400, "ATLAS-400-00-029", "{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"),
RELATIONSHIPDEF_INSUFFICIENT_ENDPOINTS(400, "ATLAS-400-00-02C", "Relationship def {0} creation attempted without 2 end points"),
RELATIONSHIPDEF_DOUBLE_CONTAINERS(400, "ATLAS-400-00-02D", "Relationship def {0} creation attempted with both end points as containers"),
RELATIONSHIPDEF_UNSUPPORTED_ATTRIBUTE_TYPE(400, "ATLAS-400-00-02F", "Cannot set an Attribute with type {0} on relationship def {1}, as it is not a primitive type "),
RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER(400, "ATLAS-400-00-030", "ASSOCIATION relationship def {0} creation attempted with an endpoint specifying isContainer"),
RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER(400, "ATLAS-400-00-031", "COMPOSITION relationship def {0} creation attempted without an endpoint specifying isContainer"),
RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER(400, "ATLAS-400-00-032", "AGGREGATION relationship def {0} creation attempted without an endpoint specifying isContainer"),
RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER(400, "ATLAS-400-00-033", "COMPOSITION relationship def {0} cannot have a SET cardinality and be a container"),
RELATIONSHIPDEF_LIST_ON_ENDPOINT(400, "ATLAS-400-00-034", "relationship def {0} cannot have a LIST cardinality on an endpoint"),
// All Not found enums go here
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"),
......
......@@ -18,5 +18,5 @@
package org.apache.atlas.model;
public enum TypeCategory {
PRIMITIVE, OBJECT_ID_TYPE, ENUM, STRUCT, CLASSIFICATION, ENTITY, ARRAY, MAP
PRIMITIVE, OBJECT_ID_TYPE, ENUM, STRUCT, CLASSIFICATION, ENTITY, ARRAY, MAP, RELATIONSHIP
}
......@@ -91,6 +91,22 @@ public abstract class AtlasBaseTypeDef implements java.io.Serializable {
ATLAS_TYPE_BIGDECIMAL,
ATLAS_TYPE_STRING,
};
/**
* The list of types that are valid for relationships. These are the
* primitive attributes and date.
*/
public static final String[] ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES = { ATLAS_TYPE_BOOLEAN,
ATLAS_TYPE_BYTE,
ATLAS_TYPE_SHORT,
ATLAS_TYPE_INT,
ATLAS_TYPE_LONG,
ATLAS_TYPE_FLOAT,
ATLAS_TYPE_DOUBLE,
ATLAS_TYPE_BIGINTEGER,
ATLAS_TYPE_BIGDECIMAL,
ATLAS_TYPE_STRING,
ATLAS_TYPE_DATE
};
public static final String[] ATLAS_BUILTIN_TYPES = {
ATLAS_TYPE_BOOLEAN,
......
/**
* 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.model.typedef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.util.Objects;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
/**
* The relationshipEndPointsDef represents an end of the relationship. The end of the relationship is defined by a type, an
* attribute name, cardinality and whether it is the container end of the relationship.
*/
@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class AtlasRelationshipEndPointDef implements Serializable {
private static final long serialVersionUID = 1L;
/**
* The type associated with the endpoint.
*/
private String type;
/**
* The name of the attribute for this endpoint
*/
private String name;
/**
* When set this indicates that this end is the container end
*/
private boolean isContainer;
/**
* This is the cardinality of the end point
*/
private Cardinality cardinality;
/**
* Base constructor
*/
public AtlasRelationshipEndPointDef() {
this(null, null, Cardinality.SINGLE, false);
}
/**
*
* @param typeName
* - The name of an entityDef type
* @param name
* - The name of the new attribute that the entity instance will pick up.
* @param cardinality
* - this indicates whether the end point is SINGLE (1) or SET (many)
*/
public AtlasRelationshipEndPointDef(String typeName, String name, Cardinality cardinality) {
this(typeName, name, cardinality, false);
}
/**
*
* @param typeName
* - The name of an entityDef type
* @param name
* - The name of the new attribute that the entity instance will pick up.
* @param cardinality
* - whether the end point is SINGLE (1) or SET (many)
* @param isContainer
* - whether the end point is a container or not
*/
public AtlasRelationshipEndPointDef(String typeName, String name, Cardinality cardinality, boolean isContainer) {
setType(typeName);
setName(name);
setCardinality(cardinality);
setIsContainer(isContainer);
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
/**
* set whether this endpoint is a container or not.
* @param isContainer
*/
public void setIsContainer(boolean isContainer) {
this.isContainer = isContainer;
}
public boolean getIsContainer() {
return isContainer;
}
/**
* set the cardinality SINGLE or SET on the endpoint.
* @param cardinality
*/
public void setCardinality(AtlasStructDef.AtlasAttributeDef.Cardinality cardinality) {
this.cardinality = cardinality;
}
/**
*
* @return the cardinality
*/
public Cardinality getCardinality() {
return this.cardinality;
}
/**
* Construct using an existing AtlasRelationshipEndPointDef
* @param other
*/
public AtlasRelationshipEndPointDef(AtlasRelationshipEndPointDef other) {
if (other != null) {
setType(other.getType());
setName(other.getName());
setIsContainer(other.getIsContainer());
setCardinality(other.getCardinality());
}
}
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append("AtlasRelationshipEndPointsDef{");
sb.append("type='").append(type).append('\'');
sb.append(", name==>'").append(name).append('\'');
sb.append(", isContainer==>'").append(isContainer).append('\'');
sb.append(", cardinality==>'").append(cardinality).append('\'');
sb.append('}');
return sb;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
AtlasRelationshipEndPointDef that = (AtlasRelationshipEndPointDef) o;
return Objects.equals(type, that.type) && Objects.equals(name, that.name)
&& (isContainer == that.isContainer) && (cardinality == that.cardinality);
}
@Override
public int hashCode() {
return Objects.hash(type, getName(), isContainer, cardinality);
}
@Override
public String toString() {
return toString(new StringBuilder()).toString();
}
}
......@@ -17,11 +17,8 @@
*/
package org.apache.atlas.model.typedef;
import org.apache.commons.collections.CollectionUtils;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
import java.util.ArrayList;
import java.util.Collection;
......@@ -31,8 +28,11 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
import org.apache.commons.collections.CollectionUtils;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
......@@ -44,29 +44,50 @@ public class AtlasTypesDef {
private List<AtlasStructDef> structDefs;
private List<AtlasClassificationDef> classificationDefs;
private List<AtlasEntityDef> entityDefs;
private List<AtlasRelationshipDef> relationshipDefs;
public AtlasTypesDef() {
enumDefs = new ArrayList<>();
structDefs = new ArrayList<>();
classificationDefs = new ArrayList<>();
entityDefs = new ArrayList<>();
}
relationshipDefs = new ArrayList<>();
}
/**
* tolerate typeDef creations that do not contain relationshipDefs, so that
* the older calls will still work.
* @param enumDefs
* @param structDefs
* @param classificationDefs
* @param entityDefs
*/
public AtlasTypesDef(List<AtlasEnumDef> enumDefs, List<AtlasStructDef> structDefs,
List<AtlasClassificationDef> classificationDefs, List<AtlasEntityDef> entityDefs) {
this(enumDefs, structDefs, classificationDefs, entityDefs,new ArrayList<AtlasRelationshipDef>());
}
/**
* Create the TypesDef. This created definitions for each of the types.
* @param enumDefs
* @param structDefs
* @param classificationDefs
* @param entityDefs
* @param relationshipDefs
*/
public AtlasTypesDef(List<AtlasEnumDef> enumDefs,
List<AtlasStructDef> structDefs,
List<AtlasClassificationDef> classificationDefs,
List<AtlasEntityDef> entityDefs) {
List<AtlasEntityDef> entityDefs,
List<AtlasRelationshipDef> relationshipDefs) {
this.enumDefs = enumDefs;
this.structDefs = structDefs;
this.classificationDefs = classificationDefs;
this.entityDefs = entityDefs;
this.relationshipDefs = relationshipDefs;
}
public List<AtlasEnumDef> getEnumDefs() {
return enumDefs;
}
public void setEnumDefs(List<AtlasEnumDef> enumDefs) {
this.enumDefs = enumDefs;
}
......@@ -94,7 +115,13 @@ public class AtlasTypesDef {
public void setClassificationDefs(List<AtlasClassificationDef> classificationDefs) {
this.classificationDefs = classificationDefs;
}
public List<AtlasRelationshipDef> getRelationshipDefs() {
return relationshipDefs;
}
public void setRelationshipDefs(List<AtlasRelationshipDef> relationshipDefs) {
this.relationshipDefs = relationshipDefs;
}
public boolean hasClassificationDef(String name) {
return hasTypeDef(classificationDefs, name);
......@@ -111,6 +138,9 @@ public class AtlasTypesDef {
public boolean hasEntityDef(String name) {
return hasTypeDef(entityDefs, name);
}
public boolean hasRelationshipDef(String name) {
return hasTypeDef(relationshipDefs, name);
}
private <T extends AtlasBaseTypeDef> boolean hasTypeDef(Collection<T> typeDefs, String name) {
......@@ -130,7 +160,8 @@ public class AtlasTypesDef {
return CollectionUtils.isEmpty(enumDefs) &&
CollectionUtils.isEmpty(structDefs) &&
CollectionUtils.isEmpty(classificationDefs) &&
CollectionUtils.isEmpty(entityDefs);
CollectionUtils.isEmpty(entityDefs) &&
CollectionUtils.isEmpty(relationshipDefs);
}
public void clear() {
......@@ -149,8 +180,10 @@ public class AtlasTypesDef {
if (entityDefs != null) {
entityDefs.clear();
}
if (relationshipDefs != null) {
relationshipDefs.clear();
}
}
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
......@@ -169,6 +202,9 @@ public class AtlasTypesDef {
sb.append("entityDefs={");
AtlasBaseTypeDef.dumpObjects(entityDefs, sb);
sb.append("}");
sb.append("relationshipDefs={");
AtlasBaseTypeDef.dumpObjects(relationshipDefs, sb);
sb.append("}");
return sb;
}
......
......@@ -24,6 +24,7 @@ import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef.AtlasClassificationDefs;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasTypesDef;
......@@ -76,6 +77,15 @@ public interface AtlasTypeDefStore {
AtlasEntityDef updateEntityDefByName(String name, AtlasEntityDef entityDef) throws AtlasBaseException;
AtlasEntityDef updateEntityDefByGuid(String guid, AtlasEntityDef entityDef) throws AtlasBaseException;
/* RelationshipDef operations */
AtlasRelationshipDef getRelationshipDefByName(String name) throws AtlasBaseException;
AtlasRelationshipDef getRelationshipDefByGuid(String guid) throws AtlasBaseException;
AtlasRelationshipDef updateRelationshipDefByName(String name, AtlasRelationshipDef structDef) throws AtlasBaseException;
AtlasRelationshipDef updateRelationshipDefByGuid(String guid, AtlasRelationshipDef structDef) throws AtlasBaseException;
/* Bulk Operations */
......
/**
* 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.type;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* class that implements behaviour of an relationship-type.
*/
public class AtlasRelationshipType extends AtlasStructType {
private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipType.class);
private final AtlasRelationshipDef relationshipDef;
public AtlasRelationshipType(AtlasRelationshipDef relationshipDef) {
super(relationshipDef);
this.relationshipDef = relationshipDef;
}
public AtlasRelationshipType(AtlasRelationshipDef relationshipDef, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
super(relationshipDef);
this.relationshipDef = relationshipDef;
resolveReferences(typeRegistry);
}
public AtlasRelationshipDef getRelationshipDef() { return relationshipDef; }
@Override
public void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
super.resolveReferences(typeRegistry);
validateAtlasRelationshipDef(this.relationshipDef);
}
@Override
public boolean isValidValue(Object obj) {
boolean ret = true;
if (obj != null) {
validateAtlasRelationshipType((AtlasRelationshipType) obj);
ret = super.isValidValue(obj);
}
return ret;
}
@Override
public boolean isValidValueForUpdate(Object obj) {
boolean ret = true;
if (obj != null) {
validateAtlasRelationshipType((AtlasRelationshipType) obj);
ret = super.isValidValueForUpdate(obj);
}
return ret;
}
/**
* Validate the fields in the the RelationshipType are consistent with respect to themselves.
* @param type
* @throws AtlasBaseException
*/
private boolean validateAtlasRelationshipType(AtlasRelationshipType type) {
boolean isValid = false;
try {
validateAtlasRelationshipDef(type.getRelationshipDef());
isValid = true;
} catch (AtlasBaseException abe) {
LOG.error("Validation error for AtlasRelationshipType", abe);
}
return isValid;
}
/**
* Throw an exception so we can junit easily.
* @param relationshipDef
* @throws AtlasBaseException
*/
public static void validateAtlasRelationshipDef(AtlasRelationshipDef relationshipDef) throws AtlasBaseException {
AtlasRelationshipEndPointDef endPointDef1 = relationshipDef.getEndPointDef1();
AtlasRelationshipEndPointDef endPointDef2 = relationshipDef.getEndPointDef2();
boolean isContainer1 = endPointDef1.getIsContainer();
boolean isContainer2 = endPointDef2.getIsContainer();
RelationshipCategory relationshipCategory = relationshipDef.getRelationshipCategory();
String name = relationshipDef.getName();
if (isContainer1 && isContainer2) {
// we support 0 or 1 of these flags.
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_DOUBLE_CONTAINERS, name);
}
if ((isContainer1 || isContainer2)) {
// we have an isContainer defined in an endpoint
if (relationshipCategory == RelationshipCategory.ASSOCIATION) {
// associations are not containment relaitonships - so do not allow an endpoiint with isContainer
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER, name);
}
} else {
// we do not have an isContainer defined in an endpoint
if (relationshipCategory == RelationshipCategory.COMPOSITION) {
// COMPOSITION needs one endpoint to be the container.
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER, name);
} else if (relationshipCategory == RelationshipCategory.AGGREGATION) {
// AGGREGATION needs one endpoint to be the container.
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER, name);
}
}
if (relationshipCategory == RelationshipCategory.COMPOSITION) {
// composition containers should not be multiple cardinality
if (endPointDef1 != null &&
endPointDef1.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
endPointDef1.getIsContainer()) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER, name);
}
if (endPointDef2 != null && endPointDef2 != null &&
endPointDef2.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
endPointDef2.getIsContainer()) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER, name);
}
}
if ((endPointDef1 != null && endPointDef1.getCardinality() == AtlasAttributeDef.Cardinality.LIST) ||
(endPointDef2 != null && endPointDef2.getCardinality() == AtlasAttributeDef.Cardinality.LIST)) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT, name);
}
}
}
\ No newline at end of file
......@@ -18,47 +18,23 @@
package org.apache.atlas.type;
import com.google.common.collect.ImmutableSet;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
import org.apache.atlas.model.typedef.*;
import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_PREFIX;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_SUFFIX;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_KEY_VAL_SEP;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_PREFIX;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_SUFFIX;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.*;
/**
* Utility methods for AtlasType/AtlasTypeDef.
......@@ -294,6 +270,11 @@ public class AtlasTypeUtil {
headerList.add(new AtlasTypeDefHeader(entityDef));
}
}
if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
headerList.add(new AtlasTypeDefHeader(relationshipDef));
}
}
return headerList;
}
......@@ -390,6 +371,10 @@ public class AtlasTypeUtil {
sb.append("entityDefs=[");
dumpTypeNames(typesDef.getEntityDefs(), sb);
sb.append("]");
sb.append("relationshipDefs=[");
dumpTypeNames(typesDef.getRelationshipDefs(), sb);
sb.append("]");
}
sb.append("}");
......
......@@ -21,12 +21,8 @@ import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasStruct;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
import org.apache.atlas.model.typedef.*;
import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
......@@ -43,6 +39,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_BUILTIN_TYPES;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_PRIMITIVE_TYPES;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES;
public final class ModelTestUtil {
......@@ -441,6 +438,67 @@ public final class ModelTestUtil {
return ret;
}
/**
* Valid types for attributes in relationships. This has good coverage of all attribute type and includes enums
* maps and arrays.
* This test does not use getRandomBuiltInType() style - so that it is deterministic.
*
* It does cover very nested maps / arrays.
* @param attrNamePrefix
* @return
*/
public static List<AtlasAttributeDef> newAttributeDefsWithAllBuiltInTypesForRelationship(String attrNamePrefix) {
List<AtlasAttributeDef> ret = new ArrayList<>();
// add enum types
ret.add(getAttributeDef(attrNamePrefix, ENUM_DEF.getName()));
ret.add(getAttributeDef(attrNamePrefix, ENUM_DEF_WITH_NO_DEFAULT.getName()));
// add array of enum types
ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(ENUM_DEF.getName())));
ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(ENUM_DEF_WITH_NO_DEFAULT.getName())));
for (String attributeType : ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES) {
// simple attributes
ret.add(getAttributeDef(attrNamePrefix, attributeType));
// array
ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(attributeType)));
// map types with enum as key
ret.add(getAttributeDef(attrNamePrefix,
AtlasBaseTypeDef.getMapTypeName(ENUM_DEF.getName(), attributeType)));
// map types with enum as key no default
ret.add(getAttributeDef(attrNamePrefix,
AtlasBaseTypeDef.getMapTypeName(ENUM_DEF_WITH_NO_DEFAULT.getName(), attributeType)));
// map types attribute as key enum no default as value
ret.add(getAttributeDef(attrNamePrefix,
AtlasBaseTypeDef.getMapTypeName(attributeType, ENUM_DEF_WITH_NO_DEFAULT.getName())));
// map types with enum as value
ret.add(getAttributeDef(attrNamePrefix,
AtlasBaseTypeDef.getMapTypeName(attributeType, ENUM_DEF.getName())));
for (String attributeType2 : ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES) {
// add map types
ret.add(getAttributeDef(attrNamePrefix,
AtlasBaseTypeDef.getMapTypeName(attributeType, attributeType2)));
// add array of arrays
ret.add(getAttributeDef(attrNamePrefix,
AtlasBaseTypeDef.getArrayTypeName(AtlasBaseTypeDef.getArrayTypeName(attributeType2))));
// add array of maps
ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(
AtlasBaseTypeDef.getMapTypeName(attributeType, attributeType2))));
// add map of arrays
ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getMapTypeName(attributeType,
AtlasBaseTypeDef.getArrayTypeName(attributeType2))));
// add map of maps
ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getMapTypeName(attributeType,
AtlasBaseTypeDef.getMapTypeName(attributeType, attributeType2))));
}
}
return ret;
}
public static String getDefaultAttributeName(String attrType) {
return PREFIX_ATTRIBUTE_NAME + attrType;
}
......
/**
* 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.model.typedef;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.ModelTestUtil;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
import org.apache.atlas.type.AtlasType;
import org.testng.annotations.Test;
import java.util.List;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
public class TestAtlasRelationshipDef {
private static final String PREFIX_ATTRIBUTE_NAME = "reltests-";
private List<AtlasStructDef.AtlasAttributeDef> attributeDefs;
@Test
public void testRelationshipDefSerDeEmpty() throws AtlasBaseException {
AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
String jsonString = AtlasType.toJson(relationshipDef);
System.out.println(jsonString);
assertNotNull(jsonString);
AtlasRelationshipDef relationshipDef2 = AtlasType.fromJson(jsonString, AtlasRelationshipDef.class);
String jsonString2 = AtlasType.toJson(relationshipDef2);
assertEquals(jsonString, jsonString2);
assertEquals(relationshipDef2, relationshipDef,
"Incorrect serialization/deserialization of AtlasRelationshipDef");
}
@Test
public void testRelationshipDefSerDeAttributes() throws AtlasBaseException {
AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
relationshipDef.setAttributeDefs(
ModelTestUtil.newAttributeDefsWithAllBuiltInTypesForRelationship(PREFIX_ATTRIBUTE_NAME));
String jsonString = AtlasType.toJson(relationshipDef);
assertNotNull(jsonString);
AtlasRelationshipDef relationshipDef2 = AtlasType.fromJson(jsonString, AtlasRelationshipDef.class);
String jsonString2 = AtlasType.toJson(relationshipDef2);
assertEquals(jsonString, jsonString2);
assertEquals(relationshipDef2, relationshipDef,
"Incorrect serialization/deserialization of AtlasRelationshipDef");
}
@Test
public void testRelationshipEquals() throws AtlasBaseException {
AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
List<AtlasStructDef.AtlasAttributeDef> attributeDefs = ModelTestUtil.newAttributeDefsWithAllBuiltInTypesForRelationship(PREFIX_ATTRIBUTE_NAME);
relationshipDef1.setAttributeDefs(attributeDefs);
AtlasRelationshipDef relationshipDef2 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
relationshipDef2.setAttributeDefs(attributeDefs);
assertEquals(relationshipDef1,relationshipDef2);
AtlasRelationshipDef relationshipDef3 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
assertNotEquals(relationshipDef1,relationshipDef3);
}
}
\ 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.type;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.fail;
public class TestAtlasRelationshipType {
@Test
public void testvalidateAtlasRelationshipDef() throws AtlasBaseException {
AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
AtlasRelationshipEndPointDef ep3 = new AtlasRelationshipEndPointDef("typeC", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
AtlasRelationshipEndPointDef ep4 = new AtlasRelationshipEndPointDef("typeD", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
AtlasRelationshipEndPointDef ep5 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SET,true);
AtlasRelationshipEndPointDef ep6 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST,true);
AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
AtlasRelationshipDef relationshipDef2 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep3);
AtlasRelationshipDef relationshipDef3 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.AGGREGATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep3);
try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep3, ep2);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail");
} catch (AtlasBaseException abe) {
if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER)) {
fail("This call expected a different error");
}
}
try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail");
} catch (AtlasBaseException abe) {
if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER)) {
fail("This call expected a different error");
}
}
try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.AGGREGATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail");
} catch (AtlasBaseException abe) {
if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER)) {
fail("This call expected a different error");
}
}
try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep5);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail");
} catch (AtlasBaseException abe) {
if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER)) {
fail("This call expected a different error");
}
}
try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep6);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail");
} catch (AtlasBaseException abe) {
if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT)) {
fail("This call expected a different error");
}
}
try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep6, ep1);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail");
} catch (AtlasBaseException abe) {
if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT)) {
fail("This call expected a different error");
}
}
}
}
/**
* 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 java.util.List;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
/**
* Interface for graph persistence store for AtlasRelationshipDef
*/
public interface AtlasRelationshipDefStore {
Object preCreate(AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
AtlasRelationshipDef create(AtlasRelationshipDef relationshipDef, Object preCreateResult) throws AtlasBaseException;
List<AtlasRelationshipDef> getAll() throws AtlasBaseException;
AtlasRelationshipDef getByName(String name) throws AtlasBaseException;
AtlasRelationshipDef getByGuid(String guid) throws AtlasBaseException;
AtlasRelationshipDef update(AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
AtlasRelationshipDef updateByName(String name, AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
AtlasRelationshipDef updateByGuid(String guid, AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
Object preDeleteByName(String name) throws AtlasBaseException;
void deleteByName(String name, Object preDeleteResult) throws AtlasBaseException;
Object preDeleteByGuid(String guid) throws AtlasBaseException;
void deleteByGuid(String guid, Object preDeleteResult) throws AtlasBaseException;
}
......@@ -19,6 +19,17 @@ package org.apache.atlas.repository.store.graph.v1;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import static org.apache.atlas.repository.Constants.TYPE_CATEGORY_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.VERTEX_TYPE_PROPERTY_KEY;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.VERTEX_TYPE;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.listener.TypeDefChangeListener;
......@@ -31,6 +42,7 @@ import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.AtlasClassificationDefStore;
import org.apache.atlas.repository.store.graph.AtlasEntityDefStore;
import org.apache.atlas.repository.store.graph.AtlasEnumDefStore;
import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
import org.apache.atlas.repository.store.graph.AtlasStructDefStore;
import org.apache.atlas.repository.store.graph.AtlasTypeDefGraphStore;
import org.apache.atlas.type.AtlasType;
......@@ -45,16 +57,6 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import static org.apache.atlas.repository.Constants.TYPE_CATEGORY_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.VERTEX_TYPE_PROPERTY_KEY;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.VERTEX_TYPE;
/**
......@@ -110,6 +112,12 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
}
@Override
protected AtlasRelationshipDefStore getRelationshipDefStore(AtlasTypeRegistry typeRegistry) {
return new AtlasRelationshipDefStoreV1(this, typeRegistry);
}
@Override
@PostConstruct
public void init() throws AtlasBaseException {
LOG.debug("==> AtlasTypeDefGraphStoreV1.init()");
......@@ -124,34 +132,34 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
@VisibleForTesting
public AtlasVertex findTypeVertexByName(String typeName) {
Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
.has(Constants.TYPENAME_PROPERTY_KEY, typeName)
.vertices().iterator();
.has(Constants.TYPENAME_PROPERTY_KEY, typeName)
.vertices().iterator();
return (results != null && results.hasNext()) ? (AtlasVertex) results.next() : null;
}
AtlasVertex findTypeVertexByNameAndCategory(String typeName, TypeCategory category) {
Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
.has(Constants.TYPENAME_PROPERTY_KEY, typeName)
.has(TYPE_CATEGORY_PROPERTY_KEY, category)
.vertices().iterator();
.has(Constants.TYPENAME_PROPERTY_KEY, typeName)
.has(TYPE_CATEGORY_PROPERTY_KEY, category)
.vertices().iterator();
return (results != null && results.hasNext()) ? (AtlasVertex) results.next() : null;
}
AtlasVertex findTypeVertexByGuid(String typeGuid) {
Iterator<AtlasVertex> vertices = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
.has(Constants.GUID_PROPERTY_KEY, typeGuid)
.vertices().iterator();
.has(Constants.GUID_PROPERTY_KEY, typeGuid)
.vertices().iterator();
return (vertices != null && vertices.hasNext()) ? vertices.next() : null;
}
AtlasVertex findTypeVertexByGuidAndCategory(String typeGuid, TypeCategory category) {
Iterator<AtlasVertex> vertices = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
.has(Constants.GUID_PROPERTY_KEY, typeGuid)
.has(TYPE_CATEGORY_PROPERTY_KEY, category)
.vertices().iterator();
.has(Constants.GUID_PROPERTY_KEY, typeGuid)
.has(TYPE_CATEGORY_PROPERTY_KEY, category)
.vertices().iterator();
return (vertices != null && vertices.hasNext()) ? vertices.next() : null;
}
......@@ -159,8 +167,8 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
Iterator<AtlasVertex> findTypeVerticesByCategory(TypeCategory category) {
return (Iterator<AtlasVertex>) atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
.has(TYPE_CATEGORY_PROPERTY_KEY, category)
.vertices().iterator();
.has(TYPE_CATEGORY_PROPERTY_KEY, category)
.vertices().iterator();
}
AtlasVertex createTypeVertex(AtlasBaseTypeDef typeDef) {
......@@ -246,7 +254,6 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
for (AtlasEdge edge : edges) {
atlasGraph.removeEdge(edge);
}
atlasGraph.removeVertex(vertex);
}
......@@ -343,7 +350,7 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
}
void createSuperTypeEdges(AtlasVertex vertex, Set<String> superTypes, TypeCategory typeCategory)
throws AtlasBaseException {
throws AtlasBaseException {
Set<String> currentSuperTypes = getSuperTypeNames(vertex);
if (CollectionUtils.isNotEmpty(superTypes)) {
......@@ -385,6 +392,9 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
case ENUM:
return TypeCategory.ENUM;
case RELATIONSHIP:
return TypeCategory.RELATIONSHIP;
}
return null;
......
......@@ -86,7 +86,8 @@ public class DataTypes {
MAP,
STRUCT,
TRAIT,
CLASS
CLASS,
RELATIONSHIP
}
public static abstract class PrimitiveType<T> extends AbstractDataType<T> {
......
/**
* 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
......@@ -266,7 +266,7 @@ public class TypesResource {
* Return the list of type names in the type system which match the specified filter.
*
* @return list of type names
* @param typeCategory returns types whose category is the given typeCategory
* @param typeCategory returns types whose relationshipCategory is the given typeCategory
* @param supertype returns types which contain the given supertype
* @param notsupertype returns types which do not contain the given supertype
*
......
......@@ -19,13 +19,7 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.model.typedef.*;
import org.apache.atlas.store.AtlasTypeDefStore;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.utils.AtlasPerfTracer;
......@@ -37,14 +31,7 @@ import org.springframework.stereotype.Service;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import java.util.List;
import java.util.Set;
......@@ -269,7 +256,39 @@ public class TypesREST {
return ret;
}
/**
* Get the relationship definition by it's name (unique)
* @param name relationship name
* @return relationship definition
* @throws AtlasBaseException
* @HTTP 200 On successful lookup of the the relationship definition by it's name
* @HTTP 404 On Failed lookup for the given name
*/
@GET
@Path("/relationshipdef/name/{name}")
@Produces(Servlets.JSON_MEDIA_TYPE)
public AtlasRelationshipDef getRelationshipDefByName(@PathParam("name") String name) throws AtlasBaseException {
AtlasRelationshipDef ret = typeDefStore.getRelationshipDefByName(name);
return ret;
}
/**
* Get the relationship definition for the given guid
* @param guid relationship guid
* @return relationship definition
* @throws AtlasBaseException
* @HTTP 200 On successful lookup of the the relationship definition by it's guid
* @HTTP 404 On Failed lookup for the given guid
*/
@GET
@Path("/relationshipdef/guid/{guid}")
@Produces(Servlets.JSON_MEDIA_TYPE)
public AtlasRelationshipDef getRelationshipDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
AtlasRelationshipDef ret = typeDefStore.getRelationshipDefByGuid(guid);
return ret;
}
/* Bulk API operation */
/**
......
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