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 <[email protected]>
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 <[email protected]>
    (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");

Reply via email to