atlas-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shweth...@apache.org
Subject incubator-atlas git commit: ATLAS-683 Refactor local type-system cache with cache provider interface (vmadugun via shwethags)
Date Fri, 20 May 2016 06:17:31 GMT
Repository: incubator-atlas
Updated Branches:
  refs/heads/master 440bd2ae4 -> 5f248157b


ATLAS-683 Refactor local type-system cache with cache provider interface (vmadugun via shwethags)


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

Branch: refs/heads/master
Commit: 5f248157bcb7daec1db66afe8d05f52f791296bc
Parents: 440bd2a
Author: Shwetha GS <sshivalingamurthy@hortonworks.com>
Authored: Fri May 20 11:44:07 2016 +0530
Committer: Shwetha GS <sshivalingamurthy@hortonworks.com>
Committed: Fri May 20 11:47:18 2016 +0530

----------------------------------------------------------------------
 .gitignore                                      |   2 +
 .../org/apache/atlas/ApplicationProperties.java |  15 +-
 distro/src/conf/atlas-application.properties    |   5 +
 release-log.txt                                 |   1 +
 .../apache/atlas/RepositoryMetadataModule.java  |   8 +-
 .../atlas/typesystem/types/TypeSystem.java      | 200 ++++++----
 .../types/cache/DefaultTypeCacheProvider.java   | 229 +++++++++++
 .../types/cache/ITypeCacheProvider.java         | 137 +++++++
 .../apache/atlas/ApplicationPropertiesTest.java |  14 +-
 .../atlas/typesystem/types/TypeSystemTest.java  |   2 +-
 .../cache/DefaultTypeCacheProviderTest.java     | 383 +++++++++++++++++++
 11 files changed, 912 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index f5899e2..0086a69 100755
--- a/.gitignore
+++ b/.gitignore
@@ -60,7 +60,9 @@ distro/hbase/*.tar.gz
 #solr package downloaded
 distro/solr/*.tgz
 
+# Scala-IDE specific
 .cache-main
+.cache-tests
 
 # emacs files
 *#

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/common/src/main/java/org/apache/atlas/ApplicationProperties.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/atlas/ApplicationProperties.java b/common/src/main/java/org/apache/atlas/ApplicationProperties.java
index 6a4dca3..877d7db 100644
--- a/common/src/main/java/org/apache/atlas/ApplicationProperties.java
+++ b/common/src/main/java/org/apache/atlas/ApplicationProperties.java
@@ -92,13 +92,22 @@ public final class ApplicationProperties extends PropertiesConfiguration {
         return inConf.subset(prefix);
     }
 
-    public static Class getClass(String propertyName, String defaultValue) {
+    public static Class getClass(String propertyName, String defaultValue, Class assignableClass)
+        throws AtlasException {
         try {
             Configuration configuration = get();
             String propertyValue = configuration.getString(propertyName, defaultValue);
-            return Class.forName(propertyValue);
+            Class<?> clazz = Class.forName(propertyValue);
+            if (assignableClass == null || assignableClass.isAssignableFrom(clazz)) {
+                return clazz;
+            } else {
+                String message = "Class " + clazz.getName() + " specified in property " + propertyName
+                        + " is not assignable to class " + assignableClass.getName();
+                LOG.error(message);
+                throw new AtlasException(message);
+            }
         } catch (Exception e) {
-            throw new RuntimeException(e);
+            throw new AtlasException(e);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/distro/src/conf/atlas-application.properties
----------------------------------------------------------------------
diff --git a/distro/src/conf/atlas-application.properties b/distro/src/conf/atlas-application.properties
index d4722fb..e2082ef 100755
--- a/distro/src/conf/atlas-application.properties
+++ b/distro/src/conf/atlas-application.properties
@@ -122,3 +122,8 @@ atlas.login.credentials.file=${sys:atlas.home}/conf/users-credentials.properties
 #########POLICY FILE PATH #########
 atlas.auth.policy.file=${sys:atlas.home}/conf/policy-store.txt
 
+#########  Type Cache Provider Implementation ########
+# A type cache provider class which implements
+# org.apache.atlas.typesystem.types.cache.ITypeCacheProvider.
+# The default is DefaultTypeCacheProvider which is a local in-memory type cache.
+#atlas.typesystem.cache.provider=

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index c44ad0b..4a9a34d 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -21,6 +21,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file (dosset
 ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags)
 
 ALL CHANGES:
+ATLAS-683 Refactor local type-system cache with cache provider interface (vmadugun via shwethags)
 ATLAS-802 New look UI to show Business Catalog functionalities (kevalbhatt18 via yhemanth)
 ATLAS-658 Improve Lineage with Backbone porting (kevalbhatt18 via yhemanth)
 ATLAS-491 Business Catalog / Taxonomy (jspeidel via yhemanth)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/repository/src/main/java/org/apache/atlas/RepositoryMetadataModule.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/RepositoryMetadataModule.java b/repository/src/main/java/org/apache/atlas/RepositoryMetadataModule.java
index 68b707f..15201dd 100755
--- a/repository/src/main/java/org/apache/atlas/RepositoryMetadataModule.java
+++ b/repository/src/main/java/org/apache/atlas/RepositoryMetadataModule.java
@@ -111,7 +111,11 @@ public class RepositoryMetadataModule extends com.google.inject.AbstractModule {
     private static final String DELETE_HANDLER_IMPLEMENTATION_PROPERTY = "atlas.DeleteHandler.impl";
 
     private Class<? extends DeleteHandler> getDeleteHandler() {
-        return ApplicationProperties.getClass(DELETE_HANDLER_IMPLEMENTATION_PROPERTY,
-                SoftDeleteHandler.class.getName());
+        try {
+            return ApplicationProperties.getClass(DELETE_HANDLER_IMPLEMENTATION_PROPERTY,
+                    SoftDeleteHandler.class.getName(), DeleteHandler.class);
+        } catch (AtlasException e) {
+            throw new RuntimeException(e);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeSystem.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeSystem.java b/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeSystem.java
index 7763ebc..14f1968 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeSystem.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/TypeSystem.java
@@ -18,19 +18,6 @@
 
 package org.apache.atlas.typesystem.types;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimap;
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.classification.InterfaceAudience;
-import org.apache.atlas.typesystem.TypesDef;
-import org.apache.atlas.typesystem.exception.TypeExistsException;
-import org.apache.atlas.typesystem.exception.TypeNotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Singleton;
 import java.lang.reflect.Constructor;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -41,10 +28,27 @@ import java.util.Set;
 import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 
+import javax.inject.Singleton;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.classification.InterfaceAudience;
+import org.apache.atlas.typesystem.TypesDef;
+import org.apache.atlas.typesystem.exception.TypeExistsException;
+import org.apache.atlas.typesystem.exception.TypeNotFoundException;
+import org.apache.atlas.typesystem.types.cache.DefaultTypeCacheProvider;
+import org.apache.atlas.typesystem.types.cache.ITypeCacheProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
 @Singleton
 @InterfaceAudience.Private
 public class TypeSystem {
     private static final Logger LOG = LoggerFactory.getLogger(TypeSystem.class);
+    private static final String CACHE_PROVIDER_CLASS_PROPERTY = "atlas.typesystem.cache.provider";
 
     private static final TypeSystem INSTANCE = new TypeSystem();
     private static ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>() {
@@ -56,15 +60,9 @@ public class TypeSystem {
         }
     };
 
-    private Map<String, IDataType> types;
+    private ITypeCacheProvider typeCache;
     private IdType idType;
-
-    /**
-     * An in-memory copy of type categories vs types for convenience.
-     */
-    private Multimap<DataTypes.TypeCategory, String> typeCategoriesToTypeNamesMap;
-
-    private ImmutableList<String> coreTypes;
+    private Map<String, IDataType> coreTypes;
 
     public TypeSystem() {
         initialize();
@@ -78,69 +76,111 @@ public class TypeSystem {
      * This is only used for testing purposes. Not intended for public use.
      */
     @InterfaceAudience.Private
-    public void reset() {
+    public TypeSystem reset() {
+
+        typeCache.clear(); // clear all entries in cache
         initialize();
+
+        return this;
     }
 
     private void initialize() {
-        types = new ConcurrentHashMap<>();
-        typeCategoriesToTypeNamesMap = ArrayListMultimap.create(DataTypes.TypeCategory.values().length, 10);
+
+        initCacheProvider();
+        coreTypes = new ConcurrentHashMap<>();
 
         registerPrimitiveTypes();
         registerCoreTypes();
-        coreTypes = ImmutableList.copyOf(types.keySet());
+    }
+
+    /**
+     * Ideally a cache provider should have been injected in the TypeSystemProvider,
+     * but a singleton of TypeSystem is constructed privately within the class so that
+     * clients of TypeSystem would never instantiate a TypeSystem object directly in
+     * their code. As soon as a client makes a call to TypeSystem.getInstance(), they
+     * should have the singleton ready for consumption. To enable such an access pattern,
+     * it kind of becomes imperative to initialize the cache provider within the
+     * TypeSystem constructor (bypassing the GUICE way of injecting a cache provider)
+     */
+    private void initCacheProvider() {
+
+        // read the pluggable cache provider from Atlas configuration
+        final String defaultCacheProvider = DefaultTypeCacheProvider.class.getName();
+        Class cacheProviderClass;
+        try {
+            cacheProviderClass = ApplicationProperties.getClass(CACHE_PROVIDER_CLASS_PROPERTY,
+                defaultCacheProvider, ITypeCacheProvider.class);
+        } catch (AtlasException e) {
+            throw new RuntimeException("Error getting type cache provider implementation class", e);
+        }
+
+        try {
+            typeCache = (ITypeCacheProvider)cacheProviderClass.newInstance();
+        }
+        catch (Exception e) {
+            throw new RuntimeException("Error creating instance of type cache provider implementation class " + cacheProviderClass.getName(), e);
+        }
     }
 
     public ImmutableList<String> getCoreTypes() {
-        return coreTypes;
+        return ImmutableList.copyOf(coreTypes.keySet());
     }
 
-    public ImmutableList<String> getTypeNames() {
-        List<String> typeNames = new ArrayList<>(types.keySet());
-        typeNames.removeAll(getCoreTypes());
+    public ImmutableList<String> getTypeNames() throws AtlasException {
+        List<String> typeNames = new ArrayList<>(typeCache.getAllTypeNames());
         return ImmutableList.copyOf(typeNames);
     }
 
-    public ImmutableList<String> getTypeNamesByCategory(DataTypes.TypeCategory typeCategory) {
-        return ImmutableList.copyOf(typeCategoriesToTypeNamesMap.get(typeCategory));
+    public ImmutableList<String> getTypeNamesByCategory(DataTypes.TypeCategory typeCategory) throws AtlasException {
+        return ImmutableList.copyOf(typeCache.getTypeNames(typeCategory));
     }
 
     private void registerPrimitiveTypes() {
-        types.put(DataTypes.BOOLEAN_TYPE.getName(), DataTypes.BOOLEAN_TYPE);
-        types.put(DataTypes.BYTE_TYPE.getName(), DataTypes.BYTE_TYPE);
-        types.put(DataTypes.SHORT_TYPE.getName(), DataTypes.SHORT_TYPE);
-        types.put(DataTypes.INT_TYPE.getName(), DataTypes.INT_TYPE);
-        types.put(DataTypes.LONG_TYPE.getName(), DataTypes.LONG_TYPE);
-        types.put(DataTypes.FLOAT_TYPE.getName(), DataTypes.FLOAT_TYPE);
-        types.put(DataTypes.DOUBLE_TYPE.getName(), DataTypes.DOUBLE_TYPE);
-        types.put(DataTypes.BIGINTEGER_TYPE.getName(), DataTypes.BIGINTEGER_TYPE);
-        types.put(DataTypes.BIGDECIMAL_TYPE.getName(), DataTypes.BIGDECIMAL_TYPE);
-        types.put(DataTypes.DATE_TYPE.getName(), DataTypes.DATE_TYPE);
-        types.put(DataTypes.STRING_TYPE.getName(), DataTypes.STRING_TYPE);
 
-        typeCategoriesToTypeNamesMap.putAll(DataTypes.TypeCategory.PRIMITIVE, types.keySet());
+        coreTypes.put(DataTypes.BOOLEAN_TYPE.getName(), DataTypes.BOOLEAN_TYPE);
+        coreTypes.put(DataTypes.BYTE_TYPE.getName(), DataTypes.BYTE_TYPE);
+        coreTypes.put(DataTypes.SHORT_TYPE.getName(), DataTypes.SHORT_TYPE);
+        coreTypes.put(DataTypes.INT_TYPE.getName(), DataTypes.INT_TYPE);
+        coreTypes.put(DataTypes.LONG_TYPE.getName(), DataTypes.LONG_TYPE);
+        coreTypes.put(DataTypes.FLOAT_TYPE.getName(), DataTypes.FLOAT_TYPE);
+        coreTypes.put(DataTypes.DOUBLE_TYPE.getName(), DataTypes.DOUBLE_TYPE);
+        coreTypes.put(DataTypes.BIGINTEGER_TYPE.getName(), DataTypes.BIGINTEGER_TYPE);
+        coreTypes.put(DataTypes.BIGDECIMAL_TYPE.getName(), DataTypes.BIGDECIMAL_TYPE);
+        coreTypes.put(DataTypes.DATE_TYPE.getName(), DataTypes.DATE_TYPE);
+        coreTypes.put(DataTypes.STRING_TYPE.getName(), DataTypes.STRING_TYPE);
     }
 
-
     /*
      * The only core OOB type we will define is the Struct to represent the Identity of an Instance.
      */
     private void registerCoreTypes() {
+
         idType = new IdType();
+        coreTypes.put(idType.getStructType().getName(), idType.getStructType());
     }
 
     public IdType getIdType() {
         return idType;
     }
 
-    public boolean isRegistered(String typeName) {
-        return types.containsKey(typeName);
+    public boolean isRegistered(String typeName) throws AtlasException {
+        return isCoreType(typeName) || typeCache.has(typeName);
+    }
+
+    protected boolean isCoreType(String typeName) {
+
+        return coreTypes.containsKey(typeName);
     }
 
     public <T> T getDataType(Class<T> cls, String name) throws AtlasException {
-        if (types.containsKey(name)) {
+
+        if (isCoreType(name)) {
+            return cls.cast(coreTypes.get(name));
+        }
+
+        if (typeCache.has(name)) {
             try {
-                return cls.cast(types.get(name));
+                return cls.cast(typeCache.get(name));
             } catch (ClassCastException cce) {
                 throw new AtlasException(cce);
             }
@@ -285,13 +325,12 @@ public class TypeSystem {
 
     public EnumType defineEnumType(EnumTypeDefinition eDef) throws AtlasException {
         assert eDef.name != null;
-        if (types.containsKey(eDef.name)) {
+        if (isRegistered(eDef.name)) {
             throw new AtlasException(String.format("Redefinition of type %s not supported", eDef.name));
         }
 
         EnumType eT = new EnumType(this, eDef.name, eDef.description, eDef.enumValues);
-        types.put(eDef.name, eT);
-        typeCategoriesToTypeNamesMap.put(DataTypes.TypeCategory.ENUM, eDef.name);
+        typeCache.put(eT);
         return eT;
     }
 
@@ -329,17 +368,14 @@ public class TypeSystem {
      *
      * This step should be called only after the types have been committed to the backend stores successfully.
      * @param typesAdded newly added types.
+     * @throws AtlasException
      */
-    public void commitTypes(Map<String, IDataType> typesAdded) {
+    public void commitTypes(Map<String, IDataType> typesAdded) throws AtlasException {
         for (Map.Entry<String, IDataType> typeEntry : typesAdded.entrySet()) {
             String typeName = typeEntry.getKey();
             IDataType type = typeEntry.getValue();
             //Add/replace the new type in the typesystem
-            types.put(typeName, type);
-            // ArrayListMultiMap allows duplicates - we want to avoid this during re-activation.
-            if (!typeCategoriesToTypeNamesMap.containsEntry(type.getTypeCategory(), typeName)) {
-                typeCategoriesToTypeNamesMap.put(type.getTypeCategory(), typeName);
-            }
+            typeCache.put(type);
         }
     }
 
@@ -372,10 +408,12 @@ public class TypeSystem {
         }
 
         private IDataType dataType(String name) throws AtlasException {
+
             if (transientTypes.containsKey(name)) {
                 return transientTypes.get(name);
             }
-            return TypeSystem.this.types.get(name);
+
+            return TypeSystem.this.getDataType(IDataType.class, name);
         }
 
         /*
@@ -386,7 +424,7 @@ public class TypeSystem {
         private void validateAndSetupShallowTypes(boolean update) throws AtlasException {
             for (EnumTypeDefinition eDef : enumDefs) {
                 assert eDef.name != null;
-                if (!update && (transientTypes.containsKey(eDef.name) || types.containsKey(eDef.name))) {
+                if (!update && (transientTypes.containsKey(eDef.name) || isRegistered(eDef.name))) {
                     throw new AtlasException(String.format("Redefinition of type %s not supported", eDef.name));
                 }
 
@@ -396,7 +434,7 @@ public class TypeSystem {
 
             for (StructTypeDefinition sDef : structDefs) {
                 assert sDef.typeName != null;
-                if (!update && (transientTypes.containsKey(sDef.typeName) || types.containsKey(sDef.typeName))) {
+                if (!update && (transientTypes.containsKey(sDef.typeName) || isRegistered(sDef.typeName))) {
                     throw new TypeExistsException(String.format("Cannot redefine type %s", sDef.typeName));
                 }
                 StructType sT = new StructType(this, sDef.typeName, sDef.typeDescription, sDef.attributeDefinitions.length);
@@ -407,7 +445,7 @@ public class TypeSystem {
             for (HierarchicalTypeDefinition<TraitType> traitDef : traitDefs) {
                 assert traitDef.typeName != null;
                 if (!update &&
-                        (transientTypes.containsKey(traitDef.typeName) || types.containsKey(traitDef.typeName))) {
+                        (transientTypes.containsKey(traitDef.typeName) || isRegistered(traitDef.typeName))) {
                     throw new TypeExistsException(String.format("Cannot redefine type %s", traitDef.typeName));
                 }
                 TraitType tT = new TraitType(this, traitDef.typeName, traitDef.typeDescription, traitDef.superTypes,
@@ -419,7 +457,7 @@ public class TypeSystem {
             for (HierarchicalTypeDefinition<ClassType> classDef : classDefs) {
                 assert classDef.typeName != null;
                 if (!update &&
-                        (transientTypes.containsKey(classDef.typeName) || types.containsKey(classDef.typeName))) {
+                        (transientTypes.containsKey(classDef.typeName) || isRegistered(classDef.typeName))) {
                     throw new TypeExistsException(String.format("Cannot redefine type %s", classDef.typeName));
                 }
 
@@ -582,11 +620,11 @@ public class TypeSystem {
          * Step 5:
          * - Validate that the update can be done
          */
-        private void validateUpdateIsPossible() throws TypeUpdateException {
+        private void validateUpdateIsPossible() throws TypeUpdateException, AtlasException {
             //If the type is modified, validate that update can be done
             for (IDataType newType : transientTypes.values()) {
-                if (TypeSystem.this.types.containsKey(newType.getName())) {
-                    IDataType oldType = TypeSystem.this.types.get(newType.getName());
+                if (TypeSystem.this.isRegistered(newType.getName())) {
+                    IDataType oldType = TypeSystem.this.typeCache.get(newType.getName());
                     oldType.validateUpdate(newType);
                 }
             }
@@ -600,7 +638,7 @@ public class TypeSystem {
         }
 
         @Override
-        public ImmutableList<String> getTypeNames() {
+        public ImmutableList<String> getTypeNames() throws AtlasException {
             Set<String> typeNames = transientTypes.keySet();
             typeNames.addAll(TypeSystem.this.getTypeNames());
             return ImmutableList.copyOf(typeNames);
@@ -644,17 +682,17 @@ public class TypeSystem {
         @Override
         public StructType defineStructType(String name, boolean errorIfExists, AttributeDefinition... attrDefs)
         throws AtlasException {
-            throw new AtlasException("Internal Error: define type called on TrasientTypeSystem");
+            throw new AtlasException("Internal Error: define type called on TransientTypeSystem");
         }
 
         @Override
         public TraitType defineTraitType(HierarchicalTypeDefinition traitDef) throws AtlasException {
-            throw new AtlasException("Internal Error: define type called on TrasientTypeSystem");
+            throw new AtlasException("Internal Error: define type called on TransientTypeSystem");
         }
 
         @Override
         public ClassType defineClassType(HierarchicalTypeDefinition<ClassType> classDef) throws AtlasException {
-            throw new AtlasException("Internal Error: define type called on TrasientTypeSystem");
+            throw new AtlasException("Internal Error: define type called on TransientTypeSystem");
         }
 
         @Override
@@ -662,7 +700,7 @@ public class TypeSystem {
                 ImmutableList<StructTypeDefinition> structDefs,
                 ImmutableList<HierarchicalTypeDefinition<TraitType>> traitDefs,
                 ImmutableList<HierarchicalTypeDefinition<ClassType>> classDefs) throws AtlasException {
-            throw new AtlasException("Internal Error: define type called on TrasientTypeSystem");
+            throw new AtlasException("Internal Error: define type called on TransientTypeSystem");
         }
 
         @Override
@@ -686,13 +724,22 @@ public class TypeSystem {
         }
 
         @Override
-        public void commitTypes(Map<String, IDataType> typesAdded) {
+        public void commitTypes(Map<String, IDataType> typesAdded) throws AtlasException {
             TypeSystem.this.commitTypes(typesAdded);
         }
 
         public Map<String, IDataType> getTypesAdded() {
             return new HashMap<>(transientTypes);
         }
+
+        /**
+         * The core types do not change and they are registered
+         * once in the main type system.
+         */
+        @Override
+        public ImmutableList<String> getCoreTypes() {
+            return TypeSystem.this.getCoreTypes();
+        }
     }
 
     public class IdType {
@@ -700,6 +747,8 @@ public class TypeSystem {
         private static final String TYPENAME_ATTRNAME = "typeName";
         private static final String TYP_NAME = "__IdType";
 
+        private StructType type;
+
         private IdType() {
             AttributeDefinition idAttr =
                     new AttributeDefinition(ID_ATTRNAME, DataTypes.STRING_TYPE.getName(), Multiplicity.REQUIRED, false,
@@ -712,16 +761,14 @@ public class TypeSystem {
                 infos[0] = new AttributeInfo(TypeSystem.this, idAttr, null);
                 infos[1] = new AttributeInfo(TypeSystem.this, typNmAttr, null);
 
-                StructType type = new StructType(TypeSystem.this, TYP_NAME, null, infos);
-                TypeSystem.this.types.put(TYP_NAME, type);
-
+                type = new StructType(TypeSystem.this, TYP_NAME, null, infos);
             } catch (AtlasException me) {
                 throw new RuntimeException(me);
             }
         }
 
-        public StructType getStructType() throws AtlasException {
-            return getDataType(StructType.class, TYP_NAME);
+        public StructType getStructType() {
+            return type;
         }
 
         public String getName() {
@@ -738,4 +785,5 @@ public class TypeSystem {
     }
 
     public static final String ID_STRUCT_ID_ATTRNAME = IdType.ID_ATTRNAME;
+    public static final String ID_STRUCT_TYP_NAME = IdType.TYP_NAME;
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProvider.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProvider.java b/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProvider.java
new file mode 100644
index 0000000..700bda6
--- /dev/null
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProvider.java
@@ -0,0 +1,229 @@
+/**
+ * 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.typesystem.types.cache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.typesystem.types.ClassType;
+import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
+import org.apache.atlas.typesystem.types.EnumType;
+import org.apache.atlas.typesystem.types.IDataType;
+import org.apache.atlas.typesystem.types.StructType;
+import org.apache.atlas.typesystem.types.TraitType;
+
+import com.google.inject.Singleton;
+
+/**
+ * Caches the types in-memory within the same process space.
+ */
+@Singleton
+@SuppressWarnings("rawtypes")
+public class DefaultTypeCacheProvider implements ITypeCacheProvider {
+
+    private Map<String, IDataType> types_ = new ConcurrentHashMap<>();
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#has(java.lang
+     * .String)
+     */
+    @Override
+    public boolean has(String typeName) throws AtlasException {
+
+        return types_.containsKey(typeName);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#has(org.
+     * apache.atlas.typesystem.types.DataTypes.TypeCategory, java.lang.String)
+     */
+    @Override
+    public boolean has(TypeCategory typeCategory, String typeName)
+        throws AtlasException {
+
+        assertValidTypeCategory(typeCategory);
+        return has(typeName);
+    }
+
+    private void assertValidTypeCategory(TypeCategory typeCategory) throws
+        AtlasException {
+
+        // there might no need of 'typeCategory' in this implementation for
+        // certain API, but for a distributed cache, it might help for the
+        // implementers to partition the types per their category
+        // while persisting so that look can be efficient
+
+        if (typeCategory == null) {
+            throw new AtlasException("Category of the types to be filtered is null.");
+        }
+
+        boolean validTypeCategory = typeCategory.equals(TypeCategory.CLASS) ||
+            typeCategory.equals(TypeCategory.TRAIT) ||
+            typeCategory.equals(TypeCategory.ENUM) ||
+            typeCategory.equals(TypeCategory.STRUCT);
+
+        if (!validTypeCategory) {
+            throw new AtlasException("Category of the types should be one of CLASS "
+                + "| TRAIT | ENUM | STRUCT.");
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#get(java.lang
+     * .String)
+     */
+    @Override
+    public IDataType get(String typeName) throws AtlasException {
+
+        return types_.get(typeName);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#get(org.apache.
+     * atlas.typesystem.types.DataTypes.TypeCategory, java.lang.String)
+     */
+    @Override
+    public IDataType get(TypeCategory typeCategory, String typeName) throws AtlasException {
+
+        assertValidTypeCategory(typeCategory);
+        return get(typeName);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#getNames(org
+     * .apache.atlas.typesystem.types.DataTypes.TypeCategory)
+     */
+    @Override
+    public Collection<String> getTypeNames(TypeCategory typeCategory) throws AtlasException {
+
+        assertValidTypeCategory(typeCategory);
+
+        List<String> typeNames = new ArrayList<>();
+        for (Entry<String, IDataType> typeEntry : types_.entrySet()) {
+            String name = typeEntry.getKey();
+            IDataType type = typeEntry.getValue();
+
+            if (type.getTypeCategory().equals(typeCategory)) {
+                typeNames.add(name);
+            }
+        }
+        return typeNames;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#getAllNames()
+     */
+    @Override
+    public Collection<String> getAllTypeNames() throws AtlasException {
+
+        return types_.keySet();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#put(org.apache
+     * .atlas.typesystem.types.IDataType)
+     */
+    @Override
+    public void put(IDataType type) throws AtlasException {
+
+        assertValidType(type);
+        types_.put(type.getName(), type);
+    }
+
+    private void assertValidType(IDataType type) throws
+        AtlasException {
+
+        if (type == null) {
+            throw new AtlasException("type is null.");
+        }
+
+        boolean validTypeCategory = (type instanceof ClassType) ||
+            (type instanceof TraitType) ||
+            (type instanceof EnumType) ||
+            (type instanceof StructType);
+
+        if (!validTypeCategory) {
+            throw new AtlasException("Category of the types should be one of ClassType | "
+                + "TraitType | EnumType | StructType.");
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#putAll(java
+     * .util.Collection)
+     */
+    @Override
+    public void putAll(Collection<IDataType> types) throws AtlasException {
+
+        for (IDataType type : types) {
+            assertValidType(type);
+            types_.put(type.getName(), type);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#remove(java
+     * .lang.String)
+     */
+    @Override
+    public void remove(String typeName) throws AtlasException {
+
+        types_.remove(typeName);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#remove(org.
+     * apache.atlas.typesystem.types.DataTypes.TypeCategory, java.lang.String)
+     */
+    @Override
+    public void remove(TypeCategory typeCategory, String typeName)
+            throws AtlasException {
+
+        assertValidTypeCategory(typeCategory);
+        remove(typeName);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.atlas.typesystem.types.cache.ITypeCacheProvider#clear()
+     */
+    @Override
+    public void clear() {
+
+        types_.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/ITypeCacheProvider.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/ITypeCacheProvider.java b/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/ITypeCacheProvider.java
new file mode 100644
index 0000000..55e9ddc
--- /dev/null
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/cache/ITypeCacheProvider.java
@@ -0,0 +1,137 @@
+/**
+ * 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.typesystem.types.cache;
+
+import java.util.Collection;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.apache.atlas.typesystem.types.IDataType;
+
+/**
+ * The types are cached to allow faster lookup when type info is needed during
+ * creation/updation of entities, DSL query translation/execution.
+ * Implementations of this can chose to plugin a distributed cache provider
+ * or an in-memory cache synched across nodes in an Altas cluster. <br>
+ * <br>
+ * Type entries in the cache can be one of ... <br>
+ * {@link org.apache.atlas.typesystem.types.ClassType} <br>
+ * {@link org.apache.atlas.typesystem.types.TraitType} <br>
+ * {@link org.apache.atlas.typesystem.types.StructType} <br>
+ * {@link org.apache.atlas.typesystem.types.EnumType}
+ */
+@SuppressWarnings("rawtypes")
+public interface ITypeCacheProvider {
+
+    /**
+     * @param typeName
+     * @return true if the type exists in cache, false otherwise.
+     * @throws AtlasException
+     */
+    boolean has(String typeName) throws AtlasException;
+
+    /**
+     * @param typeCategory Non-null category of type. The category can be one of
+     * TypeCategory.CLASS | TypeCategory.TRAIT | TypeCategory.STRUCT | TypeCategory.ENUM.
+     * @param typeName
+     * @return true if the type of given category exists in cache, false otherwise.
+     * @throws AtlasException
+     */
+    boolean has(DataTypes.TypeCategory typeCategory, String typeName) throws AtlasException;
+
+    /**
+     * @param name The name of the type.
+     * @return returns non-null type if cached, otherwise null
+     * @throws AtlasException
+     */
+    public IDataType get(String typeName) throws AtlasException;
+
+    /**
+     * @param typeCategory Non-null category of type. The category can be one of
+     * TypeCategory.CLASS | TypeCategory.TRAIT | TypeCategory.STRUCT | TypeCategory.ENUM.
+     * @param typeName
+     * @return returns non-null type (of the specified category) if cached, otherwise null
+     * @throws AtlasException
+     */
+    public IDataType get(DataTypes.TypeCategory typeCategory, String typeName) throws AtlasException;
+
+    /**
+     * @param typeCategory The category of types to filter the returned types. Cannot be null.
+     * The category can be one of TypeCategory.CLASS | TypeCategory.TRAIT |
+     * TypeCategory.STRUCT | TypeCategory.ENUM.
+     * @return
+     * @throws AtlasException
+     */
+    Collection<String> getTypeNames(DataTypes.TypeCategory typeCategory) throws AtlasException;
+
+    /**
+     * This is a convenience API to get the names of all types.
+     *
+     * @see ITypeCacheProvider#getTypeNames(org.apache.atlas.typesystem.types.DataTypes.TypeCategory)
+     * @return
+     * @throws AtlasException
+     */
+    Collection<String> getAllTypeNames() throws AtlasException;
+
+    /**
+     * @param type The type to be added to the cache. The type should not be
+     * null, otherwise throws NullPointerException. <br>
+     * Type entries in the cache can be one of ... <br>
+     * {@link org.apache.atlas.typesystem.types.ClassType} <br>
+     * {@link org.apache.atlas.typesystem.types.TraitType} <br>
+     * {@link org.apache.atlas.typesystem.types.StructType} <br>
+     * {@link org.apache.atlas.typesystem.types.EnumType}
+     * @throws AtlasException
+     */
+    void put(IDataType type) throws AtlasException;
+
+    /**
+     * @param types The types to be added to the cache. The type should not be
+     * null, otherwise throws NullPointerException. <br>
+     * Type entries in the cache can be one of ... <br>
+     * {@link org.apache.atlas.typesystem.types.ClassType} <br>
+     * {@link org.apache.atlas.typesystem.types.TraitType} <br>
+     * {@link org.apache.atlas.typesystem.types.StructType} <br>
+     * {@link org.apache.atlas.typesystem.types.EnumType}
+     * @throws AtlasException
+     */
+    void putAll(Collection<IDataType> types) throws AtlasException;
+
+    /**
+     * @param typeName Name of the type to be removed from the cache. If type
+     * exists, it will be removed, otherwise does nothing.
+     * @throws AtlasException
+     */
+    void remove(String typeName) throws AtlasException;
+
+    /**
+     * @param typeCategory Non-null category of type. The category can be one of
+     * TypeCategory.CLASS | TypeCategory.TRAIT | TypeCategory.STRUCT | TypeCategory.ENUM.
+     * @param typeName Name of the type to be removed from the cache. If type
+     * exists, it will be removed, otherwise does nothing.
+     * @throws AtlasException
+     */
+    void remove(DataTypes.TypeCategory typeCategory, String typeName) throws AtlasException;
+
+    /**
+     * Clear the type cache
+     *
+     */
+    void clear();
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/typesystem/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java
----------------------------------------------------------------------
diff --git a/typesystem/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java b/typesystem/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java
index 27f1f7e..0679642 100644
--- a/typesystem/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java
+++ b/typesystem/src/test/java/org/apache/atlas/ApplicationPropertiesTest.java
@@ -19,6 +19,7 @@ package org.apache.atlas;
 
 import org.apache.atlas.typesystem.types.TypeSystem;
 import org.apache.commons.configuration.Configuration;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;
@@ -58,11 +59,20 @@ public class ApplicationPropertiesTest {
     @Test
     public void testGetClass() throws Exception {
         //read from atlas-application.properties
-        Class cls = ApplicationProperties.getClass("atlas.TypeSystem.impl", ApplicationProperties.class.getName());
+        Class cls = ApplicationProperties.getClass("atlas.TypeSystem.impl", ApplicationProperties.class.getName(), TypeSystem.class);
         assertEquals(cls.getName(), TypeSystem.class.getName());
 
         //default value
-        cls = ApplicationProperties.getClass("atlas.TypeSystem2.impl", TypeSystem.class.getName());
+        cls = ApplicationProperties.getClass("atlas.TypeSystem2.impl", TypeSystem.class.getName(), TypeSystem.class);
         assertEquals(cls.getName(), TypeSystem.class.getName());
+
+        //incompatible assignTo class, should throw AtlasException
+        try {
+            cls = ApplicationProperties.getClass("atlas.TypeSystem.impl", ApplicationProperties.class.getName(), ApplicationProperties.class);
+            Assert.fail(AtlasException.class.getSimpleName() + " was expected but none thrown.");
+        }
+        catch (AtlasException e) {
+            // good
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java
----------------------------------------------------------------------
diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java
index c0574ce..574e0f9 100755
--- a/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java
+++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java
@@ -209,7 +209,7 @@ public class TypeSystemTest extends BaseTest {
     }
 
     @Test
-    public void testTypeNamesAreNotDuplicated() {
+    public void testTypeNamesAreNotDuplicated() throws Exception {
         TypeSystem typeSystem = getTypeSystem();
         ImmutableList<String> traitNames = typeSystem.getTypeNamesByCategory(DataTypes.TypeCategory.TRAIT);
         int numTraits = traitNames.size();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/5f248157/typesystem/src/test/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProviderTest.java
----------------------------------------------------------------------
diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProviderTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProviderTest.java
new file mode 100644
index 0000000..c426d50
--- /dev/null
+++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/cache/DefaultTypeCacheProviderTest.java
@@ -0,0 +1,383 @@
+/**
+ * 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.typesystem.types.cache;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.typesystem.types.ClassType;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
+import org.apache.atlas.typesystem.types.EnumType;
+import org.apache.atlas.typesystem.types.EnumValue;
+import org.apache.atlas.typesystem.types.IDataType;
+import org.apache.atlas.typesystem.types.StructType;
+import org.apache.atlas.typesystem.types.TraitType;
+import org.apache.atlas.typesystem.types.TypeSystem;
+import org.apache.atlas.typesystem.types.utils.TypesUtil;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Tests functional behavior of {@link DefaultTypeCacheProvider}
+ */
+@SuppressWarnings("rawtypes")
+public class DefaultTypeCacheProviderTest {
+
+    private String CLASSTYPE_CUSTOMER = "Customer";
+    private String STRUCTTYPE_ADDRESS = "Address";
+    private String TRAITTYPE_PRIVILEGED = "Privileged";
+    private String ENUMTYPE_SHIPPING = "Shipping";
+
+    private String UNKNOWN_TYPE = "UndefinedType";
+
+    private ClassType customerType;
+    private StructType addressType;
+    private TraitType privilegedTrait;
+    private EnumType shippingEnum;
+
+    private DefaultTypeCacheProvider cacheProvider;
+
+    @BeforeClass
+    public void onetimeSetup() throws Exception {
+
+        // init TypeSystem
+        TypeSystem ts = TypeSystem.getInstance().reset();
+
+        // Customer ClassType
+        customerType = ts.defineClassType(TypesUtil
+            .createClassTypeDef(CLASSTYPE_CUSTOMER, ImmutableSet.<String>of(),
+                TypesUtil.createRequiredAttrDef("name", DataTypes.STRING_TYPE),
+                TypesUtil.createRequiredAttrDef("id", DataTypes.LONG_TYPE)));
+
+        // Address StructType
+        addressType = ts.defineStructType(STRUCTTYPE_ADDRESS, true,
+                TypesUtil.createRequiredAttrDef("first line", DataTypes.STRING_TYPE),
+                TypesUtil.createOptionalAttrDef("second line", DataTypes.STRING_TYPE),
+                TypesUtil.createRequiredAttrDef("city", DataTypes.STRING_TYPE),
+                TypesUtil.createRequiredAttrDef("pincode", DataTypes.INT_TYPE));
+
+        // Privileged TraitType
+        privilegedTrait = ts.defineTraitType(TypesUtil
+                .createTraitTypeDef(TRAITTYPE_PRIVILEGED, ImmutableSet.<String>of(),
+                        TypesUtil.createRequiredAttrDef("category", DataTypes.INT_TYPE)));
+
+        // Shipping EnumType
+        shippingEnum = ts.defineEnumType(TypesUtil.createEnumTypeDef(ENUMTYPE_SHIPPING,
+            new EnumValue("Domestic", 1), new EnumValue("International", 2)));
+    }
+
+    @BeforeMethod
+    public void eachTestSetup() throws Exception {
+
+        cacheProvider = new DefaultTypeCacheProvider();
+
+        cacheProvider.put(customerType);
+        cacheProvider.put(addressType);
+        cacheProvider.put(privilegedTrait);
+        cacheProvider.put(shippingEnum);
+    }
+
+    @Test
+    public void testCacheGetType() throws Exception {
+
+        IDataType custType = cacheProvider.get(CLASSTYPE_CUSTOMER);
+        verifyType(custType, CLASSTYPE_CUSTOMER, ClassType.class);
+
+        IDataType addrType = cacheProvider.get(STRUCTTYPE_ADDRESS);
+        verifyType(addrType, STRUCTTYPE_ADDRESS, StructType.class);
+
+        IDataType privTrait = cacheProvider.get(TRAITTYPE_PRIVILEGED);
+        verifyType(privTrait, TRAITTYPE_PRIVILEGED, TraitType.class);
+
+        IDataType shippingEnum = cacheProvider.get(ENUMTYPE_SHIPPING);
+        verifyType(shippingEnum, ENUMTYPE_SHIPPING, EnumType.class);
+
+        assertNull(cacheProvider.get(UNKNOWN_TYPE));
+    }
+
+    @Test
+    public void testCacheGetTypeByCategory() throws Exception {
+
+        IDataType custType = cacheProvider.get(TypeCategory.CLASS, CLASSTYPE_CUSTOMER);
+        verifyType(custType, CLASSTYPE_CUSTOMER, ClassType.class);
+
+        IDataType addrType = cacheProvider.get(TypeCategory.STRUCT, STRUCTTYPE_ADDRESS);
+        verifyType(addrType, STRUCTTYPE_ADDRESS, StructType.class);
+
+        IDataType privTrait = cacheProvider.get(TypeCategory.TRAIT, TRAITTYPE_PRIVILEGED);
+        verifyType(privTrait, TRAITTYPE_PRIVILEGED, TraitType.class);
+
+        IDataType shippingEnum = cacheProvider.get(TypeCategory.ENUM, ENUMTYPE_SHIPPING);
+        verifyType(shippingEnum, ENUMTYPE_SHIPPING, EnumType.class);
+
+        assertNull(cacheProvider.get(UNKNOWN_TYPE));
+    }
+
+    private void verifyType(IDataType actualType, String expectedName, Class<? extends IDataType> typeClass) {
+
+        assertNotNull(actualType, "The " + expectedName + " type not in cache");
+        assertTrue(typeClass.isInstance(actualType));
+        assertEquals(actualType.getName(), expectedName, "The type name does not match");
+    }
+
+    @Test
+    public void testCacheHasType() throws Exception {
+
+        assertTrue(cacheProvider.has(CLASSTYPE_CUSTOMER));
+        assertTrue(cacheProvider.has(STRUCTTYPE_ADDRESS));
+        assertTrue(cacheProvider.has(TRAITTYPE_PRIVILEGED));
+        assertTrue(cacheProvider.has(ENUMTYPE_SHIPPING));
+
+        assertFalse(cacheProvider.has(UNKNOWN_TYPE));
+    }
+
+    @Test
+    public void testCacheHasTypeByCategory() throws Exception {
+
+        assertTrue(cacheProvider.has(TypeCategory.CLASS, CLASSTYPE_CUSTOMER));
+        assertTrue(cacheProvider.has(TypeCategory.STRUCT, STRUCTTYPE_ADDRESS));
+        assertTrue(cacheProvider.has(TypeCategory.TRAIT, TRAITTYPE_PRIVILEGED));
+        assertTrue(cacheProvider.has(TypeCategory.ENUM, ENUMTYPE_SHIPPING));
+
+        assertFalse(cacheProvider.has(UNKNOWN_TYPE));
+    }
+
+    @Test
+    public void testCacheGetAllTypeNames() throws Exception {
+
+        List<String> allTypeNames = new ArrayList<String>(cacheProvider.getAllTypeNames());
+        Collections.sort(allTypeNames);
+
+        final int EXPECTED_TYPE_COUNT = 4;
+        assertEquals(allTypeNames.size(), EXPECTED_TYPE_COUNT, "Total number of types does not match.");
+
+        assertEquals(STRUCTTYPE_ADDRESS, allTypeNames.get(0));
+        assertEquals(CLASSTYPE_CUSTOMER, allTypeNames.get(1));
+        assertEquals(TRAITTYPE_PRIVILEGED, allTypeNames.get(2));
+        assertEquals(ENUMTYPE_SHIPPING, allTypeNames.get(3));
+    }
+
+    @Test
+    public void testCacheGetTypeNamesByCategory() throws Exception {
+
+        List<String> classTypes = new ArrayList<String>(cacheProvider.getTypeNames(TypeCategory.CLASS));
+        final int EXPECTED_CLASSTYPE_COUNT = 1;
+        assertEquals(classTypes.size(), EXPECTED_CLASSTYPE_COUNT);
+        assertEquals(CLASSTYPE_CUSTOMER, classTypes.get(0));
+
+        List<String> structTypes = new ArrayList<String>(cacheProvider.getTypeNames(TypeCategory.STRUCT));
+        final int EXPECTED_STRUCTTYPE_COUNT = 1;
+        assertEquals(structTypes.size(), EXPECTED_STRUCTTYPE_COUNT);
+        assertEquals(STRUCTTYPE_ADDRESS, structTypes.get(0));
+
+        List<String> traitTypes = new ArrayList<String>(cacheProvider.getTypeNames(TypeCategory.TRAIT));
+        final int EXPECTED_TRAITTYPE_COUNT = 1;
+        assertEquals(traitTypes.size(), EXPECTED_TRAITTYPE_COUNT);
+        assertEquals(TRAITTYPE_PRIVILEGED, traitTypes.get(0));
+
+        List<String> enumTypes = new ArrayList<String>(cacheProvider.getTypeNames(TypeCategory.ENUM));
+        final int EXPECTED_ENUMTYPE_COUNT = 1;
+        assertEquals(enumTypes.size(), EXPECTED_ENUMTYPE_COUNT);
+        assertEquals(ENUMTYPE_SHIPPING, enumTypes.get(0));
+    }
+
+    @Test
+    public void testCacheBulkInsert() throws Exception {
+
+        List<IDataType> allTypes = new ArrayList<>();
+        allTypes.add(customerType);
+        allTypes.add(addressType);
+        allTypes.add(privilegedTrait);
+        allTypes.add(shippingEnum);
+
+        // create a new cache provider instead of using the one setup for every method call
+        cacheProvider = new DefaultTypeCacheProvider();
+        cacheProvider.putAll(allTypes);
+
+        IDataType custType = cacheProvider.get(CLASSTYPE_CUSTOMER);
+        verifyType(custType, CLASSTYPE_CUSTOMER, ClassType.class);
+
+        IDataType addrType = cacheProvider.get(STRUCTTYPE_ADDRESS);
+        verifyType(addrType, STRUCTTYPE_ADDRESS, StructType.class);
+
+        IDataType privTrait = cacheProvider.get(TRAITTYPE_PRIVILEGED);
+        verifyType(privTrait, TRAITTYPE_PRIVILEGED, TraitType.class);
+
+        IDataType shippingEnum = cacheProvider.get(ENUMTYPE_SHIPPING);
+        verifyType(shippingEnum, ENUMTYPE_SHIPPING, EnumType.class);
+    }
+
+    @Test
+    public void testCacheRemove() throws Exception {
+
+        cacheProvider.remove(CLASSTYPE_CUSTOMER);
+        assertNull(cacheProvider.get(CLASSTYPE_CUSTOMER));
+        assertFalse(cacheProvider.has(CLASSTYPE_CUSTOMER));
+        assertTrue(cacheProvider.getTypeNames(TypeCategory.CLASS).isEmpty());
+
+        final int EXPECTED_TYPE_COUNT = 3;
+        assertEquals(cacheProvider.getAllTypeNames().size(), EXPECTED_TYPE_COUNT);
+    }
+
+    @Test
+    public void testCacheRemoveByCategory() throws Exception {
+
+        cacheProvider.remove(TypeCategory.CLASS, CLASSTYPE_CUSTOMER);
+        assertNull(cacheProvider.get(CLASSTYPE_CUSTOMER));
+        assertFalse(cacheProvider.has(CLASSTYPE_CUSTOMER));
+        assertTrue(cacheProvider.getTypeNames(TypeCategory.CLASS).isEmpty());
+
+        final int EXPECTED_TYPE_COUNT = 3;
+        assertEquals(cacheProvider.getAllTypeNames().size(), EXPECTED_TYPE_COUNT);
+    }
+
+    @Test
+    public void testCacheClear() throws Exception {
+
+        cacheProvider.clear();
+
+        assertNull(cacheProvider.get(CLASSTYPE_CUSTOMER));
+        assertFalse(cacheProvider.has(CLASSTYPE_CUSTOMER));
+
+        assertNull(cacheProvider.get(STRUCTTYPE_ADDRESS));
+        assertFalse(cacheProvider.has(STRUCTTYPE_ADDRESS));
+
+        assertNull(cacheProvider.get(TRAITTYPE_PRIVILEGED));
+        assertFalse(cacheProvider.has(TRAITTYPE_PRIVILEGED));
+
+        assertNull(cacheProvider.get(ENUMTYPE_SHIPPING));
+        assertFalse(cacheProvider.has(ENUMTYPE_SHIPPING));
+
+        assertTrue(cacheProvider.getTypeNames(TypeCategory.CLASS).isEmpty());
+        assertTrue(cacheProvider.getTypeNames(TypeCategory.STRUCT).isEmpty());
+        assertTrue(cacheProvider.getTypeNames(TypeCategory.TRAIT).isEmpty());
+        assertTrue(cacheProvider.getTypeNames(TypeCategory.ENUM).isEmpty());
+
+        assertTrue(cacheProvider.getAllTypeNames().isEmpty());
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testPutTypeWithNullType() throws Exception {
+
+        cacheProvider.put(null);
+        fail("Null type should be not allowed in 'put'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testPutTypeWithInvalidType() throws Exception {
+
+        cacheProvider.put(DataTypes.BOOLEAN_TYPE);
+        fail("type should only be an instance of ClassType | EnumType | StructType | TraitType in 'put'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testGetTypeWithNullCategory() throws Exception {
+
+        cacheProvider.get(null, CLASSTYPE_CUSTOMER);
+        fail("Null TypeCategory should be not allowed in 'get'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testGetTypeWithInvalidCategory() throws Exception {
+
+        cacheProvider.get(TypeCategory.PRIMITIVE, DataTypes.BOOLEAN_TYPE.getName());
+        fail("TypeCategory should only be one of TypeCategory.CLASS | ENUM | STRUCT | TRAIT in 'get'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheHasTypeWithNullCategory() throws Exception {
+
+        cacheProvider.has(null, CLASSTYPE_CUSTOMER);
+        fail("Null TypeCategory should be not allowed in 'has'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheHasTypeWithInvalidCategory() throws Exception {
+
+        cacheProvider.has(TypeCategory.PRIMITIVE, DataTypes.BOOLEAN_TYPE.getName());
+        fail("TypeCategory should only be one of TypeCategory.CLASS | ENUM | STRUCT | TRAIT in 'has'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheGetTypeNamesByNullCategory() throws Exception {
+
+        cacheProvider.getTypeNames(null);
+        fail("Null TypeCategory should be not allowed in 'getNames'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheGetTypeNamesByInvalidCategory() throws Exception {
+
+        cacheProvider.getTypeNames(TypeCategory.PRIMITIVE);
+        fail("TypeCategory should only be one of TypeCategory.CLASS | ENUM | STRUCT | TRAIT in 'getNames'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheBulkInsertWithNullType() throws Exception {
+
+        List<IDataType> allTypes = new ArrayList<>();
+        allTypes.add(null);
+
+        // create a new cache provider instead of using the one setup for every method call
+        cacheProvider = new DefaultTypeCacheProvider();
+        cacheProvider.putAll(allTypes);
+
+        fail("Null type should be not allowed in 'putAll'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheBulkInsertWithInvalidType() throws Exception {
+
+        List<IDataType> allTypes = new ArrayList<>();
+        allTypes.add(DataTypes.BOOLEAN_TYPE);
+
+        // create a new cache provider instead of using the one setup for every method call
+        cacheProvider = new DefaultTypeCacheProvider();
+        cacheProvider.putAll(allTypes);
+
+        fail("type should only one of ClassType | EnumType | StructType | TraitType in 'putAll'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheRemoveByNullCategory() throws Exception {
+
+        cacheProvider.remove(null, CLASSTYPE_CUSTOMER);
+        fail("Null type should be not allowed in 'remove'");
+    }
+
+    @Test(expectedExceptions = AtlasException.class)
+    public void testCacheRemoveByInvalidCategory() throws Exception {
+
+        cacheProvider.remove(TypeCategory.PRIMITIVE, DataTypes.BOOLEAN_TYPE.getName());
+        fail("TypeCategory should only be one of TypeCategory.CLASS | ENUM | STRUCT | TRAIT in 'remove'");
+    }
+}


Mime
View raw message