You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sa...@apache.org on 2020/01/10 23:05:31 UTC
[atlas] branch branch-2.0 updated: ATLAS-3486: Introduce Atlas
NamespaceDef
This is an automated email from the ASF dual-hosted git repository.
sarath pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new 926a198 ATLAS-3486: Introduce Atlas NamespaceDef
926a198 is described below
commit 926a198c228928d278d1b336eb42c8f22d4bce3b
Author: Aadarsh Jajodia <aa...@gmail.com>
AuthorDate: Fri Jan 10 11:43:01 2020 -0800
ATLAS-3486: Introduce Atlas NamespaceDef
Signed-off-by: Sarath Subramanian <sa...@apache.org>
(cherry picked from commit 6d94f39cf3b6207bc095310eebbe3292071be68b)
---
.../main/java/org/apache/atlas/AtlasErrorCode.java | 5 +
.../java/org/apache/atlas/model/TypeCategory.java | 2 +-
.../atlas/model/typedef/AtlasNamespaceDef.java | 88 ++++++
.../apache/atlas/model/typedef/AtlasStructDef.java | 33 +-
.../apache/atlas/model/typedef/AtlasTypesDef.java | 35 ++-
.../org/apache/atlas/store/AtlasTypeDefStore.java | 6 +
.../org/apache/atlas/type/AtlasEntityType.java | 58 +++-
.../org/apache/atlas/type/AtlasNamespaceType.java | 184 +++++++++++
.../org/apache/atlas/type/AtlasStructType.java | 45 +++
.../org/apache/atlas/type/AtlasTypeRegistry.java | 52 ++-
.../java/org/apache/atlas/type/AtlasTypeUtil.java | 10 +
.../apache/atlas/typesystem/types/DataTypes.java | 3 +-
.../org/apache/atlas/TestRelationshipUtilsV2.java | 21 +-
.../atlas/model/typedef/TestAtlasNamespaceDef.java | 84 +++++
.../repository/graph/GraphBackedSearchIndexer.java | 1 +
.../atlas/repository/impexp/ExportService.java | 1 +
.../repository/impexp/ExportTypeProcessor.java | 15 +-
.../bootstrap/AtlasTypeDefStoreInitializer.java | 25 +-
.../store/graph/AtlasTypeDefGraphStore.java | 117 +++++--
.../store/graph/v2/AtlasNamespaceDefStoreV2.java | 347 +++++++++++++++++++++
.../store/graph/v2/AtlasTypeDefGraphStoreV2.java | 36 ++-
.../graph/v2/AtlasNamespaceDefStoreV2Test.java | 319 +++++++++++++++++++
.../org/apache/atlas/examples/QuickStartV2.java | 28 +-
.../java/org/apache/atlas/web/rest/TypesREST.java | 38 +++
24 files changed, 1486 insertions(+), 67 deletions(-)
diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 3ebd70d..2054513 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -161,6 +161,11 @@ public enum AtlasErrorCode {
INVALID_LABEL_LENGTH(400, "ATLAS-400-00-9B", "Invalid label: {0}, label size should not be greater than {1}"),
INVALID_LABEL_CHARACTERS(400, "ATLAS-400-00-9C", "Invalid label: {0}, label should contain alphanumeric characters, '_' or '-'"),
INVALID_PROPAGATION_TYPE(400, "ATLAS-400-00-9D", "Invalid propagation {0} for relationship-type={1}. Default value is {2}"),
+ DUPLICATE_NAMESPACE_ATTRIBUTE(400, "ATLAS-400-00-094", "Duplicate Namespace Attributes: {0} not allowed within the same namespace: {1}"),
+ APPLICABLE_ENTITY_TYPES_DELETION_NOT_SUPPORTED(400, "ATLAS-400-00-095", "Cannot remove applicableEntityTypes in Attribute Def: {1}, defined in namespace: {2}"),
+ NAMESPACE_DEF_MANDATORY_ATTRIBUTE_NOT_ALLOWED(400, "ATLAS-400-00-096", "{0}.{1} : namespaces can not have mandatory attribute"),
+ NAMESPACE_DEF_UNIQUE_ATTRIBUTE_NOT_ALLOWED(400, "ATLAS-400-00-097", "{0}.{1} : namespaces can not have unique attribute"),
+ NAMESPACE_DEF_ATTRIBUTE_TYPE_INVALID(400, "ATLAS-400-00-098", "{0}.{1}: invalid attribute type. Namespace attribute cannot be of type entity/classification/struct/namespace"),
UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
diff --git a/intg/src/main/java/org/apache/atlas/model/TypeCategory.java b/intg/src/main/java/org/apache/atlas/model/TypeCategory.java
index f06f64f..cbcd0a3 100644
--- a/intg/src/main/java/org/apache/atlas/model/TypeCategory.java
+++ b/intg/src/main/java/org/apache/atlas/model/TypeCategory.java
@@ -18,5 +18,5 @@
package org.apache.atlas.model;
public enum TypeCategory {
- PRIMITIVE, OBJECT_ID_TYPE, ENUM, STRUCT, CLASSIFICATION, ENTITY, ARRAY, MAP, RELATIONSHIP
+ PRIMITIVE, OBJECT_ID_TYPE, ENUM, STRUCT, CLASSIFICATION, ENTITY, ARRAY, MAP, RELATIONSHIP, NAMESPACE
}
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasNamespaceDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasNamespaceDef.java
new file mode 100644
index 0000000..713a2c2
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasNamespaceDef.java
@@ -0,0 +1,88 @@
+/**
+ * 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 com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.apache.atlas.model.TypeCategory;
+
+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.List;
+import java.util.Map;
+
+import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
+import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class AtlasNamespaceDef extends AtlasStructDef implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public static final String ATTR_OPTION_APPLICABLE_ENTITY_TYPES = "applicableEntityTypes";
+ public static final String ATTR_MAX_STRING_LENGTH = "maxStrLength";
+ public static final String ATTR_VALID_PATTERN = "validPattern";
+
+ public AtlasNamespaceDef() {
+ this(null, null, null, null);
+ }
+
+ public AtlasNamespaceDef(String name, String description) {
+ this(name, description, null, null, null);
+ }
+
+ public AtlasNamespaceDef(String name, String description, String typeVersion) {
+ this(name, description, typeVersion, null, null);
+ }
+
+ public AtlasNamespaceDef(String name, String description, String typeVersion, List<AtlasAttributeDef> attributeDefs) {
+ this(name, description, typeVersion, attributeDefs, null);
+ }
+
+ public AtlasNamespaceDef(String name, String description, String typeVersion, List<AtlasAttributeDef> attributeDefs, Map<String, String> options) {
+ super(TypeCategory.NAMESPACE, name, description, typeVersion, attributeDefs, options);
+ }
+
+ public AtlasNamespaceDef(AtlasNamespaceDef other) {
+ super(other);
+ }
+
+ @Override
+ public String toString() {
+ return toString(new StringBuilder()).toString();
+ }
+
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ if (sb == null) {
+ sb = new StringBuilder();
+ }
+
+ sb.append("AtlasNamespaceDef{");
+ super.toString(sb);
+ sb.append('}');
+
+ return sb;
+ }
+}
\ No newline at end of file
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
index bb7ead0..1d4e37b 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
@@ -290,9 +290,9 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
private String description;
private int searchWeight = DEFAULT_SEARCHWEIGHT;
private IndexType indexType = null;
-
private List<AtlasConstraintDef> constraints;
private Map<String, String> options;
+ private String displayName;
public AtlasAttributeDef() { this(null, null); }
@@ -373,9 +373,18 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
setDescription((other.getDescription()));
setSearchWeight(other.getSearchWeight());
setIndexType(other.getIndexType());
+ setDisplayName(other.getDisplayName());
}
}
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
public int getSearchWeight() {
return searchWeight;
}
@@ -510,6 +519,22 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
getOptions().get(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE).equals(STRING_TRUE);
}
+ @JsonIgnore
+ public void setOption(String name, String value) {
+ if (this.options == null) {
+ this.options = new HashMap<>();
+ }
+
+ this.options.put(name, value);
+ }
+
+ @JsonIgnore
+ public String getOption(String name) {
+ Map<String, String> option = this.options;
+
+ return option != null ? option.get(name) : null;
+ }
+
public String getDescription() {
return description;
}
@@ -538,6 +563,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
sb.append(", options='").append(options).append('\'');
sb.append(", searchWeight='").append(searchWeight).append('\'');
sb.append(", indexType='").append(indexType).append('\'');
+ sb.append(", displayName='").append(displayName).append('\'');
sb.append(", constraints=[");
if (CollectionUtils.isNotEmpty(constraints)) {
int i = 0;
@@ -574,12 +600,13 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
Objects.equals(constraints, that.constraints) &&
Objects.equals(options, that.options) &&
Objects.equals(searchWeight, that.searchWeight) &&
- Objects.equals(indexType, that.indexType);
+ Objects.equals(indexType, that.indexType) &&
+ Objects.equals(displayName, that.displayName);
}
@Override
public int hashCode() {
- return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, includeInNotification, defaultValue, constraints, options, description, searchWeight, indexType);
+ return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, includeInNotification, defaultValue, constraints, options, description, searchWeight, indexType, displayName);
}
@Override
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java
index 3634fdf..81ea946 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java
@@ -47,6 +47,7 @@ public class AtlasTypesDef {
private List<AtlasClassificationDef> classificationDefs;
private List<AtlasEntityDef> entityDefs;
private List<AtlasRelationshipDef> relationshipDefs;
+ private List<AtlasNamespaceDef> namespaceDefs;
public AtlasTypesDef() {
enumDefs = new ArrayList<>();
@@ -54,6 +55,7 @@ public class AtlasTypesDef {
classificationDefs = new ArrayList<>();
entityDefs = new ArrayList<>();
relationshipDefs = new ArrayList<>();
+ namespaceDefs = new ArrayList<>();
}
/**
@@ -66,7 +68,7 @@ public class AtlasTypesDef {
*/
public AtlasTypesDef(List<AtlasEnumDef> enumDefs, List<AtlasStructDef> structDefs,
List<AtlasClassificationDef> classificationDefs, List<AtlasEntityDef> entityDefs) {
- this(enumDefs, structDefs, classificationDefs, entityDefs,new ArrayList<AtlasRelationshipDef>());
+ this(enumDefs, structDefs, classificationDefs, entityDefs, new ArrayList<>(), new ArrayList<>());
}
/**
* Create the TypesDef. This created definitions for each of the types.
@@ -81,12 +83,23 @@ public class AtlasTypesDef {
List<AtlasClassificationDef> classificationDefs,
List<AtlasEntityDef> entityDefs,
List<AtlasRelationshipDef> relationshipDefs) {
+ this(enumDefs, structDefs, classificationDefs, entityDefs, relationshipDefs, new ArrayList<>());
+ }
+
+ public AtlasTypesDef(List<AtlasEnumDef> enumDefs,
+ List<AtlasStructDef> structDefs,
+ List<AtlasClassificationDef> classificationDefs,
+ List<AtlasEntityDef> entityDefs,
+ List<AtlasRelationshipDef> relationshipDefs,
+ List<AtlasNamespaceDef> namespaceDefs) {
this.enumDefs = enumDefs;
this.structDefs = structDefs;
this.classificationDefs = classificationDefs;
this.entityDefs = entityDefs;
this.relationshipDefs = relationshipDefs;
+ this.namespaceDefs = namespaceDefs;
}
+
public List<AtlasEnumDef> getEnumDefs() {
return enumDefs;
}
@@ -125,6 +138,14 @@ public class AtlasTypesDef {
this.relationshipDefs = relationshipDefs;
}
+ public void setNamespaceDefs(List<AtlasNamespaceDef> namespaceDefs) {
+ this.namespaceDefs = namespaceDefs;
+ }
+
+ public List<AtlasNamespaceDef> getNamespaceDefs() {
+ return namespaceDefs;
+ }
+
public boolean hasClassificationDef(String name) {
return hasTypeDef(classificationDefs, name);
}
@@ -144,6 +165,9 @@ public class AtlasTypesDef {
return hasTypeDef(relationshipDefs, name);
}
+ public boolean hasNamespaceDef(String name) {
+ return hasTypeDef(namespaceDefs, name);
+ }
private <T extends AtlasBaseTypeDef> boolean hasTypeDef(Collection<T> typeDefs, String name) {
if (CollectionUtils.isNotEmpty(typeDefs)) {
@@ -163,7 +187,8 @@ public class AtlasTypesDef {
CollectionUtils.isEmpty(structDefs) &&
CollectionUtils.isEmpty(classificationDefs) &&
CollectionUtils.isEmpty(entityDefs) &&
- CollectionUtils.isEmpty(relationshipDefs);
+ CollectionUtils.isEmpty(relationshipDefs) &&
+ CollectionUtils.isEmpty(namespaceDefs);
}
public void clear() {
@@ -185,6 +210,10 @@ public class AtlasTypesDef {
if (relationshipDefs != null) {
relationshipDefs.clear();
}
+
+ if (namespaceDefs != null) {
+ namespaceDefs.clear();
+ }
}
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
@@ -206,6 +235,8 @@ public class AtlasTypesDef {
sb.append("}");
sb.append("relationshipDefs={");
AtlasBaseTypeDef.dumpObjects(relationshipDefs, sb);
+ sb.append("namespaceDefs={");
+ AtlasBaseTypeDef.dumpObjects(namespaceDefs, sb);
sb.append("}");
return sb;
diff --git a/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java b/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
index 4ee68a9..b08ace4 100644
--- a/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
+++ b/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
@@ -23,6 +23,7 @@ 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.AtlasNamespaceDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasTypesDef;
@@ -85,6 +86,11 @@ public interface AtlasTypeDefStore {
AtlasRelationshipDef updateRelationshipDefByGuid(String guid, AtlasRelationshipDef structDef) throws AtlasBaseException;
+ /* Namespace Def operations */
+ AtlasNamespaceDef getNamespaceDefByName(String name) throws AtlasBaseException;
+
+ AtlasNamespaceDef getNamespaceDefByGuid(String guid) throws AtlasBaseException;
+
/* Bulk Operations */
AtlasTypesDef createTypesDef(AtlasTypesDef atlasTypesDef) throws AtlasBaseException;
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
index 4742d1c..02d6d58 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -31,6 +31,7 @@ import org.apache.atlas.model.typedef.AtlasEntityDef.AtlasRelationshipAttributeD
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType;
+import org.apache.atlas.type.AtlasNamespaceType.AtlasNamespaceAttribute;
import org.apache.atlas.utils.AtlasEntityUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
@@ -47,6 +48,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+
/**
* class that implements behaviour of an entity-type.
*/
@@ -72,22 +74,23 @@ public class AtlasEntityType extends AtlasStructType {
private final AtlasEntityDef entityDef;
private final String typeQryStr;
- private List<AtlasEntityType> superTypes = Collections.emptyList();
- private Set<String> allSuperTypes = Collections.emptySet();
- private Set<String> subTypes = Collections.emptySet();
- private Set<String> allSubTypes = Collections.emptySet();
- private Set<String> typeAndAllSubTypes = Collections.emptySet();
- private Set<String> typeAndAllSuperTypes = Collections.emptySet();
- private Map<String, Map<String, AtlasAttribute>> relationshipAttributes = Collections.emptyMap();
- private List<AtlasAttribute> ownedRefAttributes = Collections.emptyList();
- private String typeAndAllSubTypesQryStr = "";
- private boolean isInternalType = false;
- private Map<String, AtlasAttribute> headerAttributes = Collections.emptyMap();
- private Map<String, AtlasAttribute> minInfoAttributes = Collections.emptyMap();
- private List<AtlasAttribute> dynAttributes = Collections.emptyList();
- private List<AtlasAttribute> dynEvalTriggerAttributes = Collections.emptyList();
- private Map<String,List<TemplateToken>> parsedTemplates = Collections.emptyMap();
- private Set<String> tagPropagationEdges = Collections.emptySet();
+ private List<AtlasEntityType> superTypes = Collections.emptyList();
+ private Set<String> allSuperTypes = Collections.emptySet();
+ private Set<String> subTypes = Collections.emptySet();
+ private Set<String> allSubTypes = Collections.emptySet();
+ private Set<String> typeAndAllSubTypes = Collections.emptySet();
+ private Set<String> typeAndAllSuperTypes = Collections.emptySet();
+ private Map<String, Map<String, AtlasAttribute>> relationshipAttributes = Collections.emptyMap();
+ private List<AtlasAttribute> ownedRefAttributes = Collections.emptyList();
+ private String typeAndAllSubTypesQryStr = "";
+ private boolean isInternalType = false;
+ private Map<String, AtlasAttribute> headerAttributes = Collections.emptyMap();
+ private Map<String, AtlasAttribute> minInfoAttributes = Collections.emptyMap();
+ private List<AtlasAttribute> dynAttributes = Collections.emptyList();
+ private List<AtlasAttribute> dynEvalTriggerAttributes = Collections.emptyList();
+ private Map<String,List<TemplateToken>> parsedTemplates = Collections.emptyMap();
+ private Set<String> tagPropagationEdges = Collections.emptySet();
+ private Map<String, List<AtlasNamespaceAttribute>> namespaceAttributes = Collections.emptyMap();
public AtlasEntityType(AtlasEntityDef entityDef) {
super(entityDef);
@@ -140,6 +143,7 @@ public class AtlasEntityType extends AtlasStructType {
this.typeAndAllSubTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
this.relationshipAttributes = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
this.tagPropagationEdges = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
+ this.namespaceAttributes = new HashMap<>(); // this will be populated in resolveReferences(), from AtlasNamespaceType
this.typeAndAllSubTypes.add(this.getTypeName());
@@ -259,6 +263,7 @@ public class AtlasEntityType extends AtlasStructType {
relationshipAttributes = Collections.unmodifiableMap(relationshipAttributes);
ownedRefAttributes = Collections.unmodifiableList(ownedRefAttributes);
tagPropagationEdges = Collections.unmodifiableSet(tagPropagationEdges);
+ namespaceAttributes = Collections.unmodifiableMap(namespaceAttributes);
entityDef.setSubTypes(subTypes);
@@ -361,6 +366,14 @@ public class AtlasEntityType extends AtlasStructType {
public String[] getTagPropagationEdgesArray() {
return CollectionUtils.isNotEmpty(tagPropagationEdges) ? tagPropagationEdges.toArray(new String[tagPropagationEdges.size()]) : null;
}
+
+ public Map<String, List<AtlasNamespaceAttribute>> getNamespaceAttributes() {
+ return namespaceAttributes;
+ }
+
+ public List<AtlasNamespaceAttribute> getNamespaceAttributes(String nsName) {
+ return namespaceAttributes.get(nsName);
+ }
public Map<String,List<TemplateToken>> getParsedTemplates() { return parsedTemplates; }
@@ -452,6 +465,19 @@ public class AtlasEntityType extends AtlasStructType {
return relationshipAttributes.containsKey(attributeName);
}
+ public void addNamespaceAttribute(AtlasNamespaceAttribute attribute) {
+ String nsName = attribute.getDefinedInType().getTypeName();
+ List<AtlasNamespaceAttribute> attributes = namespaceAttributes.get(nsName);
+
+ if (attributes == null) {
+ attributes = new ArrayList<>();
+
+ namespaceAttributes.put(nsName, attributes);
+ }
+
+ attributes.add(attribute);
+ }
+
public String getQualifiedAttributeName(String attrName) throws AtlasBaseException {
AtlasAttribute ret = getAttribute(attrName);
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java b/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java
new file mode 100644
index 0000000..a141d4a
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java
@@ -0,0 +1,184 @@
+/**
+ * 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.instance.AtlasStruct;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
+import org.apache.commons.collections.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.*;
+
+
+public class AtlasNamespaceType extends AtlasStructType {
+ private static final Logger LOG = LoggerFactory.getLogger(AtlasNamespaceType.class);
+
+ private final AtlasNamespaceDef namespaceDef;
+
+
+ public AtlasNamespaceType(AtlasNamespaceDef namespaceDef) {
+ super(namespaceDef);
+
+ this.namespaceDef = namespaceDef;
+ }
+
+ @Override
+ public boolean isValidValue(Object o) {
+ return true; // there is no runtime instance for Namespaces, so return true
+ }
+
+ @Override
+ public AtlasStruct createDefaultValue() {
+ return null; // there is no runtime instance for Namespaces, so return null
+ }
+
+ @Override
+ public Object getNormalizedValue(Object a) {
+ return null; // there is no runtime instance for Namespaces, so return null
+ }
+
+ public AtlasNamespaceDef getNamespaceDef() {
+ return namespaceDef;
+ }
+
+ @Override
+ void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+ super.resolveReferences(typeRegistry);
+
+ Map<String, AtlasNamespaceAttribute> a = new HashMap<>();
+
+ for (AtlasAttribute attribute : super.allAttributes.values()) {
+ AtlasAttributeDef attributeDef = attribute.getAttributeDef();
+ String attrName = attribute.getName();
+ AtlasType attrType = attribute.getAttributeType();
+
+ if (attrType instanceof AtlasArrayType) {
+ attrType = ((AtlasArrayType) attrType).getElementType();
+ } else if (attrType instanceof AtlasMapType) {
+ attrType = ((AtlasMapType) attrType).getValueType();
+ }
+
+ // check if attribute type is not struct/classification/entity/namespace
+ if (attrType instanceof AtlasStructType) {
+ throw new AtlasBaseException(AtlasErrorCode.NAMESPACE_DEF_ATTRIBUTE_TYPE_INVALID, getTypeName(), attrName);
+ }
+
+ if (!attributeDef.getIsOptional()) {
+ throw new AtlasBaseException(AtlasErrorCode.NAMESPACE_DEF_MANDATORY_ATTRIBUTE_NOT_ALLOWED, getTypeName(), attrName);
+ }
+
+ if (attributeDef.getIsUnique()) {
+ throw new AtlasBaseException(AtlasErrorCode.NAMESPACE_DEF_UNIQUE_ATTRIBUTE_NOT_ALLOWED, getTypeName(), attrName);
+ }
+
+ Set<String> entityTypeNames = attribute.getOptionSet(ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+ Set<AtlasEntityType> entityTypes = new HashSet<>();
+
+ if (CollectionUtils.isNotEmpty(entityTypeNames)) {
+ for (String entityTypeName : entityTypeNames) {
+ AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName);
+
+ if (entityType == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, entityTypeName);
+ }
+
+ entityTypes.add(entityType);
+ }
+ } else {
+ throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, attributeDef.getName(), "options." + ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+ }
+
+ AtlasNamespaceAttribute nsAttribute;
+ if (attribute.getAttributeType() instanceof AtlasBuiltInTypes.AtlasStringType) {
+ Integer maxStringLength = attribute.getOptionInt(ATTR_MAX_STRING_LENGTH);
+ if (maxStringLength == null) {
+ throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, attributeDef.getName(), "options." + ATTR_MAX_STRING_LENGTH);
+ }
+
+ String validPattern = attribute.getOptionString(ATTR_VALID_PATTERN);
+ nsAttribute = new AtlasNamespaceAttribute(attribute, entityTypes, maxStringLength, validPattern);
+ } else {
+ nsAttribute = new AtlasNamespaceAttribute(attribute, entityTypes);
+ }
+
+ a.put(attrName, nsAttribute);
+ }
+
+ super.allAttributes = Collections.unmodifiableMap(a);
+ }
+
+ @Override
+ void resolveReferencesPhase2(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+ super.resolveReferencesPhase2(typeRegistry);
+
+ for (AtlasAttribute attribute : super.allAttributes.values()) {
+ AtlasNamespaceAttribute nsAttribute = (AtlasNamespaceAttribute) attribute;
+ Set<AtlasEntityType> entityTypes = nsAttribute.getApplicableEntityTypes();
+
+ if (CollectionUtils.isNotEmpty(entityTypes)) {
+ for (AtlasEntityType entityType : entityTypes) {
+ entityType.addNamespaceAttribute(nsAttribute);
+ }
+ }
+ }
+ }
+
+ public static class AtlasNamespaceAttribute extends AtlasAttribute {
+ private final Set<AtlasEntityType> applicableEntityTypes;
+ private final int maxStringLength;
+ private final String validPattern;
+
+ public AtlasNamespaceAttribute(AtlasAttribute attribute, Set<AtlasEntityType> applicableEntityTypes) {
+ super(attribute);
+ this.maxStringLength = 0;
+ this.validPattern = null;
+ this.applicableEntityTypes = applicableEntityTypes;
+ }
+
+ public AtlasNamespaceAttribute(AtlasAttribute attribute, Set<AtlasEntityType> applicableEntityTypes,
+ int maxStringLength, String validPattern) {
+ super(attribute);
+ this.maxStringLength = maxStringLength;
+ this.validPattern = validPattern;
+ this.applicableEntityTypes = applicableEntityTypes;
+ }
+
+ @Override
+ public AtlasNamespaceType getDefinedInType() {
+ return (AtlasNamespaceType) super.getDefinedInType();
+ }
+
+ public Set<AtlasEntityType> getApplicableEntityTypes() {
+ return applicableEntityTypes;
+ }
+
+ public String getValidPattern() {
+ return validPattern;
+ }
+
+ public int getMaxStringLength() {
+ return maxStringLength;
+ }
+ }
+}
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index 3475ce6..6bd3a11 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -112,6 +112,10 @@ public class AtlasStructType extends AtlasType {
throw new AtlasBaseException(AtlasErrorCode.ATTRIBUTE_TYPE_INVALID, getTypeName(), attributeDef.getName());
}
+ if (attrType instanceof AtlasNamespaceType) {
+ throw new AtlasBaseException(AtlasErrorCode.ATTRIBUTE_TYPE_INVALID, getTypeName(), attributeDef.getName());
+ }
+
a.put(attributeDef.getName(), attribute);
}
@@ -794,6 +798,26 @@ public class AtlasStructType extends AtlasType {
this(definedInType, attrDef, attributeType, null, null);
}
+ public AtlasAttribute(AtlasAttribute other) {
+ this.definedInType = other.definedInType;
+ this.attributeType = other.attributeType;
+ this.attributeDef = other.attributeDef;
+ this.qualifiedName = other.qualifiedName;
+ this.vertexPropertyName = other.vertexPropertyName;
+ this.vertexUniquePropertyName = other.vertexUniquePropertyName;
+ this.isOwnedRef = other.isOwnedRef;
+ this.isObjectRef = other.isObjectRef;
+ this.inverseRefAttributeName = other.inverseRefAttributeName;
+ this.inverseRefAttribute = other.inverseRefAttribute;
+ this.relationshipName = other.relationshipName;
+ this.relationshipEdgeLabel = other.relationshipEdgeLabel;
+ this.relationshipEdgeDirection = other.relationshipEdgeDirection;
+ this.isLegacyAttribute = other.isLegacyAttribute;
+ this.indexFieldName = other.indexFieldName;
+ this.isDynAttribute = false;
+ this.isDynAttributeEvalTrigger = false;
+ }
+
public AtlasStructType getDefinedInType() { return definedInType; }
public AtlasStructDef getDefinedInDef() { return definedInType.getStructDef(); }
@@ -860,6 +884,27 @@ public class AtlasStructType extends AtlasType {
public void setIsDynAttributeEvalTrigger(boolean isDynAttributeEvalTrigger) { this.isDynAttributeEvalTrigger = isDynAttributeEvalTrigger; }
+ public Set<String> getOptionSet(String optionName) {
+ String strValue = attributeDef.getOption(optionName);
+ Set<String> ret = StringUtils.isBlank(strValue) ? null : AtlasType.fromJson(strValue, Set.class);
+
+ return ret;
+ }
+
+ public Integer getOptionInt(String optionName) {
+ String strValue = attributeDef.getOption(optionName);
+ Integer ret = StringUtils.isBlank(strValue) ? null : Integer.parseInt(strValue);
+
+ return ret;
+ }
+
+ public String getOptionString(String optionName) {
+ String strValue = attributeDef.getOption(optionName);
+ String ret = StringUtils.isBlank(strValue) ? null : strValue;
+
+ return ret;
+ }
+
public static String getEdgeLabel(String property) {
return "__" + property;
}
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
index b071dc9..97e27d0 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
@@ -23,6 +23,7 @@ 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.AtlasNamespaceDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasTypesDef;
@@ -192,6 +193,15 @@ public class AtlasTypeRegistry {
return registryData.classificationDefs.getTypeByName(name);
}
+ public Collection<AtlasNamespaceType> getAllNamespaceTypes() {
+ return registryData.namespaceDefs.getAllTypes();
+ }
+
+ public Collection<AtlasNamespaceDef> getAllNamespaceDefs() {
+ return registryData.namespaceDefs.getAll();
+ }
+
+
public Collection<AtlasRelationshipDef> getAllRelationshipDefs() { return registryData.relationshipDefs.getAll(); }
public Collection<AtlasEntityDef> getAllEntityDefs() { return registryData.entityDefs.getAll(); }
@@ -217,6 +227,15 @@ public class AtlasTypeRegistry {
public AtlasRelationshipDef getRelationshipDefByName(String name) {
return registryData.relationshipDefs.getTypeDefByName(name);
}
+
+ public AtlasNamespaceDef getNamespaceDefByGuid(String guid) {
+ return registryData.namespaceDefs.getTypeDefByGuid(guid);
+ }
+
+ public AtlasNamespaceDef getNamespaceDefByName(String name) {
+ return registryData.namespaceDefs.getTypeDefByName(name);
+ }
+
public AtlasRelationshipType getRelationshipTypeByName(String name) { return registryData.relationshipDefs.getTypeByName(name); }
public AtlasTransientTypeRegistry lockTypeRegistryForUpdate() throws AtlasBaseException {
@@ -271,6 +290,7 @@ public class AtlasTypeRegistry {
final TypeDefCache<AtlasClassificationDef, AtlasClassificationType> classificationDefs;
final TypeDefCache<AtlasEntityDef, AtlasEntityType> entityDefs;
final TypeDefCache<AtlasRelationshipDef, AtlasRelationshipType> relationshipDefs;
+ final TypeDefCache<AtlasNamespaceDef, AtlasNamespaceType> namespaceDefs;
final TypeDefCache<? extends AtlasBaseTypeDef, ? extends AtlasType>[] allDefCaches;
RegistryData() {
@@ -280,7 +300,9 @@ public class AtlasTypeRegistry {
classificationDefs = new TypeDefCache<>(allTypes);
entityDefs = new TypeDefCache<>(allTypes);
relationshipDefs = new TypeDefCache<>(allTypes);
- allDefCaches = new TypeDefCache[] { enumDefs, structDefs, classificationDefs, entityDefs, relationshipDefs };
+ namespaceDefs = new TypeDefCache<>(allTypes);
+ allDefCaches = new TypeDefCache[] { enumDefs, structDefs, classificationDefs, entityDefs,
+ relationshipDefs, namespaceDefs };
init();
}
@@ -339,6 +361,7 @@ public class AtlasTypeRegistry {
classificationDefs.updateGuid(typeName, guid);
entityDefs.updateGuid(typeName, guid);
relationshipDefs.updateGuid(typeName, guid);
+ namespaceDefs.updateGuid(typeName, guid);
}
}
@@ -349,6 +372,7 @@ public class AtlasTypeRegistry {
classificationDefs.removeTypeDefByGuid(guid);
entityDefs.removeTypeDefByGuid(guid);
relationshipDefs.removeTypeDefByGuid(guid);
+ namespaceDefs.removeTypeDefByGuid(guid);
}
}
@@ -359,6 +383,7 @@ public class AtlasTypeRegistry {
classificationDefs.removeTypeDefByName(typeName);
entityDefs.removeTypeDefByName(typeName);
relationshipDefs.removeTypeDefByName(typeName);
+ namespaceDefs.removeTypeDefByName(typeName);
}
}
@@ -369,7 +394,7 @@ public class AtlasTypeRegistry {
classificationDefs.clear();
entityDefs.clear();
relationshipDefs.clear();
-
+ namespaceDefs.clear();
init();
}
}
@@ -388,6 +413,7 @@ public class AtlasTypeRegistry {
addTypesWithNoRefResolve(parent.getAllClassificationDefs());
addTypesWithNoRefResolve(parent.getAllEntityDefs());
addTypesWithNoRefResolve(parent.getAllRelationshipDefs());
+ addTypesWithNoRefResolve(parent.getAllNamespaceDefs());
addedTypes.clear();
updatedTypes.clear();
@@ -467,6 +493,7 @@ public class AtlasTypeRegistry {
addTypesWithNoRefResolve(typesDef.getClassificationDefs());
addTypesWithNoRefResolve(typesDef.getEntityDefs());
addTypesWithNoRefResolve(typesDef.getRelationshipDefs());
+ addTypesWithNoRefResolve(typesDef.getNamespaceDefs());
}
resolveReferences();
@@ -567,6 +594,7 @@ public class AtlasTypeRegistry {
updateTypesWithNoRefResolve(typesDef.getClassificationDefs());
updateTypesWithNoRefResolve(typesDef.getEntityDefs());
updateTypesWithNoRefResolve(typesDef.getRelationshipDefs());
+ updateTypesWithNoRefResolve(typesDef.getNamespaceDefs());
}
if (LOG.isDebugEnabled()) {
@@ -581,6 +609,7 @@ public class AtlasTypeRegistry {
removeTypesWithNoRefResolve(typesDef.getClassificationDefs());
removeTypesWithNoRefResolve(typesDef.getEntityDefs());
removeTypesWithNoRefResolve(typesDef.getRelationshipDefs());
+ removeTypesWithNoRefResolve(typesDef.getNamespaceDefs());
}
resolveReferences();
@@ -615,6 +644,9 @@ public class AtlasTypeRegistry {
case RELATIONSHIP:
registryData.relationshipDefs.removeTypeDefByName(typeDef.getName());
break;
+ case NAMESPACE:
+ registryData.namespaceDefs.removeTypeDefByName(typeDef.getName());
+ break;
}
deletedTypes.add(typeDef);
}
@@ -636,6 +668,9 @@ public class AtlasTypeRegistry {
case RELATIONSHIP:
registryData.relationshipDefs.removeTypeDefByGuid(typeDef.getGuid());
break;
+ case NAMESPACE:
+ registryData.namespaceDefs.removeTypeDefByGuid(typeDef.getGuid());
+ break;
}
deletedTypes.add(typeDef);
}
@@ -722,6 +757,9 @@ public class AtlasTypeRegistry {
AtlasRelationshipDef relationshipDef = (AtlasRelationshipDef) typeDef;
registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
+ } else if (typeDef.getClass().equals(AtlasNamespaceDef.class)) {
+ AtlasNamespaceDef namespaceDef = (AtlasNamespaceDef) typeDef;
+ registryData.namespaceDefs.addType(namespaceDef, new AtlasNamespaceType(namespaceDef));
}
addedTypes.add(typeDef);
@@ -801,6 +839,11 @@ public class AtlasTypeRegistry {
registryData.relationshipDefs.removeTypeDefByGuid(guid);
registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
+ } else if (typeDef.getClass().equals(AtlasNamespaceDef.class)) {
+ AtlasNamespaceDef namespaceDef = (AtlasNamespaceDef) typeDef;
+
+ registryData.namespaceDefs.removeTypeDefByGuid(guid);
+ registryData.namespaceDefs.addType(namespaceDef, new AtlasNamespaceType(namespaceDef));
}
updatedTypes.add(typeDef);
@@ -843,6 +886,11 @@ public class AtlasTypeRegistry {
registryData.relationshipDefs.removeTypeDefByName(name);
registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
+ } else if (typeDef.getClass().equals(AtlasNamespaceDef.class)) {
+ AtlasNamespaceDef namespaceDef = (AtlasNamespaceDef) typeDef;
+
+ registryData.namespaceDefs.removeTypeDefByName(name);
+ registryData.namespaceDefs.addType(namespaceDef, new AtlasNamespaceType(namespaceDef));
}
updatedTypes.add(typeDef);
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
index 0883d54..5b115b5 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
@@ -28,6 +28,7 @@ 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.AtlasEnumDef.AtlasEnumElementDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
@@ -315,6 +316,15 @@ public class AtlasTypeUtil {
return new AtlasTypesDef(enums, structs, traits, classes, relations);
}
+ public static AtlasTypesDef getTypesDef(List<AtlasEnumDef> enums,
+ List<AtlasStructDef> structs,
+ List<AtlasClassificationDef> traits,
+ List<AtlasEntityDef> classes,
+ List<AtlasRelationshipDef> relations,
+ List<AtlasNamespaceDef> namespaces) {
+ return new AtlasTypesDef(enums, structs, traits, classes, relations, namespaces);
+ }
+
public static List<AtlasTypeDefHeader> toTypeDefHeader(AtlasTypesDef typesDef) {
List<AtlasTypeDefHeader> headerList = new LinkedList<>();
if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
diff --git a/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java b/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
index dba2d88..d57a484 100644
--- a/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
+++ b/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
@@ -30,6 +30,7 @@ public class DataTypes {
STRUCT,
TRAIT,
CLASS,
- RELATIONSHIP
+ RELATIONSHIP,
+ NAMESPACE
}
}
\ No newline at end of file
diff --git a/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java
index 02613b5..32ed6ee 100755
--- a/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java
@@ -27,10 +27,12 @@ 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.AtlasEnumDef.AtlasEnumElementDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
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.model.typedef.AtlasTypesDef;
+import org.apache.atlas.type.AtlasType;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
@@ -38,6 +40,7 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.BOTH;
import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.ONE_TO_TWO;
import static org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory.AGGREGATION;
@@ -141,11 +144,25 @@ public final class TestRelationshipUtilsV2 {
new AtlasRelationshipEndDef(PERSON_TYPE, "sibling", SINGLE),
new AtlasRelationshipEndDef(PERSON_TYPE, "sibling", SINGLE));
+ AtlasStructDef.AtlasAttributeDef nsAttr1 = new AtlasStructDef.AtlasAttributeDef("attr1", "int");
+ AtlasStructDef.AtlasAttributeDef nsAttr2 = new AtlasStructDef.AtlasAttributeDef("attr2", "int");
+
+ nsAttr1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(DEPARTMENT_TYPE)));
+ nsAttr1.setIsOptional(true);
+ nsAttr1.setIsUnique(false);
+
+ nsAttr2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(DEPARTMENT_TYPE)));
+ nsAttr2.setIsOptional(true);
+ nsAttr2.setIsUnique(false);
+
+ AtlasNamespaceDef namespaceDef = new AtlasNamespaceDef("test_namespace", "test_description", DEFAULT_VERSION, Arrays.asList(nsAttr1, nsAttr2));
+
return new AtlasTypesDef(Collections.singletonList(orgLevelType),
Collections.singletonList(addressType),
Collections.singletonList(securityClearanceType),
Arrays.asList(personType, employeeType, departmentType, managerType),
- Arrays.asList(employeeDepartmentType, employeeManagerType, employeeMentorsType, employeeFriendsType, personSiblingType));
+ Arrays.asList(employeeDepartmentType, employeeManagerType, employeeMentorsType, employeeFriendsType, personSiblingType),
+ Collections.singletonList(namespaceDef));
}
public static AtlasEntitiesWithExtInfo getDepartmentEmployeeInstances() {
@@ -278,7 +295,7 @@ public final class TestRelationshipUtilsV2 {
new AtlasRelationshipEndDef(TYPE_A, "mapToB", SET));
return new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(), Collections.<AtlasStructDef>emptyList(), Collections.<AtlasClassificationDef>emptyList(), Arrays.asList(aType, bType),
- Arrays.asList(relationshipType1, relationshipType2, relationshipType3, relationshipType4));
+ Arrays.asList(relationshipType1, relationshipType2, relationshipType3, relationshipType4), Collections.<AtlasNamespaceDef>emptyList());
}
private static List<AtlasEnumElementDef> getOrgLevelElements() {
diff --git a/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasNamespaceDef.java b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasNamespaceDef.java
new file mode 100644
index 0000000..8867774
--- /dev/null
+++ b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasNamespaceDef.java
@@ -0,0 +1,84 @@
+/**
+ * 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.type.AtlasType;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+
+public class TestAtlasNamespaceDef {
+
+ @Test
+ public void namespaceDefSerDes() {
+ AtlasNamespaceDef namespaceDef = new AtlasNamespaceDef("test_namespace", "test_description", null);
+ String jsonString = AtlasType.toJson(namespaceDef);
+
+ AtlasNamespaceDef namespaceDef1 = AtlasType.fromJson(jsonString, AtlasNamespaceDef.class);
+ assertEquals(namespaceDef, namespaceDef1,
+ "Incorrect serialization/deserialization of AtlasNamespaceDef");
+ }
+
+ @Test
+ public void namespaceDefEquality() {
+ AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+ AtlasNamespaceDef namespaceDef2 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+ assertEquals(namespaceDef1, namespaceDef2, "Namespaces should be equal because the name of the" +
+ "namespace is same");
+ }
+
+ @Test
+ public void namespaceDefUnequality() {
+ AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+ AtlasNamespaceDef namespaceDef2 = new AtlasNamespaceDef("test_namespace1", "test_description", null);
+ assertNotEquals(namespaceDef1, namespaceDef2, "Namespaces should not be equal since they have a" +
+ "different name");
+ }
+
+ @Test
+ public void namespaceDefWithNamespaceAttributes() {
+ AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+ AtlasStructDef.AtlasAttributeDef nsAttr1 = new AtlasStructDef.AtlasAttributeDef("attr1", "int");
+ AtlasStructDef.AtlasAttributeDef nsAttr2 = new AtlasStructDef.AtlasAttributeDef("attr2", "int");
+
+ nsAttr1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+ nsAttr2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+
+ namespaceDef1.setAttributeDefs(Arrays.asList(nsAttr1, nsAttr2));
+ assertEquals(namespaceDef1.getAttributeDefs().size(), 2);
+ }
+
+ @Test
+ public void namespaceDefWithNamespaceAttributesHavingCardinality() {
+ AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+ AtlasStructDef.AtlasAttributeDef nsAttr1 = new AtlasStructDef.AtlasAttributeDef("attr1", "int");
+ AtlasStructDef.AtlasAttributeDef nsAttr2 = new AtlasStructDef.AtlasAttributeDef("attr2", "int");
+
+ nsAttr1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+ nsAttr2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+ nsAttr2.setCardinality(AtlasStructDef.AtlasAttributeDef.Cardinality.SET);
+
+ namespaceDef1.setAttributeDefs(Arrays.asList(nsAttr1, nsAttr2));
+ assertEquals(namespaceDef1.getAttributeDefs().size(), 2);
+ }
+}
\ No newline at end of file
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
index f96e6a6..7f4fc04 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
@@ -33,6 +33,7 @@ import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.repository.Constants;
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
index 6016723..82a2d31 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
@@ -347,6 +347,7 @@ public class ExportService {
final Set<String> structTypes = new HashSet<>();
final Set<String> enumTypes = new HashSet<>();
final Set<String> relationshipTypes = new HashSet<>();
+ final Set<String> namespaceTypes = new HashSet<>();
final AtlasExportResult result;
private final ZipSink sink;
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
index 5bad615..b553352 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
@@ -28,6 +28,7 @@ import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasEnumType;
import org.apache.atlas.type.AtlasMapType;
+import org.apache.atlas.type.AtlasNamespaceType;
import org.apache.atlas.type.AtlasRelationshipType;
import org.apache.atlas.type.AtlasStructType;
import org.apache.atlas.type.AtlasType;
@@ -103,12 +104,14 @@ class ExportTypeProcessor {
addEntityType((AtlasEntityType)type, context);
} else if (type instanceof AtlasClassificationType) {
addClassificationType((AtlasClassificationType)type, context);
+ } else if (type instanceof AtlasRelationshipType) {
+ addRelationshipType(type.getTypeName(), context);
+ } else if (type instanceof AtlasNamespaceType) {
+ addNamespaceType((AtlasNamespaceType) type, context);
} else if (type instanceof AtlasStructType) {
addStructType((AtlasStructType)type, context);
} else if (type instanceof AtlasEnumType) {
addEnumType((AtlasEnumType)type, context);
- } else if (type instanceof AtlasRelationshipType) {
- addRelationshipType(type.getTypeName(), context);
}
}
@@ -169,6 +172,14 @@ class ExportTypeProcessor {
}
}
+ private void addNamespaceType(AtlasNamespaceType namespaceType, ExportService.ExportContext context) {
+ if (!context.namespaceTypes.contains(namespaceType.getTypeName())) {
+ context.namespaceTypes.add(namespaceType.getTypeName());
+
+ addAttributeTypes(namespaceType, context);
+ }
+ }
+
private void addAttributeTypes(AtlasStructType structType, ExportService.ExportContext context) {
for (AtlasStructDef.AtlasAttributeDef attributeDef : structType.getStructDef().getAttributeDefs()) {
addType(attributeDef.getTypeName(), context);
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
index 08b00e7..2a602c8 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
@@ -34,13 +34,13 @@ 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.AtlasEnumDef.AtlasEnumElementDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.model.typedef.AtlasTypesDef;
-import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.patches.AtlasPatchRegistry;
@@ -55,7 +55,6 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.jute.Index;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
@@ -253,6 +252,14 @@ public class AtlasTypeDefStoreInitializer implements ActiveStateChangeHandler {
}
}
+ if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+ for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+ if (!typeRegistry.isRegisteredType(namespaceDef.getName())) {
+ typesToCreate.getNamespaceDefs().add(namespaceDef);
+ }
+ }
+ }
+
return typesToCreate;
}
@@ -337,6 +344,20 @@ public class AtlasTypeDefStoreInitializer implements ActiveStateChangeHandler {
}
}
+ if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+ for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+ AtlasNamespaceDef oldNamespaceDef = typeRegistry.getNamespaceDefByName(namespaceDef.getName());
+
+ if (oldNamespaceDef == null) {
+ continue;
+ }
+
+ if (updateTypeAttributes(oldNamespaceDef, namespaceDef, checkTypeVersion)) {
+ typesToUpdate.getNamespaceDefs().add(namespaceDef);
+ }
+ }
+ }
+
return typesToUpdate;
}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
index b04f188..e1ef849 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
@@ -79,6 +79,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
protected abstract AtlasDefStore<AtlasRelationshipDef> getRelationshipDefStore(AtlasTypeRegistry typeRegistry);
+ protected abstract AtlasDefStore<AtlasNamespaceDef> getNamespaceDefStore(AtlasTypeRegistry typeRegistry);
+
public AtlasTypeRegistry getTypeRegistry() { return typeRegistry; }
@Override
@@ -97,7 +99,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
getStructDefStore(ttr).getAll(),
getClassificationDefStore(ttr).getAll(),
getEntityDefStore(ttr).getAll(),
- getRelationshipDefStore(ttr).getAll());
+ getRelationshipDefStore(ttr).getAll(),
+ getNamespaceDefStore(ttr).getAll());
rectifyTypeErrorsIfAny(typesDef);
@@ -194,6 +197,28 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
@Override
+ public AtlasNamespaceDef getNamespaceDefByName(String name) throws AtlasBaseException {
+ AtlasNamespaceDef ret = typeRegistry.getNamespaceDefByName(name);
+
+ if (ret == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public AtlasNamespaceDef getNamespaceDefByGuid(String guid) throws AtlasBaseException {
+ AtlasNamespaceDef ret = typeRegistry.getNamespaceDefByGuid(guid);
+
+ if (ret == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+ }
+
+ return ret;
+ }
+
+ @Override
@GraphTransaction
public AtlasStructDef updateStructDefByName(String name, AtlasStructDef structDef) throws AtlasBaseException {
AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -325,12 +350,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
@GraphTransaction
public AtlasTypesDef createTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classifications={}, entities={}, relationships={})",
+ LOG.debug("==> AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classifications={}, entities={}, relationships={}, namespaces={})",
CollectionUtils.size(typesDef.getEnumDefs()),
CollectionUtils.size(typesDef.getStructDefs()),
CollectionUtils.size(typesDef.getClassificationDefs()),
CollectionUtils.size(typesDef.getEntityDefs()),
- CollectionUtils.size(typesDef.getRelationshipDefs()));
+ CollectionUtils.size(typesDef.getRelationshipDefs()),
+ CollectionUtils.size(typesDef.getNamespaceDefs()));
}
AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -346,12 +372,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
if (LOG.isDebugEnabled()) {
- LOG.debug("<== AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
+ LOG.debug("<== AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={}, namespaces={})",
CollectionUtils.size(typesDef.getEnumDefs()),
CollectionUtils.size(typesDef.getStructDefs()),
CollectionUtils.size(typesDef.getClassificationDefs()),
CollectionUtils.size(typesDef.getEntityDefs()),
- CollectionUtils.size(typesDef.getRelationshipDefs()));
+ CollectionUtils.size(typesDef.getRelationshipDefs()),
+ CollectionUtils.size(typesDef.getNamespaceDefs()));
}
return ret;
@@ -429,12 +456,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
@GraphTransaction
public AtlasTypesDef updateTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships{})",
+ LOG.debug("==> AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships{}, namespaceDefs={})",
CollectionUtils.size(typesDef.getEnumDefs()),
CollectionUtils.size(typesDef.getStructDefs()),
CollectionUtils.size(typesDef.getClassificationDefs()),
CollectionUtils.size(typesDef.getEntityDefs()),
- CollectionUtils.size(typesDef.getRelationshipDefs()));
+ CollectionUtils.size(typesDef.getRelationshipDefs()),
+ CollectionUtils.size(typesDef.getNamespaceDefs()));
}
AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -459,12 +487,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
if (LOG.isDebugEnabled()) {
- LOG.debug("<== AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
+ LOG.debug("<== AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={}, namespaceDefs={})",
CollectionUtils.size(typesDef.getEnumDefs()),
CollectionUtils.size(typesDef.getStructDefs()),
CollectionUtils.size(typesDef.getClassificationDefs()),
CollectionUtils.size(typesDef.getEntityDefs()),
- CollectionUtils.size(typesDef.getRelationshipDefs()));
+ CollectionUtils.size(typesDef.getRelationshipDefs()),
+ CollectionUtils.size(typesDef.getNamespaceDefs()));
}
return ret;
@@ -475,12 +504,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
@GraphTransaction
public void deleteTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> AtlasTypeDefGraphStore.deleteTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
+ LOG.debug("==> AtlasTypeDefGraphStore.deleteTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={}, namespaceDefs={})",
CollectionUtils.size(typesDef.getEnumDefs()),
CollectionUtils.size(typesDef.getStructDefs()),
CollectionUtils.size(typesDef.getClassificationDefs()),
CollectionUtils.size(typesDef.getEntityDefs()),
- CollectionUtils.size(typesDef.getRelationshipDefs()));
+ CollectionUtils.size(typesDef.getRelationshipDefs()),
+ CollectionUtils.size(typesDef.getNamespaceDefs()));
}
AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -490,6 +520,7 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
AtlasDefStore<AtlasClassificationDef> classifiDefStore = getClassificationDefStore(ttr);
AtlasDefStore<AtlasEntityDef> entityDefStore = getEntityDefStore(ttr);
AtlasDefStore<AtlasRelationshipDef> relationshipDefStore = getRelationshipDefStore(ttr);
+ AtlasDefStore<AtlasNamespaceDef> namespaceDefStore = getNamespaceDefStore(ttr);
List<AtlasVertex> preDeleteStructDefs = new ArrayList<>();
List<AtlasVertex> preDeleteClassifiDefs = new ArrayList<>();
@@ -599,6 +630,16 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
}
+ if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+ for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+ if (StringUtils.isNotBlank(namespaceDef.getGuid())) {
+ namespaceDefStore.deleteByGuid(namespaceDef.getGuid(), null);
+ } else {
+ namespaceDefStore.deleteByName(namespaceDef.getName(), null);
+ }
+ }
+ }
+
// Remove all from
ttr.removeTypesDef(typesDef);
@@ -631,6 +672,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
typesDef.setEnumDefs(Collections.singletonList((AtlasEnumDef) baseTypeDef));
} else if (baseTypeDef instanceof AtlasRelationshipDef) {
typesDef.setRelationshipDefs(Collections.singletonList((AtlasRelationshipDef) baseTypeDef));
+ } else if (baseTypeDef instanceof AtlasNamespaceDef) {
+ typesDef.setNamespaceDefs(Collections.singletonList((AtlasNamespaceDef) baseTypeDef));
} else if (baseTypeDef instanceof AtlasStructDef) {
typesDef.setStructDefs(Collections.singletonList((AtlasStructDef) baseTypeDef));
}
@@ -673,6 +716,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
}
+ for(AtlasNamespaceType namespaceType : typeRegistry.getAllNamespaceTypes()) {
+ if (searchPredicates.evaluate(namespaceType)) {
+ typesDef.getNamespaceDefs().add(namespaceType.getNamespaceDef());
+ }
+ }
+
return typesDef;
}
@@ -712,6 +761,9 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
case RELATIONSHIP:
ret = ((AtlasRelationshipType) type).getRelationshipDef();
break;
+ case NAMESPACE:
+ ret = ((AtlasNamespaceType) type).getNamespaceDef();
+ break;
case PRIMITIVE:
case OBJECT_ID_TYPE:
case ARRAY:
@@ -838,11 +890,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
AtlasDefStore<AtlasClassificationDef> classifiDefStore = getClassificationDefStore(ttr);
AtlasDefStore<AtlasEntityDef> entityDefStore = getEntityDefStore(ttr);
AtlasDefStore<AtlasRelationshipDef> relationshipDefStore = getRelationshipDefStore(ttr);
+ AtlasDefStore<AtlasNamespaceDef> nameSpaceDefStore = getNamespaceDefStore(ttr);
- List<AtlasVertex> preCreateStructDefs = new ArrayList<>();
- List<AtlasVertex> preCreateClassifiDefs = new ArrayList<>();
- List<AtlasVertex> preCreateEntityDefs = new ArrayList<>();
+ List<AtlasVertex> preCreateStructDefs = new ArrayList<>();
+ List<AtlasVertex> preCreateClassifiDefs = new ArrayList<>();
+ List<AtlasVertex> preCreateEntityDefs = new ArrayList<>();
List<AtlasVertex> preCreateRelationshipDefs = new ArrayList<>();
+ List<AtlasVertex> preCreateNamespaceDefs = new ArrayList<>();
// for enumerations run the create
if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
@@ -880,6 +934,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
}
+ if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+ for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+ preCreateNamespaceDefs.add(nameSpaceDefStore.preCreate(namespaceDef));
+ }
+ }
+
if (CollectionUtils.isNotEmpty(typesDef.getStructDefs())) {
int i = 0;
for (AtlasStructDef structDef : typesDef.getStructDefs()) {
@@ -927,17 +987,30 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
}
+ if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+ int i = 0;
+ for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+ AtlasNamespaceDef createdDef = nameSpaceDefStore.create(namespaceDef, preCreateNamespaceDefs.get(i));
+
+ ttr.updateGuid(createdDef.getName(), createdDef.getGuid());
+
+ ret.getNamespaceDefs().add(createdDef);
+ i++;
+ }
+ }
+
return ret;
}
private AtlasTypesDef updateGraphStore(AtlasTypesDef typesDef, AtlasTransientTypeRegistry ttr) throws AtlasBaseException {
AtlasTypesDef ret = new AtlasTypesDef();
- AtlasDefStore<AtlasEnumDef> enumDefStore = getEnumDefStore(ttr);
- AtlasDefStore<AtlasStructDef> structDefStore = getStructDefStore(ttr);
- AtlasDefStore<AtlasClassificationDef> classifiDefStore = getClassificationDefStore(ttr);
- AtlasDefStore<AtlasEntityDef> entityDefStore = getEntityDefStore(ttr);
- AtlasDefStore<AtlasRelationshipDef> relationDefStore = getRelationshipDefStore(ttr);
+ AtlasDefStore<AtlasEnumDef> enumDefStore = getEnumDefStore(ttr);
+ AtlasDefStore<AtlasStructDef> structDefStore = getStructDefStore(ttr);
+ AtlasDefStore<AtlasClassificationDef> classifiDefStore = getClassificationDefStore(ttr);
+ AtlasDefStore<AtlasEntityDef> entityDefStore = getEntityDefStore(ttr);
+ AtlasDefStore<AtlasRelationshipDef> relationDefStore = getRelationshipDefStore(ttr);
+ AtlasDefStore<AtlasNamespaceDef> nameSpaceDefStore = getNamespaceDefStore(ttr);
if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
for (AtlasEnumDef enumDef : typesDef.getEnumDefs()) {
@@ -969,6 +1042,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
}
}
+ if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+ for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+ ret.getNamespaceDefs().add(nameSpaceDefStore.update(namespaceDef));
+ }
+ }
+
return ret;
}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2.java
new file mode 100644
index 0000000..eaaf6bb
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2.java
@@ -0,0 +1,347 @@
+/**
+ * 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.v2;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.authorize.AtlasAuthorizationUtils;
+import org.apache.atlas.authorize.AtlasPrivilege;
+import org.apache.atlas.authorize.AtlasTypeAccessRequest;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.TypeCategory;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.type.AtlasNamespaceType;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
+
+public class AtlasNamespaceDefStoreV2 extends AtlasAbstractDefStoreV2<AtlasNamespaceDef> {
+ private static final Logger LOG = LoggerFactory.getLogger(AtlasNamespaceDefStoreV2.class);
+
+ @Inject
+ public AtlasNamespaceDefStoreV2(AtlasTypeDefGraphStoreV2 typeDefStore, AtlasTypeRegistry typeRegistry) {
+ super(typeDefStore, typeRegistry);
+ }
+
+ @Override
+ public AtlasVertex preCreate(AtlasNamespaceDef namespaceDef) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.preCreate({})", namespaceDef);
+ }
+
+ validateType(namespaceDef);
+
+ AtlasType type = typeRegistry.getType(namespaceDef.getName());
+
+ if (type.getTypeCategory() != TypeCategory.NAMESPACE) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, namespaceDef.getName(),
+ DataTypes.TypeCategory.NAMESPACE.name());
+ }
+
+ AtlasVertex ret = typeDefStore.findTypeVertexByName(namespaceDef.getName());
+
+ if (ret != null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_ALREADY_EXISTS, namespaceDef.getName());
+ }
+
+ ret = typeDefStore.createTypeVertex(namespaceDef);
+
+ updateVertexPreCreate(namespaceDef, (AtlasNamespaceType) type, ret);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.preCreate({}): {}", namespaceDef, ret);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public AtlasNamespaceDef create(AtlasNamespaceDef namespaceDef, AtlasVertex preCreateResult) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.create({}, {})", namespaceDef, preCreateResult);
+ }
+
+ AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_CREATE, namespaceDef), "create namespace-def ", namespaceDef.getName());
+
+ AtlasVertex vertex = (preCreateResult == null) ? preCreate(namespaceDef) : preCreateResult;
+
+ AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.create({}, {}): {}", namespaceDef, preCreateResult, ret);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public List<AtlasNamespaceDef> getAll() throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDef.getAll()");
+ }
+
+ List<AtlasNamespaceDef> ret = new ArrayList<>();
+
+ Iterator<AtlasVertex> vertices = typeDefStore.findTypeVerticesByCategory(DataTypes.TypeCategory.NAMESPACE);
+ while (vertices.hasNext()) {
+ ret.add(toNamespaceDef(vertices.next()));
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.getAll(): count={}", ret.size());
+ }
+ return ret;
+ }
+
+ @Override
+ public AtlasNamespaceDef getByName(String name) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.getByName({})", name);
+ }
+
+ AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, DataTypes.TypeCategory.NAMESPACE);
+
+ if (vertex == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+ }
+
+ vertex.getProperty(Constants.TYPE_CATEGORY_PROPERTY_KEY, String.class);
+
+ AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.getByName({}): {}", name, ret);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public AtlasNamespaceDef getByGuid(String guid) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.getByGuid({})", guid);
+ }
+
+ AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, DataTypes.TypeCategory.NAMESPACE);
+
+ if (vertex == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+ }
+
+ AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.getByGuid({}): {}", guid, ret);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public AtlasNamespaceDef update(AtlasNamespaceDef typeDef) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.update({})", typeDef);
+ }
+
+ validateType(typeDef);
+
+ AtlasNamespaceDef ret = StringUtils.isNotBlank(typeDef.getGuid()) ? updateByGuid(typeDef.getGuid(), typeDef)
+ : updateByName(typeDef.getName(), typeDef);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.update({}): {}", typeDef, ret);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public AtlasNamespaceDef updateByName(String name, AtlasNamespaceDef typeDef) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.updateByName({}, {})", name, typeDef);
+ }
+
+ AtlasNamespaceDef existingDef = typeRegistry.getNamespaceDefByName(name);
+
+ AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update namespace-def ", name);
+
+ validateType(typeDef);
+
+ AtlasType type = typeRegistry.getType(typeDef.getName());
+
+ if (type.getTypeCategory() != TypeCategory.NAMESPACE) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, typeDef.getName(), DataTypes.TypeCategory.NAMESPACE.name());
+ }
+
+ AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, DataTypes.TypeCategory.NAMESPACE);
+
+ if (vertex == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+ }
+
+
+ updateVertexPreUpdate(typeDef, (AtlasNamespaceType)type, vertex);
+
+ AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.updateByName({}, {}): {}", name, typeDef, ret);
+ }
+
+ return ret;
+ }
+
+ public AtlasNamespaceDef updateByGuid(String guid, AtlasNamespaceDef typeDef) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.updateByGuid({})", guid);
+ }
+
+ AtlasNamespaceDef existingDef = typeRegistry.getNamespaceDefByGuid(guid);
+
+ AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update namespace-def ", (existingDef != null ? existingDef.getName() : guid));
+
+ validateType(typeDef);
+
+ AtlasType type = typeRegistry.getTypeByGuid(guid);
+
+ if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.NAMESPACE) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, typeDef.getName(), DataTypes.TypeCategory.NAMESPACE.name());
+ }
+
+ AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, DataTypes.TypeCategory.NAMESPACE);
+
+ if (vertex == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+ }
+
+ updateVertexPreUpdate(typeDef, (AtlasNamespaceType)type, vertex);
+
+ AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.updateByGuid({}): {}", guid, ret);
+ }
+
+ return ret;
+ }
+
+ public AtlasVertex preDeleteByName(String name) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.preDeleteByName({})", name);
+ }
+
+ AtlasNamespaceDef existingDef = typeRegistry.getNamespaceDefByName(name);
+
+ AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete namespace-def ", name);
+
+ AtlasVertex ret = typeDefStore.findTypeVertexByNameAndCategory(name, DataTypes.TypeCategory.NAMESPACE);
+
+ if (ret == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.preDeleteByName({}): {}", name, ret);
+ }
+
+ return ret;
+ }
+
+ public AtlasVertex preDeleteByGuid(String guid) throws AtlasBaseException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> AtlasNamespaceDefStoreV2.preDeleteByGuid({})", guid);
+ }
+
+ AtlasNamespaceDef existingDef = typeRegistry.getNamespaceDefByGuid(guid);
+
+ AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete namespace-def ", (existingDef != null ? existingDef.getName() : guid));
+
+ AtlasVertex ret = typeDefStore.findTypeVertexByGuidAndCategory(guid, DataTypes.TypeCategory.NAMESPACE);
+
+ if (ret == null) {
+ throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== AtlasNamespaceDefStoreV2.preDeleteByGuid({}): ret={}", guid, ret);
+ }
+
+ return ret;
+ }
+
+ private void updateVertexPreCreate(AtlasNamespaceDef namespaceDef, AtlasNamespaceType namespaceType,
+ AtlasVertex vertex) throws AtlasBaseException {
+ AtlasStructDefStoreV2.updateVertexPreCreate(namespaceDef, namespaceType, vertex, typeDefStore);
+ }
+
+ private void updateVertexPreUpdate(AtlasNamespaceDef namespaceDef, AtlasNamespaceType namespaceType,
+ AtlasVertex vertex) throws AtlasBaseException {
+ // Load up current struct definition for matching attributes
+ AtlasNamespaceDef currentNamespaceDef = toNamespaceDef(vertex);
+
+ // Check to verify that in an update call we only allow addition of new entity types, not deletion of existing
+ // entity types
+ if (CollectionUtils.isNotEmpty(namespaceDef.getAttributeDefs())) {
+ for (AtlasStructDef.AtlasAttributeDef attributeDef : namespaceDef.getAttributeDefs()) {
+ String updatedApplicableEntityTypesString = attributeDef.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+ Set<String> updatedApplicableEntityTypes = StringUtils.isBlank(updatedApplicableEntityTypesString) ? null : AtlasType.fromJson(updatedApplicableEntityTypesString, Set.class);
+
+ AtlasStructDef.AtlasAttributeDef existingAttribute = currentNamespaceDef.getAttribute(attributeDef.getName());
+ if (existingAttribute != null) {
+ String existingApplicableEntityTypesString = existingAttribute.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+ Set<String> existingApplicableEntityTypes = StringUtils.isBlank(existingApplicableEntityTypesString) ? null : AtlasType.fromJson(existingApplicableEntityTypesString, Set.class);
+
+ if (existingApplicableEntityTypes != null) {
+ if (!updatedApplicableEntityTypes.containsAll(existingApplicableEntityTypes)) {
+ throw new AtlasBaseException(AtlasErrorCode.APPLICABLE_ENTITY_TYPES_DELETION_NOT_SUPPORTED,
+ attributeDef.getName(), namespaceDef.getName());
+ }
+ }
+ }
+ }
+ }
+
+ AtlasStructDefStoreV2.updateVertexPreUpdate(namespaceDef, namespaceType, vertex, typeDefStore);
+ }
+
+ private AtlasNamespaceDef toNamespaceDef(AtlasVertex vertex) throws AtlasBaseException {
+ AtlasNamespaceDef ret = null;
+
+ if (vertex != null && typeDefStore.isTypeVertex(vertex, DataTypes.TypeCategory.NAMESPACE)) {
+ ret = new AtlasNamespaceDef();
+
+ AtlasStructDefStoreV2.toStructDef(vertex, ret, typeDefStore);
+ }
+
+ return ret;
+ }
+}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java
index a5ccfb5..afdfba9 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java
@@ -19,17 +19,6 @@ package org.apache.atlas.repository.store.graph.v2;
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.v2.AtlasGraphUtilsV2.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.RequestContext;
import org.apache.atlas.annotation.GraphTransaction;
@@ -37,8 +26,12 @@ import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.listener.TypeDefChangeListener;
import org.apache.atlas.model.typedef.*;
import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.graphdb.*;
-import org.apache.atlas.repository.store.graph.*;
+import org.apache.atlas.repository.graphdb.AtlasEdge;
+import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
+import org.apache.atlas.repository.graphdb.AtlasGraph;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.AtlasDefStore;
+import org.apache.atlas.repository.store.graph.AtlasTypeDefGraphStore;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
@@ -50,6 +43,16 @@ import org.springframework.stereotype.Component;
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.v2.AtlasGraphUtilsV2.VERTEX_TYPE;
/**
@@ -97,6 +100,10 @@ public class AtlasTypeDefGraphStoreV2 extends AtlasTypeDefGraphStore {
return new AtlasRelationshipDefStoreV2(this, typeRegistry);
}
+ @Override
+ protected AtlasDefStore<AtlasNamespaceDef> getNamespaceDefStore(AtlasTypeRegistry typeRegistry) {
+ return new AtlasNamespaceDefStoreV2(this, typeRegistry);
+ }
@Override
@GraphTransaction
@@ -490,6 +497,9 @@ public class AtlasTypeDefGraphStoreV2 extends AtlasTypeDefGraphStore {
case RELATIONSHIP:
return TypeCategory.RELATIONSHIP;
+
+ case NAMESPACE:
+ return TypeCategory.NAMESPACE;
}
return null;
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2Test.java
new file mode 100644
index 0000000..1d6534e
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2Test.java
@@ -0,0 +1,319 @@
+/**
+ * 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.v2;
+
+import com.google.inject.Inject;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasNamespaceType;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.*;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
+import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.*;
+
+/* Please note that for these tests, since the typeRegistry can be injected only once,
+ * any new tests should make sure that they flush the type registry at the end of the test.
+ * testNG does not provide a way to execute a method after each test has completed the run, hence
+ * we have to manually make sure that the flushTypeRegistry method is invoked.
+ */
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class AtlasNamespaceDefStoreV2Test {
+
+ @Inject
+ AtlasTypeRegistry typeRegistry;
+
+ @Inject
+ private AtlasTypeDefGraphStoreV2 typeDefStore;
+
+ private AtlasTypesDef typesDefs;
+
+ private static int randomCount;
+ private static final String TEST_NAMESPACE = "test_namespace";
+ private String namespaceName;
+ @BeforeClass
+ public void setup() throws IOException, AtlasBaseException {
+ loadBaseModel(typeDefStore, typeRegistry);
+ loadFsModel(typeDefStore, typeRegistry);
+ loadHiveModel(typeDefStore, typeRegistry);
+
+ typesDefs = new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+
+ namespaceName = TEST_NAMESPACE;
+
+ randomCount = 1;
+ }
+
+ @BeforeMethod
+ public void setTypeDefs() {
+ typesDefs = new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+ randomCount++;
+ namespaceName = TEST_NAMESPACE + randomCount;
+ }
+
+ @Test
+ public void createNamespaceTypeDef() throws AtlasBaseException {
+ createNamespaceTypes(namespaceName);
+ Assert.assertEquals(typeRegistry.getAllNamespaceDefs().size(), 1);
+ AtlasEntityType entityType = typeRegistry.getEntityTypeByName("hive_table");
+ Map<String, List<AtlasNamespaceType.AtlasNamespaceAttribute>> m1 = entityType.getNamespaceAttributes();
+ Assert.assertEquals(m1.get(namespaceName).size(), 2);
+ }
+
+ @Test
+ public void deleteNamespaceTypeDefs() throws AtlasBaseException {
+ createNamespaceTypes(namespaceName);
+ for (AtlasNamespaceDef atlasNamespaceDef : typesDefs.getNamespaceDefs()) {
+ if (atlasNamespaceDef.getName().equals(namespaceName)) {
+ typesDefs = new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),
+ Collections.emptyList());
+ typesDefs.setNamespaceDefs(Arrays.asList(atlasNamespaceDef));
+ typeDefStore.deleteTypesDef(typesDefs);
+ }
+ }
+
+ for (AtlasNamespaceDef namespaceDef : typeRegistry.getAllNamespaceDefs()) {
+ Assert.assertNotEquals(namespaceDef.getName(), namespaceName);
+ }
+ }
+
+ @Test
+ public void updateNamespaceTypeDefs() throws AtlasBaseException {
+ createNamespaceTypes(namespaceName);
+ AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+ Assert.assertNotNull(namespaceDef);
+
+ addNamespaceAttribute(namespaceDef, "test_namespace_attribute3", Collections.singleton("hive_table"),
+ String.format("array<%s>", "string"), AtlasStructDef.AtlasAttributeDef.Cardinality.LIST);
+
+ updateNamespaceTypeDefs(namespaceDef);
+ typeDefStore.updateTypesDef(typesDefs);
+ AtlasEntityType entityType = typeRegistry.getEntityTypeByName("hive_table");
+ Map<String, List<AtlasNamespaceType.AtlasNamespaceAttribute>> m1 = entityType.getNamespaceAttributes();
+ Assert.assertEquals(m1.get(namespaceName).size(), 3);
+ }
+
+ /**
+ * Test to verify that we cannot delete attribute defs from a namespace definition
+ * @throws AtlasBaseException
+ */
+ @Test
+ public void updateTypeDefsWithoutApplicableEntityTypes() throws AtlasBaseException {
+ createNamespaceTypes(namespaceName);
+ AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+ Assert.assertNotNull(namespaceDef);
+
+ AtlasStructDef.AtlasAttributeDef namespaceAttributeDef = namespaceDef.getAttributeDefs().iterator().next();
+ namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef));
+
+ AtlasTypesDef existingTypeDefs = typesDefs;
+
+ try {
+ typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef));
+ typeDefStore.updateTypesDef(typesDefs);
+ } catch (AtlasBaseException e) {
+ Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.ATTRIBUTE_DELETION_NOT_SUPPORTED);
+ } finally {
+ typesDefs = existingTypeDefs;
+ }
+ }
+
+ @Test
+ public void updateTypeDefsDeleteApplicableEntityTypes() throws AtlasBaseException {
+ createNamespaceTypes(namespaceName);
+ AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+ Assert.assertNotNull(namespaceDef);
+
+ Iterator<AtlasStructDef.AtlasAttributeDef> it = namespaceDef.getAttributeDefs().iterator();
+ AtlasStructDef.AtlasAttributeDef namespaceAttributeDef = it.next();
+ AtlasStructDef.AtlasAttributeDef namespaceAttributeDef2 = it.next();
+
+ namespaceAttributeDef.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.emptySet()));
+
+ namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef, namespaceAttributeDef2));
+
+ AtlasTypesDef existingTypeDefs = typesDefs;
+
+ try {
+ typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef));
+ typeDefStore.updateTypesDef(typesDefs);
+ } catch (AtlasBaseException e) {
+ Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE);
+ } finally {
+ typesDefs = existingTypeDefs;
+ }
+ }
+
+ /**
+ * Test to verify that we cannot have an empty applicable entity types in an attribute definition
+ * @throws AtlasBaseException
+ */
+ @Test
+ public void createNsAttrDefWithoutApplicableEntityTypes() {
+ AtlasTypesDef existingTypeDefs = typesDefs;
+
+ try {
+ typesDefs.setNamespaceDefs(Arrays.asList(createNamespaceDef2(namespaceName)));
+ typeDefStore.updateTypesDef(typesDefs);
+ } catch (AtlasBaseException e) {
+ Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE);
+ } finally {
+ typesDefs = existingTypeDefs;
+ }
+ }
+
+ @Test
+ public void updateNsAttrDefDeleteApplicableEntityTypes() throws AtlasBaseException {
+ createNamespaceTypes(namespaceName);
+
+ AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+ Assert.assertNotNull(namespaceDef);
+
+ Iterator<AtlasStructDef.AtlasAttributeDef> it = namespaceDef.getAttributeDefs().iterator();
+ AtlasStructDef.AtlasAttributeDef namespaceAttributeDef = it.next();
+ AtlasStructDef.AtlasAttributeDef namespaceAttributeDef2 = it.next();
+
+ namespaceAttributeDef.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+
+ namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef, namespaceAttributeDef2));
+
+ AtlasTypesDef existingTypeDefs = typesDefs;
+
+ try {
+ typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef));
+ typeDefStore.updateTypesDef(typesDefs);
+ } catch (AtlasBaseException e) {
+ Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.APPLICABLE_ENTITY_TYPES_DELETION_NOT_SUPPORTED);
+ } finally {
+ typesDefs = existingTypeDefs;
+ }
+ }
+
+ @Test
+ public void updateNsAttrDefAddApplicableEntityTypes() throws AtlasBaseException {
+ createNamespaceTypes(namespaceName);
+
+ AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+ AtlasStructDef.AtlasAttributeDef namespaceAttributeDef1 = namespaceDef.getAttributeDefs().get(0);
+ AtlasStructDef.AtlasAttributeDef namespaceAttributeDef2 = namespaceDef.getAttributeDefs().get(1);
+ Set<String> applicableEntityTypes = AtlasType.fromJson(namespaceAttributeDef1.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES), Set.class);
+
+ if (applicableEntityTypes == null) {
+ applicableEntityTypes = new HashSet<>();
+ }
+
+ applicableEntityTypes.add("hive_column");
+ namespaceAttributeDef1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(applicableEntityTypes));
+ namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef1, namespaceAttributeDef2));
+
+ updateNamespaceTypeDefs(namespaceDef);
+
+ typeDefStore.updateTypesDef(typesDefs);
+
+ namespaceDef = findNamespaceDef(namespaceName);
+ namespaceAttributeDef1 = namespaceDef.getAttributeDefs().get(0);
+
+ applicableEntityTypes = AtlasType.fromJson(namespaceAttributeDef1.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES), Set.class);
+
+ Assert.assertEquals(applicableEntityTypes == null ? 0 : applicableEntityTypes.size(), 3);
+ }
+
+ @Test
+ public void validateMaxStringLengthForStringTypes() throws AtlasBaseException {
+ AtlasTypesDef existingTypeDefs = typesDefs;
+ AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef(namespaceName, "test_description", null);
+ addNamespaceAttribute(namespaceDef1, "test_namespace_attribute1", new HashSet<>(Arrays.asList("hive_table", "fs_path")), "string",
+ AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+ typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef1));
+ try {
+ typeDefStore.createTypesDef(typesDefs);
+ } catch (AtlasBaseException exception) {
+ Assert.assertEquals(exception.getAtlasErrorCode(), AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE);
+ } finally {
+ typesDefs = existingTypeDefs;
+ }
+ }
+
+ private AtlasNamespaceDef createNamespaceDef(String namespaceName) {
+ AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef(namespaceName, "test_description", null);
+ addNamespaceAttribute(namespaceDef1, "test_namespace_attribute1", new HashSet<>(Arrays.asList("hive_table", "fs_path")), "int",
+ AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+ addNamespaceAttribute(namespaceDef1, "test_namespace_attribute2", Collections.singleton("hive_table"), "int",
+ AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+ return namespaceDef1;
+ }
+
+ private AtlasNamespaceDef createNamespaceDef2(String namespaceName) {
+ AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef(namespaceName, "test_description", null);
+ addNamespaceAttribute(namespaceDef1, "test_namespace_attribute1", Collections.emptySet(), "int",
+ AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+ addNamespaceAttribute(namespaceDef1, "test_namespace_attribute2", Collections.singleton("hive_table"), "int",
+ AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+ return namespaceDef1;
+ }
+
+ private void createNamespaceTypes(String namespaceName) throws AtlasBaseException {
+ List<AtlasNamespaceDef> namespaceDefs = new ArrayList(typesDefs.getNamespaceDefs());
+ namespaceDefs.add(createNamespaceDef(namespaceName));
+ typesDefs.setNamespaceDefs(namespaceDefs);
+ typeDefStore.createTypesDef(typesDefs);
+ }
+
+ private void addNamespaceAttribute(AtlasNamespaceDef namespaceDef, String name, Set<String> applicableEntityTypes,
+ String typeName, AtlasStructDef.AtlasAttributeDef.Cardinality cardinality) {
+ AtlasStructDef.AtlasAttributeDef attributeDef = new AtlasStructDef.AtlasAttributeDef(name, typeName);
+
+ attributeDef.setCardinality(cardinality);
+ attributeDef.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(applicableEntityTypes));
+ attributeDef.setIsOptional(true);
+ attributeDef.setIsUnique(false);
+
+ namespaceDef.addAttribute(attributeDef);
+ }
+
+ private AtlasNamespaceDef findNamespaceDef(String namespaceName) {
+ for (AtlasNamespaceDef atlasNamespaceDef : typesDefs.getNamespaceDefs()) {
+ if (atlasNamespaceDef.getName().equals(namespaceName)) {
+ return atlasNamespaceDef;
+ }
+ }
+
+ return null;
+ }
+
+ private void updateNamespaceTypeDefs(AtlasNamespaceDef atlasNamespaceDef) {
+ for (int i = 0; i < typesDefs.getNamespaceDefs().size(); i++) {
+ if (typesDefs.getNamespaceDefs().get(i).getName().equals(namespaceName)) {
+ typesDefs.getNamespaceDefs().set(i, atlasNamespaceDef);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
index 6cd0ee3..72f5bef 100755
--- a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
+++ b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
@@ -19,7 +19,6 @@
package org.apache.atlas.examples;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasClientV2;
@@ -40,10 +39,12 @@ import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection;
import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageRelation;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
-import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.model.typedef.AtlasTypesDef;
-import org.apache.atlas.repository.Constants;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
+import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.collections.CollectionUtils;
@@ -55,6 +56,7 @@ import java.util.*;
import static java.util.Arrays.asList;
import static org.apache.atlas.AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME;
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
import static org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory.AGGREGATION;
import static org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory.COMPOSITION;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality.SET;
@@ -316,7 +318,25 @@ public class QuickStartV2 {
List<AtlasRelationshipDef> relationshipDefs = asList(tableDatabaseTypeDef, viewDatabaseTypeDef, viewTablesTypeDef, tableColumnsTypeDef, tableStorageDescTypeDef, processProcessExecutionTypeDef);
List<AtlasClassificationDef> classificationDefs = asList(dimClassifDef, factClassifDef, piiClassifDef, metricClassifDef, etlClassifDef, jdbcClassifDef, logClassifDef);
- return new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), classificationDefs, entityDefs, relationshipDefs);
+ // Namespace definitions
+ AtlasAttributeDef nsAttrDef1 = new AtlasAttributeDef("attr1", "int");
+ AtlasAttributeDef nsAttrDef2 = new AtlasAttributeDef("attr2", "int");
+
+ nsAttrDef1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(TABLE_TYPE)));
+ nsAttrDef1.setIsOptional(true);
+ nsAttrDef1.setIsUnique(false);
+
+ nsAttrDef2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(TABLE_TYPE)));
+ nsAttrDef2.setIsOptional(true);
+ nsAttrDef2.setIsUnique(false);
+
+ AtlasNamespaceDef testNamespaceDef = new AtlasNamespaceDef("test_namespace", "test_description", VERSION_1);
+
+ testNamespaceDef.setAttributeDefs(Arrays.asList(nsAttrDef1, nsAttrDef2));
+
+ List<AtlasNamespaceDef> namespaceDefs = asList(testNamespaceDef);
+
+ return new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), classificationDefs, entityDefs, relationshipDefs, namespaceDefs);
}
void createEntities() throws Exception {
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java
index fb56fad..e7cf62d 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java
@@ -23,6 +23,7 @@ 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.AtlasNamespaceDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
@@ -317,6 +318,43 @@ public class TypesREST {
return ret;
}
+
+ /**
+ * Get the namespace definition for the given guid
+ * @param guid namespace guid
+ * @return namespace definition
+ * @throws AtlasBaseException
+ * @HTTP 200 On successful lookup of the the namespace definition by it's guid
+ * @HTTP 404 On Failed lookup for the given guid
+ */
+ @GET
+ @Path("/namespacedef/guid/{guid}")
+ public AtlasNamespaceDef getNamespaceDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
+ Servlets.validateQueryParamLength("guid", guid);
+
+ AtlasNamespaceDef ret = typeDefStore.getNamespaceDefByGuid(guid);
+
+ return ret;
+ }
+
+ /**
+ * Get the namespace definition by it's name (unique)
+ * @param name namespace name
+ * @return namespace definition
+ * @throws AtlasBaseException
+ * @HTTP 200 On successful lookup of the the namespace definition by it's name
+ * @HTTP 404 On Failed lookup for the given name
+ */
+ @GET
+ @Path("/namespacedef/name/{name}")
+ public AtlasNamespaceDef getNamespaceDefByName(@PathParam("name") String name) throws AtlasBaseException {
+ Servlets.validateQueryParamLength("name", name);
+
+ AtlasNamespaceDef ret = typeDefStore.getNamespaceDefByName(name);
+
+ return ret;
+ }
+
/* Bulk API operation */
/**