You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ra...@apache.org on 2026/06/12 21:12:25 UTC
(atlas) branch atlas-2.6 updated: ATLAS-5310: Export/Import API : When tag attributes types get modified between th… (#662)
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch atlas-2.6
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/atlas-2.6 by this push:
new 9db78b95e ATLAS-5310: Export/Import API : When tag attributes types get modified between th… (#662)
9db78b95e is described below
commit 9db78b95e1b6a750bb7b77fd87b4b4ef0a1787dc
Author: saksenasonali <37...@users.noreply.github.com>
AuthorDate: Sat Jun 13 02:41:00 2026 +0530
ATLAS-5310: Export/Import API : When tag attributes types get modified between th… (#662)
Co-authored-by: ssaksena <ss...@cloudera.com>
(cherry picked from commit ac00c0f983b64cddace745e806750c7057abd867)
---
.../repository/graphdb/AtlasGraphManagement.java | 7 ++++++
.../graphdb/janus/AtlasJanusGraphManagement.java | 9 ++++++++
.../repository/graph/GraphBackedSearchIndexer.java | 9 ++++++++
.../repository/impexp/TypeAttributeDifference.java | 10 ++++----
.../store/graph/v2/AtlasStructDefStoreV2.java | 27 ++++++++++++++++++----
.../atlas/repository/impexp/ImportServiceTest.java | 17 ++++++--------
.../impexp/TypeAttributeDifferenceTest.java | 15 ++++++++++++
7 files changed, 74 insertions(+), 20 deletions(-)
diff --git a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java
index 7a3ca74c2..55f2d7629 100644
--- a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java
+++ b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphManagement.java
@@ -47,6 +47,13 @@ public interface AtlasGraphManagement extends AutoCloseable {
*/
AtlasEdgeLabel makeEdgeLabel(String label);
+ /**
+ * @param propertyName
+ * @param dataType
+ * @return true if the property key exists and has the given data type
+ */
+ boolean propertyKeyHasDataType(String propertyName, Class<?> dataType);
+
/**
* @param propertyKey
*
diff --git a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java
index bc3b25cdb..824733e01 100644
--- a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java
+++ b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraphManagement.java
@@ -210,6 +210,15 @@ public class AtlasJanusGraphManagement implements AtlasGraphManagement {
return GraphDbObjectFactory.createEdgeLabel(edgeLabel);
}
+ @Override
+ public boolean propertyKeyHasDataType(String propertyName, Class<?> dataType) {
+ checkName(propertyName);
+
+ PropertyKey janusPropertyKey = management.getPropertyKey(propertyName);
+
+ return janusPropertyKey != null && janusPropertyKey.dataType().equals(dataType);
+ }
+
@Override
public void deletePropertyKey(String propertyKey) {
PropertyKey janusPropertyKey = management.getPropertyKey(propertyKey);
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 addeb3d0c..03bb953af 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
@@ -21,6 +21,7 @@ package org.apache.atlas.repository.graph;
import com.google.common.annotations.VisibleForTesting;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasException;
+import org.apache.atlas.RequestContext;
import org.apache.atlas.discovery.SearchIndexer;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.ha.HAConfiguration;
@@ -439,6 +440,14 @@ public class GraphBackedSearchIndexer implements SearchIndexer, ActiveStateChang
if (propertyName != null) {
AtlasPropertyKey propertyKey = management.getPropertyKey(propertyName);
+ if (propertyKey != null && RequestContext.get().isImportInProgress()
+ && !management.propertyKeyHasDataType(propertyName, propertyClass)) {
+ LOG.info("Recreating property key {} during import; data type changed to {}", propertyName, propertyClass.getName());
+
+ management.deletePropertyKey(propertyName);
+ propertyKey = null;
+ }
+
if (propertyKey == null) {
propertyKey = management.makePropertyKey(propertyName, propertyClass, cardinality);
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/TypeAttributeDifference.java b/repository/src/main/java/org/apache/atlas/repository/impexp/TypeAttributeDifference.java
index a3885810f..070932d5a 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/TypeAttributeDifference.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/TypeAttributeDifference.java
@@ -18,7 +18,6 @@
package org.apache.atlas.repository.impexp;
import com.google.common.annotations.VisibleForTesting;
-import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.impexp.AtlasImportResult;
import org.apache.atlas.model.typedef.AtlasBusinessMetadataDef;
@@ -170,12 +169,11 @@ public class TypeAttributeDifference {
if (relationshipType == null) {
difference.add(incoming);
}
- } else {
- if (!existingAttribute.getTypeName().equals(incoming.getTypeName())) {
- LOG.error("Attribute definition difference found: {}, {}", existingAttribute, incoming);
+ } else if (!existingAttribute.getTypeName().equals(incoming.getTypeName())) {
+ LOG.info("Attribute type changed for {}.{}: {} -> {}; updating typedef during import",
+ existing.getName(), existingAttribute.getName(), existingAttribute.getTypeName(), incoming.getTypeName());
- throw new AtlasBaseException(AtlasErrorCode.INVALID_IMPORT_ATTRIBUTE_TYPE_CHANGED, existing.getName(), existingAttribute.getName(), existingAttribute.getTypeName(), incoming.getTypeName());
- }
+ difference.add(incoming);
}
}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java
index c26d1c347..e187b0f26 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasStructDefStoreV2.java
@@ -177,7 +177,18 @@ public class AtlasStructDefStoreV2 extends AtlasAbstractDefStoreV2<AtlasStructDe
AtlasAttributeDef existingAttribute = currentStructDef.getAttribute(attributeDef.getName());
if (null != existingAttribute && !attributeDef.getTypeName().equals(existingAttribute.getTypeName())) {
- throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Data type update for attribute is not supported");
+ if (!RequestContext.get().isImportInProgress()) {
+ throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Data type update for attribute is not supported");
+ }
+
+ LOG.info("Updating attribute type during import: {}.{} from {} to {}",
+ structDef.getName(), attributeDef.getName(), existingAttribute.getTypeName(), attributeDef.getTypeName());
+
+ String propertyKey = AtlasGraphUtilsV2.getTypeDefPropertyKey(structDef, attributeDef.getName());
+
+ AtlasGraphUtilsV2.setProperty(vertex, propertyKey, toJsonFromAttributeDef(attributeDef));
+
+ continue;
}
String propertyKey = AtlasGraphUtilsV2.getTypeDefPropertyKey(structDef, attributeDef.getName());
@@ -237,7 +248,15 @@ public class AtlasStructDefStoreV2 extends AtlasAbstractDefStoreV2<AtlasStructDe
@VisibleForTesting
public static String toJsonFromAttribute(AtlasAttribute attribute) {
- AtlasAttributeDef attributeDef = attribute.getAttributeDef();
+ return toJsonFromAttributeDef(attribute.getAttributeDef(), attribute.isOwnedRef(), attribute.getInverseRefAttributeName());
+ }
+
+ @VisibleForTesting
+ public static String toJsonFromAttributeDef(AtlasAttributeDef attributeDef) {
+ return toJsonFromAttributeDef(attributeDef, false, null);
+ }
+
+ private static String toJsonFromAttributeDef(AtlasAttributeDef attributeDef, boolean isComposite, String reverseAttributeName) {
Map<String, Object> attribInfo = new HashMap<>();
attribInfo.put("name", attributeDef.getName());
@@ -245,8 +264,8 @@ public class AtlasStructDefStoreV2 extends AtlasAbstractDefStoreV2<AtlasStructDe
attribInfo.put("isUnique", attributeDef.getIsUnique());
attribInfo.put("isIndexable", attributeDef.getIsIndexable());
attribInfo.put("includeInNotification", attributeDef.getIncludeInNotification());
- attribInfo.put("isComposite", attribute.isOwnedRef());
- attribInfo.put("reverseAttributeName", attribute.getInverseRefAttributeName());
+ attribInfo.put("isComposite", isComposite);
+ attribInfo.put("reverseAttributeName", reverseAttributeName);
attribInfo.put("defaultValue", attributeDef.getDefaultValue());
attribInfo.put("description", attributeDef.getDescription());
attribInfo.put("searchWeight", attributeDef.getSearchWeight());
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
index 6f461cf2c..bef2de68f 100644
--- a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
@@ -364,21 +364,18 @@ public class ImportServiceTest extends AtlasTestBase {
assertEntityCount("AtlasGlossaryTerm", "105533b6-c125-4a87-bed5-cdf67fb68c39", 1);
}
- @Test(dataProvider = "hdfs_path1", expectedExceptions = AtlasBaseException.class)
+ @Test(dataProvider = "hdfs_path1")
public void importHdfs_path1(InputStream inputStream) throws IOException, AtlasBaseException {
loadBaseModel();
loadFsModel();
loadModelFromResourcesJson("tag1.json", typeDefStore, typeRegistry);
- try {
- runImportWithNoParameters(importService, inputStream);
- } catch (AtlasBaseException e) {
- assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INVALID_IMPORT_ATTRIBUTE_TYPE_CHANGED);
- AtlasClassificationType tag1 = typeRegistry.getClassificationTypeByName("tag1");
- assertNotNull(tag1);
- assertEquals(tag1.getAllAttributes().size(), 2);
- throw e;
- }
+ runImportWithNoParameters(importService, inputStream);
+
+ AtlasClassificationType tag1 = typeRegistry.getClassificationTypeByName("tag1");
+ assertNotNull(tag1);
+ assertEquals(tag1.getAttribute("attrib1").getAttributeDef().getTypeName(), "string");
+ assertNotNull(tag1.getAttribute("attrib2"));
}
@Test(dataProvider = "zip-direct-3", expectedExceptions = AtlasBaseException.class)
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/TypeAttributeDifferenceTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/TypeAttributeDifferenceTest.java
index 85ba6bd10..53164a9a8 100644
--- a/repository/src/test/java/org/apache/atlas/repository/impexp/TypeAttributeDifferenceTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/TypeAttributeDifferenceTest.java
@@ -88,6 +88,21 @@ public class TypeAttributeDifferenceTest {
assertEquals(actualAttributes, expectedAttributes);
}
+ @Test
+ public void attributeTypeChanged_ReturnsUpdatedAttribute() throws Exception {
+ AtlasEntityDef existing = getAtlasEntityDefWithAttributes("name");
+ AtlasEntityDef incoming = new AtlasEntityDef();
+ AtlasStructDef.AtlasAttributeDef nameAttr = new AtlasStructDef.AtlasAttributeDef("name", AtlasBaseTypeDef.ATLAS_TYPE_DOUBLE);
+ List<AtlasStructDef.AtlasAttributeDef> expectedAttributes = new ArrayList<>();
+
+ incoming.addAttribute(nameAttr);
+ expectedAttributes.add(nameAttr);
+
+ List<AtlasStructDef.AtlasAttributeDef> actualAttributes = invokeGetAttributesAbsentInExisting(existing, incoming);
+
+ assertEquals(actualAttributes, expectedAttributes);
+ }
+
@Test
public void differentSubset_ReturnsDifference() throws Exception {
AtlasEntityDef existing = getAtlasEntityDefWithAttributes("name", "qualifiedName");