atlas-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mad...@apache.org
Subject incubator-atlas git commit: ATLAS-916: Return System Attributes in get entity definition [Forced Update!]
Date Sat, 19 Nov 2016 00:22:05 GMT
Repository: incubator-atlas
Updated Branches:
  refs/heads/master 2cee65182 -> 774975c97 (forced update)


ATLAS-916: Return System Attributes in get entity definition


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

Branch: refs/heads/master
Commit: 774975c970cc2613a9f955c35f8eead16ad1d9bf
Parents: 95083cb
Author: Vimal <svimal2106@apache.org>
Authored: Fri Nov 18 20:35:26 2016 +0530
Committer: Madhan Neethiraj <madhan@apache.org>
Committed: Fri Nov 18 16:21:55 2016 -0800

----------------------------------------------------------------------
 .../atlas/catalog/DefaultPropertyMapper.java    |   6 +
 .../org/apache/atlas/repository/Constants.java  |   2 +
 release-log.txt                                 |   1 +
 .../atlas/repository/graph/DeleteHandler.java   |   1 +
 .../graph/GraphBackedMetadataRepository.java    |   2 +
 .../graph/GraphBackedSearchIndexer.java         |  21 +++-
 .../atlas/repository/graph/GraphHelper.java     |  27 ++++-
 .../graph/GraphToTypedInstanceMapper.java       |  12 +-
 .../repository/graph/SoftDeleteHandler.java     |   3 +
 .../graph/TypedInstanceToGraphMapper.java       |   2 +
 .../GraphBackedDiscoveryServiceTest.java        |  42 +++++++
 .../GraphBackedMetadataRepositoryTest.java      |   6 +
 .../typesystem/IReferenceableInstance.java      |   3 +
 .../apache/atlas/typesystem/Referenceable.java  |  28 +++++
 .../persistence/AtlasSystemAttributes.java      | 115 +++++++++++++++++++
 .../apache/atlas/typesystem/persistence/Id.java |   7 ++
 .../persistence/ReferenceableInstance.java      |  14 ++-
 .../atlas/typesystem/types/ClassType.java       |  13 ++-
 .../typesystem/json/InstanceSerialization.scala |  46 +++++++-
 .../atlas/typesystem/json/Serialization.scala   |  38 +++++-
 20 files changed, 367 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/catalog/src/main/java/org/apache/atlas/catalog/DefaultPropertyMapper.java
----------------------------------------------------------------------
diff --git a/catalog/src/main/java/org/apache/atlas/catalog/DefaultPropertyMapper.java b/catalog/src/main/java/org/apache/atlas/catalog/DefaultPropertyMapper.java
index 2f52b3b..6c41881 100644
--- a/catalog/src/main/java/org/apache/atlas/catalog/DefaultPropertyMapper.java
+++ b/catalog/src/main/java/org/apache/atlas/catalog/DefaultPropertyMapper.java
@@ -138,5 +138,11 @@ public class DefaultPropertyMapper implements PropertyMapper {
 
         m_qualifiedToCleanMap.put(Constants.STATE_PROPERTY_KEY, "state");
         m_cleanToQualifiedMap.put("state", Constants.STATE_PROPERTY_KEY);
+
+        m_qualifiedToCleanMap.put(Constants.CREATED_BY_KEY, "created_by");
+        m_cleanToQualifiedMap.put("created_by", Constants.CREATED_BY_KEY);
+
+        m_qualifiedToCleanMap.put(Constants.MODIFIED_BY_KEY, "modified_by");
+        m_cleanToQualifiedMap.put("modified_by", Constants.MODIFIED_BY_KEY);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/common/src/main/java/org/apache/atlas/repository/Constants.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java b/common/src/main/java/org/apache/atlas/repository/Constants.java
index cc184a5..6175ac2 100644
--- a/common/src/main/java/org/apache/atlas/repository/Constants.java
+++ b/common/src/main/java/org/apache/atlas/repository/Constants.java
@@ -63,6 +63,8 @@ public final class Constants {
 
     public static final String VERSION_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "version";
     public static final String STATE_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "state";
+    public static final String CREATED_BY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "createdBy";
+    public static final String MODIFIED_BY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "modifiedBy";
 
     public static final String TIMESTAMP_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "timestamp";
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index 6a17548..8f1147c 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
 ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
 
 ALL CHANGES:
+ATLAS-916 Return System Attributes in get entity definition (svimal2106)
 ATLAS-1242 update TypesResource API implementation to use new v2 TypesREST API
 ATLAS-1306 bootstrap type-load ignores model file contents if a type in the file already exists
 ATLAS-1299 The project org.apache.atlas:atlas-hbase-client-shaded - build error (shwethags)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/repository/src/main/java/org/apache/atlas/repository/graph/DeleteHandler.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/DeleteHandler.java b/repository/src/main/java/org/apache/atlas/repository/graph/DeleteHandler.java
index fb014f2..ae1ec45 100644
--- a/repository/src/main/java/org/apache/atlas/repository/graph/DeleteHandler.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/DeleteHandler.java
@@ -397,6 +397,7 @@ public abstract class DeleteHandler {
             RequestContext requestContext = RequestContext.get();
             GraphHelper.setProperty(outVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
                     requestContext.getRequestTime());
+            GraphHelper.setProperty(outVertex, Constants.MODIFIED_BY_KEY, requestContext.getUser());
             requestContext.recordEntityUpdate(outId);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepository.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepository.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepository.java
index 691a12c..1a3faf7 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepository.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepository.java
@@ -238,6 +238,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
             GraphHelper.addProperty(instanceVertex, Constants.TRAIT_NAMES_PROPERTY_KEY, traitName);
             GraphHelper.setProperty(instanceVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
                     RequestContext.get().getRequestTime());
+            GraphHelper.setProperty(instanceVertex, Constants.MODIFIED_BY_KEY, RequestContext.get().getUser());
             
         } catch (RepositoryException e) {
             throw e;
@@ -293,6 +294,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
         }
         GraphHelper.setProperty(instanceVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
                 RequestContext.get().getRequestTime());
+        GraphHelper.setProperty(instanceVertex, Constants.MODIFIED_BY_KEY, RequestContext.get().getUser());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
----------------------------------------------------------------------
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 aea54fa..9ef3160 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
@@ -88,7 +88,7 @@ import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING;
 /**
  * Adds index for properties of a given type when its added before any instances are added.
  */
-public class GraphBackedSearchIndexer implements SearchIndexer, ActiveStateChangeHandler,
+public class    GraphBackedSearchIndexer implements SearchIndexer, ActiveStateChangeHandler,
         TypeDefChangeListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(GraphBackedSearchIndexer.class);
@@ -154,17 +154,26 @@ public class GraphBackedSearchIndexer implements SearchIndexer, ActiveStateChang
             createIndexes(management, Constants.GUID_PROPERTY_KEY, String.class, true,
                     AtlasCardinality.SINGLE, true, true);
 
-            // create a composite index for entity creation timestamp
-            createIndexes(management, Constants.TIMESTAMP_PROPERTY_KEY, Long.class, false, AtlasCardinality.SINGLE, true, true);
+            // Add creation_timestamp property to Vertex Index (mixed index)
+            createIndexes(management, Constants.TIMESTAMP_PROPERTY_KEY, Long.class, false, AtlasCardinality.SINGLE, false, false);
+
+            // Add modification_timestamp property to Vertex Index (mixed index)
+            createIndexes(management, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class, false,
+                    AtlasCardinality.SINGLE, false, false);
+
 
             // create a mixed index for entity state. Set systemProperty flag deliberately to false
             // so that it doesnt create a composite index which has issues with
             // titan 0.5.4 - Refer https://groups.google.com/forum/#!searchin/aureliusgraphs/hemanth/aureliusgraphs/bx7T843mzXU/fjAsclx7GAAJ
             createIndexes(management, Constants.STATE_PROPERTY_KEY, String.class, false, AtlasCardinality.SINGLE, false, false);
 
-            // create a composite index for entity modification timestamp
-            createIndexes(management, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class, false,
-                    AtlasCardinality.SINGLE, false, false);
+            // Create a composite and mixed index for created by property
+            createIndexes(management, Constants.CREATED_BY_KEY, String.class, false,
+                    AtlasCardinality.SINGLE, true, true);
+
+            // Create a composite and mixed index for modified by property
+            createIndexes(management, Constants.MODIFIED_BY_KEY, String.class, false,
+                    AtlasCardinality.SINGLE, true, true);
 
             // create a composite and mixed index for type since it can be combined with other keys
             createIndexes(management, Constants.ENTITY_TYPE_PROPERTY_KEY, String.class, false, AtlasCardinality.SINGLE,

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/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 7e47d30..4c2bd76 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
@@ -27,6 +27,7 @@ import java.util.List;
 import java.util.Set;
 import java.util.Stack;
 import java.util.UUID;
+import java.util.Date;
 
 import org.apache.atlas.ApplicationProperties;
 import org.apache.atlas.AtlasException;
@@ -159,6 +160,8 @@ public final class GraphHelper {
         setProperty(vertexWithoutIdentity, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
                 RequestContext.get().getRequestTime());
 
+        setProperty(vertexWithoutIdentity, Constants.CREATED_BY_KEY, RequestContext.get().getUser());
+        setProperty(vertexWithoutIdentity, Constants.MODIFIED_BY_KEY, RequestContext.get().getUser());
         return vertexWithoutIdentity;
     }
 
@@ -169,6 +172,8 @@ public final class GraphHelper {
         setProperty(edge, Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name());
         setProperty(edge, Constants.TIMESTAMP_PROPERTY_KEY, RequestContext.get().getRequestTime());
         setProperty(edge, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, RequestContext.get().getRequestTime());
+        setProperty(edge, Constants.CREATED_BY_KEY, RequestContext.get().getUser());
+        setProperty(edge, Constants.MODIFIED_BY_KEY, RequestContext.get().getUser());
 
         LOG.debug("Added {}", string(edge));
         return edge;
@@ -517,6 +522,24 @@ public final class GraphHelper {
         return element.getProperty(Constants.STATE_PROPERTY_KEY, String.class);
     }
 
+
+    //Added conditions in fetching system attributes to handle test failures in GremlinTest where these properties are not set
+    public static String getCreatedByAsString(AtlasElement element){
+        return element.getProperty(Constants.CREATED_BY_KEY, String.class);
+    }
+
+    public static String getModifiedByAsString(AtlasElement element){
+        return element.getProperty(Constants.MODIFIED_BY_KEY, String.class);
+    }
+
+    public static long getCreatedTime(AtlasElement element){
+        return element.getProperty(Constants.TIMESTAMP_PROPERTY_KEY, Long.class);
+    }
+
+    public static long getModifiedTime(AtlasElement element){
+        return element.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class);
+    }
+
     /**
      * For the given type, finds an unique attribute and checks if there is an existing instance with the same
      * unique value
@@ -857,7 +880,9 @@ public final class GraphHelper {
         switch (field) {
         case Constants.STATE_PROPERTY_KEY:
         case Constants.GUID_PROPERTY_KEY:
-            return TypesUtil.newAttributeInfo(field, DataTypes.STRING_TYPE);
+        case Constants.CREATED_BY_KEY:
+        case Constants.MODIFIED_BY_KEY:
+                return TypesUtil.newAttributeInfo(field, DataTypes.STRING_TYPE);
 
         case Constants.TIMESTAMP_PROPERTY_KEY:
         case Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY:

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/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 ceb6011..8dd548a 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
@@ -36,7 +36,10 @@ import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.typesystem.ITypedInstance;
 import org.apache.atlas.typesystem.ITypedReferenceableInstance;
 import org.apache.atlas.typesystem.ITypedStruct;
+import org.apache.atlas.typesystem.Referenceable;
+import org.apache.atlas.typesystem.persistence.AtlasSystemAttributes;
 import org.apache.atlas.typesystem.persistence.Id;
+import org.apache.atlas.typesystem.persistence.ReferenceableInstance;
 import org.apache.atlas.typesystem.types.AttributeInfo;
 import org.apache.atlas.typesystem.types.ClassType;
 import org.apache.atlas.typesystem.types.DataTypes;
@@ -70,6 +73,13 @@ public final class GraphToTypedInstanceMapper {
         String typeName = GraphHelper.getSingleValuedProperty(instanceVertex, Constants.ENTITY_TYPE_PROPERTY_KEY, String.class);
         List<String> traits = GraphHelper.getTraitNames(instanceVertex);
         String state = GraphHelper.getStateAsString(instanceVertex);
+        String createdBy = GraphHelper.getCreatedByAsString(instanceVertex);
+        String modifiedBy = GraphHelper.getModifiedByAsString(instanceVertex);
+        Date createdTime = new Date(GraphHelper.getCreatedTime(instanceVertex));
+        Date modifiedTime = new Date(GraphHelper.getModifiedTime(instanceVertex));
+        AtlasSystemAttributes systemAttributes = new AtlasSystemAttributes(createdBy, modifiedBy, createdTime, modifiedTime);
+
+        LOG.debug("Found createdBy : {} modifiedBy : {} createdTime: {} modifedTime: {}", createdBy, modifiedBy, createdTime, modifiedTime);
 
         Id id = new Id(guid, (Integer) GraphHelper.getProperty(instanceVertex, Constants.VERSION_PROPERTY_KEY),
                 typeName, state);
@@ -77,7 +87,7 @@ public final class GraphToTypedInstanceMapper {
 
         ClassType classType = typeSystem.getDataType(ClassType.class, typeName);
         ITypedReferenceableInstance typedInstance =
-            classType.createInstance(id, traits.toArray(new String[traits.size()]));
+            classType.createInstance(id, systemAttributes, traits.toArray(new String[traits.size()]));
 
         mapVertexToInstance(instanceVertex, typedInstance, classType.fieldMapping().fields);
         mapVertexToInstanceTraits(instanceVertex, typedInstance, traits);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/repository/src/main/java/org/apache/atlas/repository/graph/SoftDeleteHandler.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/SoftDeleteHandler.java b/repository/src/main/java/org/apache/atlas/repository/graph/SoftDeleteHandler.java
index 92e43cb..dc21291 100644
--- a/repository/src/main/java/org/apache/atlas/repository/graph/SoftDeleteHandler.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/SoftDeleteHandler.java
@@ -27,6 +27,7 @@ import org.apache.atlas.typesystem.persistence.Id;
 import org.apache.atlas.typesystem.types.TypeSystem;
 
 import static org.apache.atlas.repository.Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY;
+import static org.apache.atlas.repository.Constants.MODIFIED_BY_KEY;
 import static org.apache.atlas.repository.Constants.STATE_PROPERTY_KEY;
 
 public class SoftDeleteHandler extends DeleteHandler {
@@ -45,6 +46,7 @@ public class SoftDeleteHandler extends DeleteHandler {
                 GraphHelper.setProperty(instanceVertex, STATE_PROPERTY_KEY, Id.EntityState.DELETED.name());
                 GraphHelper.setProperty(instanceVertex, MODIFICATION_TIMESTAMP_PROPERTY_KEY,
                         RequestContext.get().getRequestTime());
+                GraphHelper.setProperty(instanceVertex, MODIFIED_BY_KEY, RequestContext.get().getUser());
             }
         }
     }
@@ -59,6 +61,7 @@ public class SoftDeleteHandler extends DeleteHandler {
                 GraphHelper.setProperty(edge, STATE_PROPERTY_KEY, Id.EntityState.DELETED.name());
                 GraphHelper
                         .setProperty(edge, MODIFICATION_TIMESTAMP_PROPERTY_KEY, RequestContext.get().getRequestTime());
+                GraphHelper.setProperty(edge, MODIFIED_BY_KEY, RequestContext.get().getUser());
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
index 47ae5e1..62b0be0 100644
--- a/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/TypedInstanceToGraphMapper.java
@@ -187,6 +187,8 @@ public final class TypedInstanceToGraphMapper {
         }
         GraphHelper.setProperty(instanceVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
                 RequestContext.get().getRequestTime());
+        GraphHelper.setProperty(instanceVertex, Constants.MODIFIED_BY_KEY, RequestContext.get().getUser());
+        LOG.debug("Setting modifiedBy: {} and modifiedTime: {}", RequestContext.get().getUser(), RequestContext.get().getRequestTime());
     }
 
     void mapAttributeToVertex(ITypedInstance typedInstance, AtlasVertex instanceVertex,

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java b/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
index 645fef1..4ac001e 100755
--- a/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
@@ -59,6 +59,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Date;
+import java.text.SimpleDateFormat;
 
 import javax.inject.Inject;
 
@@ -67,6 +69,7 @@ import static org.apache.atlas.typesystem.types.utils.TypesUtil.createOptionalAt
 import static org.apache.atlas.typesystem.types.utils.TypesUtil.createRequiredAttrDef;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
 @Guice(modules = RepositoryMetadataModule.class)
 public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
@@ -167,6 +170,24 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
         assertNotNull(rows);
         assertEquals(rows.length(), 1);
 
+        //Assert system attributes are not null
+        JSONObject sys_attributes = (JSONObject)rows.getJSONObject(0).get("$systemAttributes$");
+        assertNotNull(sys_attributes.get("createdBy"));
+        assertNotNull(sys_attributes.get("modifiedBy"));
+        assertNotNull(sys_attributes.get("createdTime"));
+        assertNotNull(sys_attributes.get("modifiedTime"));
+
+
+        //Assert that createdTime and modifiedTime are valid dates
+        String createdTime = (String) sys_attributes.get("createdTime");
+        String modifiedTime = (String) sys_attributes.get("modifiedTime");
+        final String outputFormat = "EEE MMM dd HH:mm:ss z yyyy";
+        SimpleDateFormat df = new SimpleDateFormat(outputFormat);
+        Date createdDate = df.parse(createdTime);
+        Date modifiedDate = df.parse(modifiedTime);
+        assertNotNull(createdDate);
+        assertNotNull(modifiedDate);
+
         final String testTs = "\"2011-11-01T02:35:58.440Z\"";
         dslQuery = "Department where " + Constants.TIMESTAMP_PROPERTY_KEY + " > " + testTs;
         jsonResults = searchByDSL(dslQuery);
@@ -191,6 +212,27 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
         assertNotNull(rows);
         assertEquals(rows.length(), 1);
 
+        dslQuery = "from Department select " + Constants.CREATED_BY_KEY;
+        jsonResults = searchByDSL(dslQuery);
+        assertNotNull(jsonResults);
+
+        results = new JSONObject(jsonResults);
+        assertEquals(results.length(), 3);
+
+        rows = results.getJSONArray("rows");
+        assertNotNull(rows);
+        assertEquals(rows.length(), 1);
+
+        dslQuery = "from Department select " + Constants.MODIFIED_BY_KEY;
+        jsonResults = searchByDSL(dslQuery);
+        assertNotNull(jsonResults);
+
+        results = new JSONObject(jsonResults);
+        assertEquals(results.length(), 3);
+
+        rows = results.getJSONArray("rows");
+        assertNotNull(rows);
+        assertEquals(rows.length(), 1);
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
index 725b9a6..7444bf3 100755
--- a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
@@ -43,6 +43,7 @@ import org.apache.atlas.typesystem.Referenceable;
 import org.apache.atlas.typesystem.Struct;
 import org.apache.atlas.typesystem.exception.EntityNotFoundException;
 import org.apache.atlas.typesystem.exception.TraitNotFoundException;
+import org.apache.atlas.typesystem.persistence.AtlasSystemAttributes;
 import org.apache.atlas.typesystem.persistence.Id;
 import org.apache.atlas.typesystem.types.AttributeDefinition;
 import org.apache.atlas.typesystem.types.ClassType;
@@ -207,6 +208,11 @@ public class GraphBackedMetadataRepositoryTest {
 
         //entity state should be active by default
         Assert.assertEquals(entity.getId().getState(), Id.EntityState.ACTIVE);
+
+        //System attributes created time and modified time should not be null
+        AtlasSystemAttributes systemAttributes = entity.getSystemAttributes();
+        Assert.assertNotNull(systemAttributes.createdTime);
+        Assert.assertNotNull(systemAttributes.modifiedTime);
     }
 
     @Test(expectedExceptions = EntityNotFoundException.class)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/java/org/apache/atlas/typesystem/IReferenceableInstance.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/IReferenceableInstance.java b/typesystem/src/main/java/org/apache/atlas/typesystem/IReferenceableInstance.java
index 9285014..04af67c 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/IReferenceableInstance.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/IReferenceableInstance.java
@@ -19,6 +19,7 @@
 package org.apache.atlas.typesystem;
 
 import com.google.common.collect.ImmutableList;
+import org.apache.atlas.typesystem.persistence.AtlasSystemAttributes;
 import org.apache.atlas.typesystem.persistence.Id;
 
 /**
@@ -32,4 +33,6 @@ public interface IReferenceableInstance extends IStruct {
     Id getId();
 
     IStruct getTrait(String typeName);
+
+    AtlasSystemAttributes getSystemAttributes();
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java b/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
index 5b8e157..0b3ffe3 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
@@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import org.apache.atlas.AtlasException;
 import org.apache.atlas.classification.InterfaceAudience;
+import org.apache.atlas.typesystem.persistence.AtlasSystemAttributes;
 import org.apache.atlas.typesystem.persistence.Id;
 
 import java.util.HashMap;
@@ -36,6 +37,7 @@ public class Referenceable extends Struct implements IReferenceableInstance {
     private Id id;
     private final ImmutableMap<String, IStruct> traits;
     private final ImmutableList<String> traitNames;
+    private AtlasSystemAttributes systemAttributes;
 
     public Referenceable(String typeName, String... traitNames) {
         super(typeName);
@@ -46,6 +48,7 @@ public class Referenceable extends Struct implements IReferenceableInstance {
             b.put(t, new Struct(t));
         }
         traits = b.build();
+        this.systemAttributes = new AtlasSystemAttributes();
     }
 
     public Referenceable(String typeName, Map<String, Object> values) {
@@ -53,6 +56,7 @@ public class Referenceable extends Struct implements IReferenceableInstance {
         id = new Id(typeName);
         traitNames = ImmutableList.of();
         traits = ImmutableMap.of();
+        this.systemAttributes = new AtlasSystemAttributes();
     }
 
     public Referenceable(String guid, String typeName, Map<String, Object> values) {
@@ -60,6 +64,7 @@ public class Referenceable extends Struct implements IReferenceableInstance {
         id = new Id(guid, 0, typeName);
         traitNames = ImmutableList.of();
         traits = ImmutableMap.of();
+        this.systemAttributes = new AtlasSystemAttributes();
     }
 
     /**
@@ -75,6 +80,7 @@ public class Referenceable extends Struct implements IReferenceableInstance {
         id = new Id(guid, 0, typeName);
         traitNames = ImmutableList.copyOf(_traitNames);
         traits = ImmutableMap.copyOf(_traits);
+        this.systemAttributes = new AtlasSystemAttributes();
     }
 
     /**
@@ -90,6 +96,23 @@ public class Referenceable extends Struct implements IReferenceableInstance {
         this.id = id;
         traitNames = ImmutableList.copyOf(_traitNames);
         traits = ImmutableMap.copyOf(_traits);
+        this.systemAttributes = new AtlasSystemAttributes();
+    }
+
+    /**
+     * Not public - only use during deserialization
+     * @param id      entity id
+     * @param typeName  the type name
+     * @param values    the entity attribute values
+     */
+    @InterfaceAudience.Private
+    public Referenceable(Id id, String typeName, Map<String, Object> values, List<String> _traitNames,
+                         Map<String, IStruct> _traits, AtlasSystemAttributes systemAttributes) {
+        super(typeName, values);
+        this.id = id;
+        traitNames = ImmutableList.copyOf(_traitNames);
+        traits = ImmutableMap.copyOf(_traits);
+        this.systemAttributes = systemAttributes;
     }
 
     /**
@@ -130,6 +153,11 @@ public class Referenceable extends Struct implements IReferenceableInstance {
         return traits.get(typeName);
     }
 
+    @Override
+    public AtlasSystemAttributes getSystemAttributes(){
+        return systemAttributes;
+    }
+
     /**
      * Matches traits, values associated with this Referenceable and skips the id match
      * @param o The Referenceable which needs to be matched with

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/AtlasSystemAttributes.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/AtlasSystemAttributes.java b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/AtlasSystemAttributes.java
new file mode 100644
index 0000000..3c08a02
--- /dev/null
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/AtlasSystemAttributes.java
@@ -0,0 +1,115 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.persistence;
+
+import org.apache.atlas.typesystem.types.TypeSystem;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class AtlasSystemAttributes {
+    public  String createdBy;
+    public  String modifiedBy;
+    public Date createdTime;
+    public Date modifiedTime;
+    public SimpleDateFormat simpleDateFormat = TypeSystem.getInstance().getDateFormat();
+
+
+    public AtlasSystemAttributes(String createdBy, String modifiedBy, Date createdTime, Date modifiedTime){
+        this.createdBy = createdBy;
+        this.modifiedBy = modifiedBy;
+        this.createdTime = createdTime;
+        this.modifiedTime = modifiedTime;
+    }
+
+    public AtlasSystemAttributes(){
+        super();
+    }
+
+    public AtlasSystemAttributes(String createdBy, String modifiedBy, String createdTime, String modifiedTime){
+        this.createdBy  = createdBy;
+        this.modifiedBy = modifiedBy;
+
+        try{
+            this.createdTime = simpleDateFormat.parse(createdTime);
+        }catch (ParseException e){
+            //this.createdTime = new Date(0);
+        }
+
+        try{
+            this.modifiedTime = simpleDateFormat.parse(modifiedTime);
+        }catch (ParseException e){
+            //this.modifiedTime = new Date(0);
+        }
+    }
+
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        AtlasSystemAttributes sys_attr = (AtlasSystemAttributes) o;
+
+        if (!createdBy.equals(sys_attr.createdBy)) {
+            return false;
+        }
+        if (!modifiedBy.equals(sys_attr.modifiedBy)) {
+            return false;
+        }
+        if (!createdTime.equals(sys_attr.createdTime)) {
+            return false;
+        }
+
+        if(!modifiedTime.equals(sys_attr.modifiedTime)){
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = createdBy.hashCode();
+        result = 31 * result + modifiedBy.hashCode();
+        result = 31 * result + createdTime.hashCode();
+        result = 31 * result + modifiedTime.hashCode();
+        return result;
+    }
+
+    public String getCreatedBy(){
+        return createdBy;
+    }
+
+    public String getModifiedBy(){
+        return modifiedBy;
+    }
+
+    public Date getCreatedTime(){
+        return createdTime;
+    }
+
+    public Date getModifiedTime(){
+        return modifiedTime;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java
index 42280d0..a3f9421 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java
@@ -45,6 +45,7 @@ public class Id implements ITypedReferenceableInstance {
     public final int version;
     public EntityState state;
     private static AtomicLong s_nextId = new AtomicLong(System.nanoTime());
+    public final AtlasSystemAttributes systemAttributes;
 
     public Id(String id, int version, String typeName, String state) {
         id       = ParamChecker.notEmpty(id, "id");
@@ -58,6 +59,7 @@ public class Id implements ITypedReferenceableInstance {
         } else {
             this.state = EntityState.valueOf(state.toUpperCase());
         }
+        this.systemAttributes = new AtlasSystemAttributes();
     }
 
     public Id(String id, int version, String typeName) {
@@ -105,6 +107,11 @@ public class Id implements ITypedReferenceableInstance {
         return String.format("id[type=%s guid=%s state=%s]", typeName, id, state);
     }
 
+    @Override
+    public AtlasSystemAttributes getSystemAttributes(){
+        return systemAttributes;
+    }
+
     public String getClassName() {
         return typeName;
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
index 561cb62..75ec9a2 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
@@ -45,9 +45,10 @@ public class ReferenceableInstance extends StructInstance implements ITypedRefer
     private final ImmutableMap<String, ITypedStruct> traits;
     private final ImmutableList<String> traitNames;
     private Id id;
+    private AtlasSystemAttributes systemAttributes;
 
 
-    public ReferenceableInstance(Id id, String dataTypeName, FieldMapping fieldMapping, boolean[] nullFlags,
+    public ReferenceableInstance(Id id, String dataTypeName, AtlasSystemAttributes systemAttributes, FieldMapping fieldMapping, boolean[] nullFlags,
             boolean[] bools, byte[] bytes, short[] shorts, int[] ints, long[] longs, float[] floats, double[] doubles,
             BigDecimal[] bigDecimals, BigInteger[] bigIntegers, Date[] dates, String[] strings,
             ImmutableList<Object>[] arrays, ImmutableMap<Object, Object>[] maps, StructInstance[] structs,
@@ -61,6 +62,12 @@ public class ReferenceableInstance extends StructInstance implements ITypedRefer
             b.add(t);
         }
         this.traitNames = b.build();
+        if(systemAttributes == null){
+            this.systemAttributes = new AtlasSystemAttributes();
+        }
+        else{
+            this.systemAttributes = systemAttributes;
+        }
     }
 
     @Override
@@ -78,6 +85,11 @@ public class ReferenceableInstance extends StructInstance implements ITypedRefer
         return traits.get(typeName);
     }
 
+    @Override
+    public AtlasSystemAttributes getSystemAttributes(){
+        return systemAttributes;
+    }
+
     /**
      * @nopub
      * @param id

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java b/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java
index 6b530a8..6398829 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java
@@ -31,6 +31,7 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance;
 import org.apache.atlas.typesystem.ITypedStruct;
 import org.apache.atlas.typesystem.Referenceable;
 import org.apache.atlas.typesystem.Struct;
+import org.apache.atlas.typesystem.persistence.AtlasSystemAttributes;
 import org.apache.atlas.typesystem.persistence.Id;
 import org.apache.atlas.typesystem.persistence.ReferenceableInstance;
 import org.apache.atlas.typesystem.persistence.StructInstance;
@@ -132,7 +133,7 @@ public class ClassType extends HierarchicalType<ClassType, IReferenceableInstanc
                 }
 
                 ITypedReferenceableInstance tr =
-                        r != null ? createInstanceWithTraits(id, r, r.getTraits().toArray(new String[0])) :
+                        r != null ? createInstanceWithTraits(id, null, r, r.getTraits().toArray(new String[0])) :
                                 createInstance(id);
 
                 if (id != null && id.isAssigned()) {
@@ -180,10 +181,14 @@ public class ClassType extends HierarchicalType<ClassType, IReferenceableInstanc
     }
 
     public ITypedReferenceableInstance createInstance(Id id, String... traitNames) throws AtlasException {
-        return createInstanceWithTraits(id, null, traitNames);
+        return createInstanceWithTraits(id, null, null, traitNames);
     }
 
-    public ITypedReferenceableInstance createInstanceWithTraits(Id id, Referenceable r, String... traitNames)
+    public ITypedReferenceableInstance createInstance(Id id, AtlasSystemAttributes systemAttributes, String... traitNames) throws AtlasException{
+        return createInstanceWithTraits(id, systemAttributes, null, traitNames);
+    }
+
+    public ITypedReferenceableInstance createInstanceWithTraits(Id id, AtlasSystemAttributes systemAttributes, Referenceable r, String... traitNames)
     throws AtlasException {
 
         ImmutableMap.Builder<String, ITypedStruct> b = new ImmutableBiMap.Builder<String, ITypedStruct>();
@@ -197,7 +202,7 @@ public class ClassType extends HierarchicalType<ClassType, IReferenceableInstanc
             }
         }
 
-        return new ReferenceableInstance(id == null ? new Id(getName()) : id, getName(), fieldMapping,
+        return new ReferenceableInstance(id == null ? new Id(getName()) : id, getName(), systemAttributes, fieldMapping,
                 new boolean[fieldMapping.fields.size()],
                 fieldMapping.numBools == 0 ? null : new boolean[fieldMapping.numBools],
                 fieldMapping.numBytes == 0 ? null : new byte[fieldMapping.numBytes],

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/scala/org/apache/atlas/typesystem/json/InstanceSerialization.scala
----------------------------------------------------------------------
diff --git a/typesystem/src/main/scala/org/apache/atlas/typesystem/json/InstanceSerialization.scala b/typesystem/src/main/scala/org/apache/atlas/typesystem/json/InstanceSerialization.scala
index 73b3526..6f63d0f 100755
--- a/typesystem/src/main/scala/org/apache/atlas/typesystem/json/InstanceSerialization.scala
+++ b/typesystem/src/main/scala/org/apache/atlas/typesystem/json/InstanceSerialization.scala
@@ -21,23 +21,26 @@ package org.apache.atlas.typesystem.json
 import java.text.SimpleDateFormat
 
 import org.apache.atlas.typesystem._
-import org.apache.atlas.typesystem.persistence.Id
+import org.apache.atlas.typesystem.persistence.{AtlasSystemAttributes, Id}
 import org.apache.atlas.typesystem.types._
 import org.json4s._
 import org.json4s.native.Serialization._
 
 import scala.collection.JavaConversions._
 import scala.collection.JavaConverters._
+import java.util.Date
 
 object InstanceSerialization {
 
   case class _Id(id : String, version : Int, typeName : String, state : Option[String])
+  case class _AtlasSystemAttributes(createdBy: Option[String], modifiedBy: Option[String], createdTime: Option[Date], modifiedTime: Option[Date])
   case class _Struct(typeName : String, values : Map[String, AnyRef])
   case class _Reference(id : Option[_Id],
                         typeName : String,
                         values : Map[String, AnyRef],
                         traitNames : List[String],
-                        traits : Map[String, _Struct])
+                        traits : Map[String, _Struct],
+                        systemAttributes : Option[_AtlasSystemAttributes])
 
   def Try[B](x : => B) : Option[B] = {
     try { Some(x) } catch { case _ : Throwable => None }
@@ -71,6 +74,14 @@ object InstanceSerialization {
       jsonMap.get("id").filter(_.isInstanceOf[String]).flatMap(v => Some(v.asInstanceOf[String]))
     }
 
+    def createdBy: Option[String] = {
+      jsonMap.get("createdBy").filter(_.isInstanceOf[String]).flatMap(v => Some(v.asInstanceOf[String]))
+    }
+
+    def modifiedBy: Option[String] = {
+      jsonMap.get("modifiedBy").filter(_.isInstanceOf[String]).flatMap(v => Some(v.asInstanceOf[String]))
+    }
+
     /**
      * validate and extract 'state' attribute from Map
      * @return
@@ -91,6 +102,14 @@ object InstanceSerialization {
       }
     }
 
+    def createdTime: Option[Date] = {
+      jsonMap.get("createdTime").filter(_.isInstanceOf[String]).flatMap(v => Some(v.asInstanceOf[Date]))
+    }
+
+    def modifiedTime: Option[Date] = {
+      jsonMap.get("modifiedTime").filter(_.isInstanceOf[String]).flatMap(v => Some(v.asInstanceOf[Date]))
+    }
+
     /**
      * A Map is an Id if:
      * - it has the correct [[format.typeHintFieldName]]
@@ -109,6 +128,15 @@ object InstanceSerialization {
       } yield _Id(i, v, typNm, s)
     }
 
+    def convertSystemAttributes: Option[_AtlasSystemAttributes] = {
+      for {
+        c <- Some(createdBy)
+        m <- Some(modifiedBy)
+        c_t <- Some(createdTime)
+        m_t <- Some(modifiedTime)
+      } yield _AtlasSystemAttributes(c, m, c_t, m_t)
+    }
+
     /**
      * validate and extract 'typeName' attribute from Map
      * @return
@@ -232,7 +260,8 @@ object InstanceSerialization {
         values <- valuesMap
         traitNms <- traitNames
         ts <- traits
-      } yield _Reference(i, typNm, values, traitNms.toList, ts)
+        s_attr <- Some(convertSystemAttributes)
+      } yield _Reference(i, typNm, values, traitNms.toList, ts, s_attr)
     }
 
     /**
@@ -259,16 +288,22 @@ object InstanceSerialization {
   def asJava(v : Any)(implicit format: Formats) : Any = v match {
     case i : _Id => new Id(i.id, i.version, i.typeName, i.state.orNull)
     case s : _Struct => new Struct(s.typeName, asJava(s.values).asInstanceOf[java.util.Map[String, Object]])
+    case s_attr : _AtlasSystemAttributes => new AtlasSystemAttributes(s_attr.createdBy.orNull, s_attr.modifiedBy.orNull, s_attr.createdTime.orNull, s_attr.modifiedTime.orNull)
     case r : _Reference => {
       val id = r.id match {
         case Some(i) => new Id(i.id, i.version, i.typeName, i.state.orNull)
         case None => new Id(r.typeName)
       }
+
+      val s_attr = r.systemAttributes match {
+        case Some(s) => new AtlasSystemAttributes(s.createdBy.orNull, s.modifiedBy.orNull, s.createdTime.orNull, s.modifiedTime.orNull)
+        case None => new AtlasSystemAttributes()
+      }
       new Referenceable(id,
         r.typeName,
         asJava(r.values).asInstanceOf[java.util.Map[String, Object]],
         asJava(r.traitNames).asInstanceOf[java.util.List[String]],
-        asJava(r.traits).asInstanceOf[java.util.Map[String, IStruct]])
+        asJava(r.traits).asInstanceOf[java.util.Map[String, IStruct]], s_attr)
     }
     case l : List[_] => l.map(e => asJava(e)).toList.asJava
     case m : Map[_, _] if Try{m.asInstanceOf[Map[String,_]]}.isDefined => {
@@ -284,6 +319,7 @@ object InstanceSerialization {
 
   def asScala(v : Any) : Any = v match {
     case i : Id => _Id(i._getId(), i.getVersion, i.getClassName, Some(i.getStateAsString))
+    case s_attr: AtlasSystemAttributes => _AtlasSystemAttributes(Some(s_attr.createdBy), Some(s_attr.modifiedBy), Some(s_attr.createdTime), Some(s_attr.modifiedTime))
     case r : IReferenceableInstance => {
       val traits = r.getTraits.map { tName =>
         val t = r.getTrait(tName).asInstanceOf[IStruct]
@@ -292,7 +328,7 @@ object InstanceSerialization {
       _Reference(Some(asScala(r.getId).asInstanceOf[_Id]),
         r.getTypeName, asScala(r.getValuesMap).asInstanceOf[Map[String, AnyRef]],
         asScala(r.getTraits).asInstanceOf[List[String]],
-        traits.asInstanceOf[Map[String, _Struct]])
+        traits.asInstanceOf[Map[String, _Struct]], Some(asScala(r.getSystemAttributes).asInstanceOf[_AtlasSystemAttributes]))
     }
     case s : IStruct => _Struct(s.getTypeName, asScala(s.getValuesMap).asInstanceOf[Map[String, AnyRef]])
     case l : java.util.List[_] => l.asScala.map(e => asScala(e)).toList

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/774975c9/typesystem/src/main/scala/org/apache/atlas/typesystem/json/Serialization.scala
----------------------------------------------------------------------
diff --git a/typesystem/src/main/scala/org/apache/atlas/typesystem/json/Serialization.scala b/typesystem/src/main/scala/org/apache/atlas/typesystem/json/Serialization.scala
index 68c47ec..ca4dd7f 100755
--- a/typesystem/src/main/scala/org/apache/atlas/typesystem/json/Serialization.scala
+++ b/typesystem/src/main/scala/org/apache/atlas/typesystem/json/Serialization.scala
@@ -19,15 +19,16 @@
 package org.apache.atlas.typesystem.json
 
 import org.apache.atlas.typesystem._
-import org.apache.atlas.typesystem.persistence.{Id, ReferenceableInstance, StructInstance}
+import org.apache.atlas.typesystem.persistence.{AtlasSystemAttributes, Id, ReferenceableInstance, StructInstance}
 import org.apache.atlas.typesystem.types.DataTypes.{ArrayType, MapType, TypeCategory}
 import org.apache.atlas.typesystem.types._
 import org.json4s.JsonAST.JInt
-import org.json4s._
+import org.json4s.{JsonAST, _}
 import org.json4s.native.Serialization._
 
 import scala.collection.JavaConversions._
 import scala.collection.JavaConverters._
+import java.util.Date
 
 class BigDecimalSerializer extends CustomSerializer[java.math.BigDecimal](format => (
     {
@@ -60,6 +61,7 @@ class IdSerializer extends CustomSerializer[Id](format => ( {
     case JObject(JField(Serialization.STRUCT_TYPE_FIELD_NAME, JString(typeName)) ::
         JField("id", JString(id)) ::
         JField("version", JString(version)) :: Nil) => new Id(id, version.toInt, typeName)
+
 }, {
     case id: Id => JObject(JField("id", JString(id.id)),
         JField(Serialization.STRUCT_TYPE_FIELD_NAME, JString(id.typeName)),
@@ -117,12 +119,14 @@ class TypedReferenceableInstanceSerializer()
                 var typField: Option[JField] = None
                 var idField: Option[JField] = None
                 var traitsField: Option[JField] = None
+                var sysAttrField: Option[JField] = None
                 var fields: List[JField] = Nil
 
                 fs.foreach { f: JField => f._1 match {
                     case Serialization.STRUCT_TYPE_FIELD_NAME => typField = Some(f)
                     case Serialization.ID_TYPE_FIELD_NAME => idField = Some(f)
                     case Serialization.TRAIT_TYPE_FIELD_NAME => traitsField = Some(f)
+                    case Serialization.SYSTEM_ATTR_FIELD_NAME => sysAttrField = Some(f)
                     case _ => fields = fields :+ f
                 }
                 }
@@ -141,7 +145,8 @@ class TypedReferenceableInstanceSerializer()
                 val sT = typSystem.getDataType(
                     classOf[ClassType], typName).asInstanceOf[ClassType]
                 val id = Serialization.deserializeId(idField.get._2)
-                val s = sT.createInstance(id, traitNames: _*)
+                val s_attr = Serialization.deserializeSystemAttributes(sysAttrField.get._2)
+                val s = sT.createInstance(id, s_attr, traitNames: _*)
                 Serialization.deserializeFields(typSystem, sT, s, fields)
 
                 traitsField.map { t =>
@@ -169,10 +174,11 @@ class TypedReferenceableInstanceSerializer()
         case id: Id => Serialization.serializeId(id)
         case e: ITypedReferenceableInstance =>
             val idJ = JField(Serialization.ID_TYPE_FIELD_NAME, Serialization.serializeId(e.getId))
+            val s_attrJ = JField(Serialization.SYSTEM_ATTR_FIELD_NAME, Serialization.serializeSystemAttributes(e.getSystemAttributes))
             var fields = Serialization.serializeFields(e)
             val traitsJ: List[JField] = e.getTraits.map(tName => JField(tName, Extraction.decompose(e.getTrait(tName)))).toList
 
-            fields = idJ :: fields
+            fields = idJ :: s_attrJ :: fields
             if (traitsJ.size > 0) {
                 fields = fields :+ JField(Serialization.TRAIT_TYPE_FIELD_NAME, JObject(traitsJ: _*))
             }
@@ -186,6 +192,7 @@ object Serialization {
     val STRUCT_TYPE_FIELD_NAME = "$typeName$"
     val ID_TYPE_FIELD_NAME = "$id$"
     val TRAIT_TYPE_FIELD_NAME = "$traits$"
+    val SYSTEM_ATTR_FIELD_NAME = "$systemAttributes$"
 
     def extractList(lT: ArrayType, value: JArray)(implicit format: Formats): Any = {
         val dT = lT.getElemType
@@ -218,6 +225,22 @@ object Serialization {
         JField(Serialization.STRUCT_TYPE_FIELD_NAME, JString(id.typeName)),
         JField("version", JInt(id.version)), JField("state", JString(id.state.name())))
 
+
+    //Handling serialization issues with null values
+    //See https://github.com/json4s/json4s/issues/358
+    def parseString(s: Any) = s match {
+        case s:String => JString(s)
+        case s:Date => JString(s.toString)
+        case _ => JString("")
+    }
+
+    def serializeSystemAttributes(s_attr: AtlasSystemAttributes) = JObject(
+        JField("createdBy", parseString(s_attr.modifiedBy)),
+        JField("modifiedBy", parseString(s_attr.modifiedBy)),
+        JField("createdTime", parseString(s_attr.createdTime)),
+        JField("modifiedTime", parseString(s_attr.modifiedTime))
+    )
+
     def serializeFields(e: ITypedInstance)(implicit format: Formats) = e.fieldMapping.fields.map {
         case (fName, info) => {
             var v = e.get(fName)
@@ -272,6 +295,13 @@ object Serialization {
             JField("state", JString(state)) :: Nil) => new Id(id, version.toInt, typeName, state)
     }
 
+    def deserializeSystemAttributes(value: JValue)(implicit format : Formats) = value match {
+        case JObject(JField("createdBy", JString(createdBy))::
+            JField("modifiedBy", JString(modifiedBy))::
+            JField("createdTime", JString(createdTime))::
+            JField("modifiedTime", JString(modifiedTime))::Nil) => new AtlasSystemAttributes(createdBy, modifiedBy, createdTime, modifiedTime)
+    }
+
     def toJson(value: ITypedReferenceableInstance): String = {
         implicit val formats = org.json4s.native.Serialization.formats(NoTypeHints) + new TypedStructSerializer +
             new TypedReferenceableInstanceSerializer + new BigDecimalSerializer + new BigIntegerSerializer


Mime
View raw message