You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2016/11/19 00:22:05 UTC
incubator-atlas git commit: ATLAS-916: Return System Attributes in
get entity definition [Forced Update!]
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 <sv...@apache.org>
Authored: Fri Nov 18 20:35:26 2016 +0530
Committer: Madhan Neethiraj <ma...@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