You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2018/01/04 22:01:14 UTC

atlas git commit: ATLAS-2332: support for attributes having nested collection datatype

Repository: atlas
Updated Branches:
  refs/heads/branch-0.8 574e3b786 -> 3d33261dd


ATLAS-2332: support for attributes having nested collection datatype


Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/3d33261d
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/3d33261d
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/3d33261d

Branch: refs/heads/branch-0.8
Commit: 3d33261dd152c98c2a455140b75ed6a1729a1287
Parents: 574e3b7
Author: Madhan Neethiraj <ma...@apache.org>
Authored: Wed Jan 3 00:58:19 2018 -0800
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Wed Jan 3 15:57:10 2018 -0800

----------------------------------------------------------------------
 .../test/java/org/apache/atlas/TestUtilsV2.java | 145 +++++++++++++++++++
 .../atlas/repository/graph/GraphHelper.java     |   4 +-
 .../graph/GraphToTypedInstanceMapper.java       |   4 +-
 .../store/graph/v1/EntityGraphMapper.java       |   8 +-
 .../store/graph/v1/EntityGraphRetriever.java    |   4 +-
 .../store/graph/AtlasTypeDefGraphStoreTest.java |  15 ++
 .../store/graph/v1/AtlasEntityStoreV1Test.java  |  13 +-
 .../atlas/typesystem/types/TypeUtils.java       |  36 ++++-
 .../typesystem/types/TypedStructHandler.java    |  15 ++
 9 files changed, 228 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
index 25d502b..8470054 100755
--- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
@@ -543,6 +543,7 @@ public final class TestUtilsV2 {
     public static final String SERDE_TYPE = "serdeType";
     public static final String COLUMNS_MAP = "columnsMap";
     public static final String COLUMNS_ATTR_NAME = "columns";
+    public static final String ENTITY_TYPE_WITH_NESTED_COLLECTION_ATTR = "entity_with_nested_collection_attr";
 
     public static final String NAME = "name";
 
@@ -835,6 +836,150 @@ public final class TestUtilsV2 {
         return ret;
     }
 
+    public static AtlasTypesDef defineTypeWithNestedCollectionAttributes() {
+        AtlasEntityDef nestedCollectionAttributesEntityType =
+                AtlasTypeUtil.createClassTypeDef(ENTITY_TYPE_WITH_NESTED_COLLECTION_ATTR, ENTITY_TYPE_WITH_NESTED_COLLECTION_ATTR + "_description", null,
+                        AtlasTypeUtil.createUniqueRequiredAttrDef("name", "string"),
+
+                        new AtlasAttributeDef("mapOfArrayOfStrings", "map<string,array<string>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfArrayOfBooleans", "map<string,array<boolean>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfArrayOfInts", "map<string,array<int>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfArrayOfFloats", "map<string,array<float>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfArrayOfDates", "map<string,array<date>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+
+                        new AtlasAttributeDef("mapOfMapOfStrings", "map<string,map<string,string>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfMapOfBooleans", "map<string,map<string,boolean>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfMapOfInts", "map<string,map<string,int>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfMapOfFloats", "map<string,map<string,float>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("mapOfMapOfDates", "map<string,map<string,date>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+
+                        new AtlasAttributeDef("arrayOfArrayOfStrings", "array<array<string>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfArrayOfBooleans", "array<array<boolean>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfArrayOfInts", "array<array<int>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfArrayOfFloats", "array<array<float>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfArrayOfDates", "array<array<date>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+
+                        new AtlasAttributeDef("arrayOfMapOfStrings", "array<map<string,string>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfMapOfBooleans", "array<map<string,boolean>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfMapOfInts", "array<map<string,int>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfMapOfFloats", "array<map<string,float>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList()),
+                        new AtlasAttributeDef("arrayOfMapOfDates", "array<map<string,date>>", false,
+                                AtlasAttributeDef.Cardinality.SINGLE, 1, 1,
+                                false, false,
+                                Collections.<AtlasConstraintDef>emptyList())
+                );
+
+        AtlasTypesDef ret = AtlasTypeUtil.getTypesDef(ImmutableList.<AtlasEnumDef>of(),
+                                                      ImmutableList.<AtlasStructDef>of(),
+                                                      ImmutableList.<AtlasClassificationDef>of(),
+                                                      ImmutableList.of(nestedCollectionAttributesEntityType));
+
+        populateSystemAttributes(ret);
+
+        return ret;
+    }
+
+    public static AtlasEntityWithExtInfo createNestedCollectionAttrEntity() {
+        AtlasEntity entity = new AtlasEntity(ENTITY_TYPE_WITH_NESTED_COLLECTION_ATTR);
+
+        String[]  arrayOfStrings  = new String[] { "one", "two", "three" };
+        boolean[] arrayOfBooleans = new boolean[] { false, true };
+        int[]     arrayOfInts     = new int[] { 1, 2, 3 };
+        float[]   arrayOfFloats   = new float[] { 1.1f, 2.2f, 3.3f };
+        Date[]    arrayOfDates    = new Date[] { new Date() };
+
+        Map<String, String>  mapOfStrings  = Collections.singletonMap("one", "one");
+        Map<String, Boolean> mapOfBooleans = Collections.singletonMap("one", true);
+        Map<String, Integer> mapOfInts     = Collections.singletonMap("one", 1);
+        Map<String, Float>   mapOfFloats   = Collections.singletonMap("one", 1.1f);
+        Map<String, Date>    mapOfDates    = Collections.singletonMap("now", new Date());
+
+        entity.setAttribute("name", randomString() + "_" + System.currentTimeMillis());
+
+        entity.setAttribute("mapOfArrayOfStrings", Collections.singletonMap("one", arrayOfStrings));
+        entity.setAttribute("mapOfArrayOfBooleans", Collections.singletonMap("one", arrayOfBooleans));
+        entity.setAttribute("mapOfArrayOfInts", Collections.singletonMap("one", arrayOfInts));
+        entity.setAttribute("mapOfArrayOfFloats", Collections.singletonMap("one", arrayOfFloats));
+        entity.setAttribute("mapOfArrayOfDates", Collections.singletonMap("one", arrayOfDates));
+
+        entity.setAttribute("mapOfMapOfStrings", Collections.singletonMap("one", mapOfStrings));
+        entity.setAttribute("mapOfMapOfBooleans", Collections.singletonMap("one", mapOfBooleans));
+        entity.setAttribute("mapOfMapOfInts", Collections.singletonMap("one", mapOfInts));
+        entity.setAttribute("mapOfMapOfFloats", Collections.singletonMap("one", mapOfFloats));
+        entity.setAttribute("mapOfMapOfDates", Collections.singletonMap("one", mapOfDates));
+
+        entity.setAttribute("arrayOfArrayOfStrings", Collections.singletonList(arrayOfStrings));
+        entity.setAttribute("arrayOfArrayOfBooleans", Collections.singletonList(arrayOfBooleans));
+        entity.setAttribute("arrayOfArrayOfInts", Collections.singletonList(arrayOfInts));
+        entity.setAttribute("arrayOfArrayOfFloats", Collections.singletonList(arrayOfFloats));
+        entity.setAttribute("arrayOfArrayOfDates", Collections.singletonList(arrayOfDates));
+
+        entity.setAttribute("arrayOfMapOfStrings", Collections.singletonList(mapOfStrings));
+        entity.setAttribute("arrayOfMapOfBooleans", Collections.singletonList(mapOfBooleans));
+        entity.setAttribute("arrayOfMapOfInts", Collections.singletonList(mapOfInts));
+        entity.setAttribute("arrayOfMapOfFloats", Collections.singletonList(mapOfFloats));
+        entity.setAttribute("arrayOfMapOfDates", Collections.singletonList(mapOfDates));
+
+        return new AtlasEntityWithExtInfo(entity);
+    }
+
     public static final String randomString() {
         return RandomStringUtils.randomAlphanumeric(10);
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
index 0a13efb..0cdbc57 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
@@ -1028,7 +1028,7 @@ public final class GraphHelper {
             return instanceVertex.getProperty(actualPropertyName, AtlasEdge.class);
         }
         else {
-            return instanceVertex.getProperty(actualPropertyName, Object.class).toString();
+            return instanceVertex.getProperty(actualPropertyName, Object.class);
         }
     }
 
@@ -1038,7 +1038,7 @@ public final class GraphHelper {
         if (AtlasGraphUtilsV1.isReference(elementType)) {
             return instanceVertex.getProperty(vertexPropertyName, AtlasEdge.class);
         } else {
-            return instanceVertex.getProperty(vertexPropertyName, Object.class).toString();
+            return instanceVertex.getProperty(vertexPropertyName, Object.class);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
index bbacb14..00fc57f 100644
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphToTypedInstanceMapper.java
@@ -273,10 +273,10 @@ public final class GraphToTypedInstanceMapper {
         switch (elementType.getTypeCategory()) {
         case PRIMITIVE:
         case ENUM:
-            return value;
-
         case ARRAY:
         case MAP:
+            return value;
+
         case TRAIT:
             // do nothing
             break;

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
index 0d8b026..d3df464 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
@@ -647,6 +647,8 @@ public class EntityGraphMapper {
         switch(ctx.getAttrType().getTypeCategory()) {
         case PRIMITIVE:
         case ENUM:
+        case MAP:
+        case ARRAY:
             return ctx.getValue();
 
         case STRUCT:
@@ -657,8 +659,6 @@ public class EntityGraphMapper {
             ctx.setElementType(instanceType);
             return mapObjectIdValue(ctx, context);
 
-        case MAP:
-        case ARRAY:
         default:
                 throw new AtlasBaseException(AtlasErrorCode.TYPE_CATEGORY_INVALID, ctx.getAttrType().getTypeCategory().name());
         }
@@ -726,6 +726,10 @@ public class EntityGraphMapper {
     public static Object getMapValueProperty(AtlasType elementType, AtlasVertex vertex, String vertexPropertyName) {
         if (AtlasGraphUtilsV1.isReference(elementType)) {
             return vertex.getProperty(vertexPropertyName, AtlasEdge.class);
+        } else if (elementType instanceof AtlasArrayType) {
+            return vertex.getProperty(vertexPropertyName, List.class);
+        } else if (elementType instanceof AtlasMapType) {
+            return vertex.getProperty(vertexPropertyName, Map.class);
         }
         else {
             return vertex.getProperty(vertexPropertyName, String.class).toString();

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
index 7758b1e..6132cb0 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java
@@ -479,11 +479,11 @@ public final class EntityGraphRetriever {
         switch (arrayElement.getTypeCategory()) {
             case PRIMITIVE:
             case ENUM:
+            case ARRAY:
+            case MAP:
                 ret = value;
                 break;
 
-            case ARRAY:
-            case MAP:
             case CLASSIFICATION:
                 break;
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java
index 242c07f..a1fbf97 100644
--- a/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java
@@ -326,6 +326,21 @@ public class AtlasTypeDefGraphStoreTest {
         }
     }
 
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateWithNestedContainerAttributes() {
+        AtlasTypesDef typesDef = TestUtilsV2.defineTypeWithNestedCollectionAttributes();
+
+        try {
+            AtlasTypesDef createdTypes = typeDefStore.createTypesDef(typesDef);
+            assertEquals(typesDef.getEnumDefs(), createdTypes.getEnumDefs(), "Data integrity issue while persisting");
+            assertEquals(typesDef.getStructDefs(), createdTypes.getStructDefs(), "Data integrity issue while persisting");
+            assertEquals(typesDef.getClassificationDefs(), createdTypes.getClassificationDefs(), "Data integrity issue while persisting");
+            assertEquals(typesDef.getEntityDefs(), createdTypes.getEntityDefs(), "Data integrity issue while persisting");
+        } catch (AtlasBaseException e) {
+            fail("creation of type with nested-container attributes should've succeeded");
+        }
+    }
+
     @Test(enabled = false)
     public void testCreateWithInvalidAttributes(){
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
index 8a13b68..35d1a74 100644
--- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
@@ -103,6 +103,7 @@ public class AtlasEntityStoreV1Test {
     private AtlasEntitiesWithExtInfo deptEntity;
     private AtlasEntityWithExtInfo   dbEntity;
     private AtlasEntityWithExtInfo   tblEntity;
+    private AtlasEntityWithExtInfo   nestedCollectionAttrEntity;
 
     AtlasEntityChangeNotifier mockChangeNotifier = mock(AtlasEntityChangeNotifier.class);
     @Inject
@@ -118,7 +119,8 @@ public class AtlasEntityStoreV1Test {
         new GraphBackedSearchIndexer(typeRegistry);
 
         AtlasTypesDef[] testTypesDefs = new AtlasTypesDef[] { TestUtilsV2.defineDeptEmployeeTypes(),
-                                                              TestUtilsV2.defineHiveTypes()
+                                                              TestUtilsV2.defineHiveTypes(),
+                                                              TestUtilsV2.defineTypeWithNestedCollectionAttributes(),
                                                             };
 
         for (AtlasTypesDef typesDef : testTypesDefs) {
@@ -132,6 +134,7 @@ public class AtlasEntityStoreV1Test {
         deptEntity = TestUtilsV2.createDeptEg2();
         dbEntity   = TestUtilsV2.createDBEntityV2();
         tblEntity  = TestUtilsV2.createTableEntityV2(dbEntity.getEntity());
+        nestedCollectionAttrEntity = TestUtilsV2.createNestedCollectionAttrEntity();
     }
 
     @AfterClass
@@ -187,6 +190,14 @@ public class AtlasEntityStoreV1Test {
 
         AtlasEntityHeader tableEntity = tableCreationResponse.getFirstCreatedEntityByTypeName(TABLE_TYPE);
         validateEntity(tblEntity, getEntityFromStore(tableEntity));
+
+        //Create nested-collection attribute entity
+        init();
+        EntityMutationResponse entityMutationResponse = entityStore.createOrUpdate(new AtlasEntityStream(nestedCollectionAttrEntity), false);
+        validateMutationResponse(entityMutationResponse, EntityOperation.CREATE, 1);
+
+        AtlasEntityHeader createdEntity = entityMutationResponse.getFirstCreatedEntityByTypeName(TestUtilsV2.ENTITY_TYPE_WITH_NESTED_COLLECTION_ATTR);
+        validateEntity(nestedCollectionAttrEntity, getEntityFromStore(createdEntity));
     }
 
     @Test(dependsOnMethods = "testCreate")

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeUtils.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeUtils.java b/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeUtils.java
index 6a14dc4..c590bc4 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeUtils.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeUtils.java
@@ -30,9 +30,11 @@ public class TypeUtils {
 
     public static final String NAME_REGEX = "[a-zA-z][a-zA-Z0-9_]*";
     public static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX);
-    public static final Pattern ARRAY_TYPE_NAME_PATTERN = Pattern.compile(String.format("array<(%s)>", NAME_REGEX));
-    public static final Pattern MAP_TYPE_NAME_PATTERN =
-            Pattern.compile(String.format("map<(%s),(%s)>", NAME_REGEX, NAME_REGEX));
+    private static final String ARRAY_TYPE_NAME_PREFIX = "array<";
+    private static final String ARRAY_TYPE_NAME_SUFFIX = ">";
+    private static final String MAP_TYPE_NAME_PREFIX   = "map<";
+    private static final String MAP_TYPE_NAME_SUFFIX   = ">";
+    private static final String MAP_TYPE_KEY_VAL_SEP   = ",";
 
     public static void outputVal(String val, Appendable buf, String prefix) throws AtlasException {
         try {
@@ -43,13 +45,33 @@ public class TypeUtils {
     }
 
     public static String parseAsArrayType(String typeName) {
-        Matcher m = ARRAY_TYPE_NAME_PATTERN.matcher(typeName);
-        return m.matches() ? m.group(1) : null;
+        String ret = null;
+
+        if (typeName.startsWith(ARRAY_TYPE_NAME_PREFIX) && typeName.endsWith(ARRAY_TYPE_NAME_SUFFIX)) {
+            int    startIdx        = ARRAY_TYPE_NAME_PREFIX.length();
+            int    endIdx          = typeName.length() - ARRAY_TYPE_NAME_SUFFIX.length();
+            String elementTypeName = typeName.substring(startIdx, endIdx);
+
+            ret = elementTypeName;
+        }
+
+        return ret;
     }
 
     public static String[] parseAsMapType(String typeName) {
-        Matcher m = MAP_TYPE_NAME_PATTERN.matcher(typeName);
-        return m.matches() ? new String[]{m.group(1), m.group(2)} : null;
+        String[] ret = null;
+
+        if (typeName.startsWith(MAP_TYPE_NAME_PREFIX) && typeName.endsWith(MAP_TYPE_NAME_SUFFIX)) {
+            int      startIdx      = MAP_TYPE_NAME_PREFIX.length();
+            int      endIdx        = typeName.length() - MAP_TYPE_NAME_SUFFIX.length();
+            String[] keyValueTypes = typeName.substring(startIdx, endIdx).split(MAP_TYPE_KEY_VAL_SEP, 2);
+            String   keyTypeName   = keyValueTypes.length > 0 ? keyValueTypes[0] : null;
+            String   valueTypeName = keyValueTypes.length > 1 ? keyValueTypes[1] : null;
+
+            ret = new String[] { keyTypeName, valueTypeName };
+        }
+
+        return ret;
     }
 
     public static Map<AttributeInfo, List<String>> buildAttrInfoToNameMap(FieldMapping f) {

http://git-wip-us.apache.org/repos/asf/atlas/blob/3d33261d/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypedStructHandler.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypedStructHandler.java b/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypedStructHandler.java
index 9afa873..4ce9795 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypedStructHandler.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypedStructHandler.java
@@ -73,6 +73,21 @@ public class TypedStructHandler {
                 return ts;
             } else if (val instanceof StructInstance && Objects.equals(((StructInstance) val).getTypeName(), structType.getName())) {
                 return (StructInstance) val;
+            } else if (val instanceof Map) {
+                Map s = (Map) val;
+
+                ITypedStruct ts = createInstance();
+                for (Map.Entry<String, AttributeInfo> e : fieldMapping.fields.entrySet()) {
+                    String attrKey = e.getKey();
+                    AttributeInfo i = e.getValue();
+                    Object aVal = s.get(attrKey);
+                    try {
+                        ts.set(attrKey, aVal);
+                    } catch (ValueConversionException ve) {
+                        throw new ValueConversionException(structType, val, ve);
+                    }
+                }
+                return ts;
             } else {
                 throw new ValueConversionException(structType, val);
             }