http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/model/notification/HookNotification.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/notification/HookNotification.java 
b/intg/src/main/java/org/apache/atlas/model/notification/HookNotification.java
new file mode 100644
index 0000000..ea77a20
--- /dev/null
+++ 
b/intg/src/main/java/org/apache/atlas/model/notification/HookNotification.java
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.model.notification;
+
+import org.apache.commons.lang.StringUtils;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+/**
+ * Base type of hook message.
+ */
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class HookNotification implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public static final String UNKNOW_USER = "UNKNOWN";
+
+    /**
+     * Type of the hook message.
+     */
+    public enum HookNotificationType {
+        TYPE_CREATE, TYPE_UPDATE, ENTITY_CREATE, ENTITY_PARTIAL_UPDATE, 
ENTITY_FULL_UPDATE, ENTITY_DELETE
+    }
+
+    protected HookNotificationType type;
+    protected String               user;
+
+    public HookNotification() {
+    }
+
+    public HookNotification(HookNotificationType type, String user) {
+        this.type = type;
+        this.user = user;
+    }
+
+    public HookNotificationType getType() {
+        return type;
+    }
+
+    public void setType(HookNotificationType type) {
+        this.type = type;
+    }
+
+    public String getUser() {
+        if (StringUtils.isEmpty(user)) {
+            return UNKNOW_USER;
+        }
+
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public void normalize() { }
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("HookNotification{");
+        sb.append("type=").append(type);
+        sb.append(", user=").append(user);
+        sb.append("}");
+
+        return sb;
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/model/notification/MessageVersion.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/notification/MessageVersion.java 
b/intg/src/main/java/org/apache/atlas/model/notification/MessageVersion.java
new file mode 100644
index 0000000..1dafa94
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/notification/MessageVersion.java
@@ -0,0 +1,170 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.model.notification;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+/**
+ * Represents the version of a notification message.
+ */
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class MessageVersion implements Comparable<MessageVersion>, 
Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Used for message with no version (old format).
+     */
+    public static final MessageVersion NO_VERSION = new MessageVersion("0");
+    public static final MessageVersion VERSION_1  = new 
MessageVersion("1.0.0");
+
+    public static final MessageVersion CURRENT_VERSION = VERSION_1;
+
+    private String version;
+
+
+    // ----- Constructors ----------------------------------------------------
+    public MessageVersion() {
+        this.version = CURRENT_VERSION.version;
+    }
+
+    /**
+     * Create a message version.
+     *
+     * @param version  the version string
+     */
+    public MessageVersion(String version) {
+        this.version = version;
+
+        try {
+            getVersionParts();
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(String.format("Invalid version 
string : %s.", version), e);
+        }
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+
+    // ----- Comparable ------------------------------------------------------
+
+    @Override
+    public int compareTo(MessageVersion that) {
+        if (that == null) {
+            return 1;
+        }
+
+        Integer[] thisParts = getVersionParts();
+        Integer[] thatParts = that.getVersionParts();
+
+        int length = Math.max(thisParts.length, thatParts.length);
+
+        for (int i = 0; i < length; i++) {
+
+            int comp = getVersionPart(thisParts, i) - 
getVersionPart(thatParts, i);
+
+            if (comp != 0) {
+                return comp;
+            }
+        }
+        return 0;
+    }
+
+
+    // ----- Object overrides ------------------------------------------------
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that){
+            return true;
+        }
+
+        if (that == null || getClass() != that.getClass()) {
+            return false;
+        }
+
+        return compareTo((MessageVersion) that) == 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(getVersionParts());
+    }
+
+
+    @Override
+    public String toString() {
+        return "MessageVersion[version=" + version + "]";
+    }
+
+    // ----- helper methods --------------------------------------------------
+
+    /**
+     * Get the version parts array by splitting the version string.
+     * Strip the trailing zeros (i.e. '1.0.0' equals '1').
+     *
+     * @return  the version parts array
+     */
+    public Integer[] getVersionParts() {
+
+        String[] sParts = version.split("\\.");
+        ArrayList<Integer> iParts = new ArrayList<>();
+        int trailingZeros = 0;
+
+        for (String sPart : sParts) {
+            Integer iPart = new Integer(sPart);
+
+            if (iPart == 0) {
+                ++trailingZeros;
+            } else {
+                for (int i = 0; i < trailingZeros; ++i) {
+                    iParts.add(0);
+                }
+                trailingZeros = 0;
+                iParts.add(iPart);
+            }
+        }
+        return iParts.toArray(new Integer[iParts.size()]);
+    }
+
+    public Integer getVersionPart(Integer[] versionParts, int i) {
+        return i < versionParts.length ? versionParts[i] : 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/type/AtlasType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasType.java 
b/intg/src/main/java/org/apache/atlas/type/AtlasType.java
index dc0d300..ce0a475 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasType.java
@@ -20,25 +20,56 @@ package org.apache.atlas.type;
 
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.TypeCategory;
+import org.apache.atlas.model.notification.EntityNotification;
+import 
org.apache.atlas.model.notification.EntityNotification.EntityNotificationType;
+import org.apache.atlas.model.notification.HookNotification;
+import 
org.apache.atlas.model.notification.HookNotification.HookNotificationType;
 import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
-import org.codehaus.jackson.map.DeserializationConfig;
-import org.codehaus.jackson.map.ObjectMapper;
+import org.apache.atlas.v1.model.notification.EntityNotificationV1;
+import 
org.apache.atlas.v1.model.notification.HookNotificationV1.EntityCreateRequest;
+import 
org.apache.atlas.v1.model.notification.HookNotificationV1.EntityDeleteRequest;
+import 
org.apache.atlas.v1.model.notification.HookNotificationV1.EntityPartialUpdateRequest;
+import 
org.apache.atlas.v1.model.notification.HookNotificationV1.EntityUpdateRequest;
+import org.apache.atlas.v1.model.notification.HookNotificationV1.TypeRequest;
+import org.codehaus.jackson.*;
+import org.codehaus.jackson.map.*;
+import org.codehaus.jackson.map.module.SimpleModule;
+import org.codehaus.jackson.node.ObjectNode;
+import org.codehaus.jackson.type.TypeReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.text.ParseException;
+import java.util.Date;
 import java.util.List;
 
 
-
-
 /**
  * base class that declares interface for all Atlas types.
  */
 
 public abstract class AtlasType {
+    private static final Logger LOG = 
LoggerFactory.getLogger(AtlasStructType.class);
 
     private static final ObjectMapper mapper = new ObjectMapper()
                                             
.configure(DeserializationConfig.Feature.USE_BIG_DECIMAL_FOR_FLOATS, true);
 
+    private static final ObjectMapper mapperV1 = new ObjectMapper()
+                                            
.configure(DeserializationConfig.Feature.USE_BIG_DECIMAL_FOR_FLOATS, true);
+
+    static {
+        SimpleModule atlasSerDeModule = new SimpleModule("AtlasSerDe", new 
Version(1, 0, 0, null));
+
+        atlasSerDeModule.addSerializer(Date.class, new DateSerializer());
+        atlasSerDeModule.addDeserializer(Date.class, new DateDeserializer());
+        atlasSerDeModule.addDeserializer(HookNotification.class, new 
HookNotificationDeserializer());
+        atlasSerDeModule.addDeserializer(EntityNotification.class, new 
EntityNotificationDeserializer());
+
+        mapperV1.registerModule(atlasSerDeModule);
+    }
+
+
     private final String       typeName;
     private final TypeCategory typeCategory;
 
@@ -109,6 +140,8 @@ public abstract class AtlasType {
         try {
             ret = mapper.writeValueAsString(obj);
         }catch (IOException e){
+            LOG.error("AtlasType.toJson()", e);
+
             ret = null;
         }
         return ret;
@@ -119,8 +152,134 @@ public abstract class AtlasType {
         try {
             ret =  mapper.readValue(jsonStr, type);
         }catch (IOException e){
+            LOG.error("AtlasType.fromJson()", e);
+
             ret = null;
         }
         return ret;
     }
+
+    public static String toV1Json(Object obj) {
+        String ret;
+        try {
+            ret = mapperV1.writeValueAsString(obj);
+        }catch (IOException e){
+            LOG.error("AtlasType.toV1Json()", e);
+
+            ret = null;
+        }
+        return ret;
+    }
+
+    public static <T> T fromV1Json(String jsonStr, Class<T> type) {
+        T ret;
+        try {
+            ret =  mapperV1.readValue(jsonStr, type);
+        }catch (IOException e){
+            LOG.error("AtlasType.fromV1Json()", e);
+
+            ret = null;
+        }
+        return ret;
+    }
+
+    public static <T> T fromV1Json(String jsonStr, TypeReference<T> type) {
+        T ret;
+        try {
+            ret =  mapperV1.readValue(jsonStr, type);
+        }catch (IOException e){
+            LOG.error("AtlasType.toV1Json()", e);
+
+            ret = null;
+        }
+        return ret;
+    }
+
+    static class DateSerializer extends JsonSerializer<Date> {
+        @Override
+        public void serialize(Date value, JsonGenerator jgen, 
SerializerProvider provider) throws IOException {
+            if (value != null) {
+                
jgen.writeString(AtlasBaseTypeDef.DATE_FORMATTER.format(value));
+            }
+        }
+    }
+
+    static class DateDeserializer extends JsonDeserializer<Date> {
+        @Override
+        public Date deserialize(JsonParser parser, DeserializationContext 
context) throws IOException {
+            Date ret = null;
+
+            String value = parser.readValueAs(String.class);
+
+            if (value != null) {
+                try {
+                    ret = AtlasBaseTypeDef.DATE_FORMATTER.parse(value);
+                } catch (ParseException excp) {
+                }
+            }
+
+            return ret;
+        }
+    }
+
+    static class HookNotificationDeserializer extends 
JsonDeserializer<HookNotification> {
+        @Override
+        public HookNotification deserialize(JsonParser parser, 
DeserializationContext context) throws IOException {
+            HookNotification     ret              = null;
+            ObjectMapper         mapper           = (ObjectMapper) 
parser.getCodec();
+            ObjectNode           root             = (ObjectNode) 
mapper.readTree(parser);
+            JsonNode             typeNode         = root != null ? 
root.get("type") : null;
+            String               strType          = typeNode != null ? 
typeNode.asText() : null;
+            HookNotificationType notificationType = strType != null ? 
HookNotificationType.valueOf(strType) : null;
+
+            if (notificationType != null) {
+                switch (notificationType) {
+                    case TYPE_CREATE:
+                    case TYPE_UPDATE:
+                        ret = mapper.readValue(root, TypeRequest.class);
+                        break;
+
+                    case ENTITY_CREATE:
+                        ret = mapper.readValue(root, 
EntityCreateRequest.class);
+                        break;
+
+                    case ENTITY_PARTIAL_UPDATE:
+                        ret = mapper.readValue(root, 
EntityPartialUpdateRequest.class);
+                        break;
+
+                    case ENTITY_FULL_UPDATE:
+                        ret = mapper.readValue(root, 
EntityUpdateRequest.class);
+                        break;
+
+                    case ENTITY_DELETE:
+                        ret = mapper.readValue(root, 
EntityDeleteRequest.class);
+                        break;
+                }
+            }
+
+            return ret;
+        }
+    }
+
+    static class EntityNotificationDeserializer extends 
JsonDeserializer<EntityNotification> {
+        @Override
+        public EntityNotification deserialize(JsonParser parser, 
DeserializationContext context) throws IOException {
+            EntityNotification     ret              = null;
+            ObjectMapper           mapper           = (ObjectMapper) 
parser.getCodec();
+            ObjectNode             root             = (ObjectNode) 
mapper.readTree(parser);
+            JsonNode               typeNode         = root != null ? 
root.get("type") : null;
+            String                 strType          = typeNode != null ? 
typeNode.asText() : null;
+            EntityNotificationType notificationType = strType != null ? 
EntityNotificationType.valueOf(strType) : 
EntityNotificationType.ENTITY_NOTIFICATION_V1;
+
+            if (root != null) {
+                switch (notificationType) {
+                    case ENTITY_NOTIFICATION_V1:
+                        ret = mapper.readValue(root, 
EntityNotificationV1.class);
+                        break;
+                }
+            }
+
+            return ret;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java 
b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
index bd4b0e9..5f55b43 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
@@ -846,8 +846,8 @@ public class AtlasTypeRegistry {
             boolean alreadyLockedByCurrentThread = 
typeRegistryUpdateLock.isHeldByCurrentThread();
 
             if (!alreadyLockedByCurrentThread) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("lockTypeRegistryForUpdate(): waiting for lock 
to be released by thread {}", lockedByThread);
+                if (lockedByThread != null) {
+                    LOG.info("lockTypeRegistryForUpdate(): waiting for lock to 
be released by thread {}", lockedByThread);
                 }
             } else {
                 LOG.warn("lockTypeRegistryForUpdate(): already locked. 
currentLockCount={}",

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java 
b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
index 5f3cefd..80c6a0c 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
@@ -17,17 +17,29 @@
  */
 package org.apache.atlas.type;
 
-import com.google.common.collect.ImmutableSet;
+import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.model.typedef.*;
+import org.apache.atlas.model.instance.AtlasStruct;
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.atlas.model.typedef.AtlasClassificationDef;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.model.typedef.AtlasEnumDef;
 import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
 import 
org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import 
org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
+import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.v1.model.typedef.AttributeDefinition;
+import org.apache.atlas.v1.model.typedef.ClassTypeDefinition;
+import org.apache.atlas.v1.model.typedef.Multiplicity;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
@@ -35,6 +47,7 @@ import org.apache.commons.lang.StringUtils;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.*;
 
@@ -208,19 +221,19 @@ public class AtlasTypeUtil {
         return new AtlasEnumDef(name, description, "1.0", 
Arrays.asList(enumValues));
     }
 
-    public static AtlasClassificationDef createTraitTypeDef(String name, 
ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
+    public static AtlasClassificationDef createTraitTypeDef(String name, 
Set<String> superTypes, AtlasAttributeDef... attrDefs) {
         return createTraitTypeDef(name, null, superTypes, attrDefs);
     }
 
-    public static AtlasClassificationDef createTraitTypeDef(String name, 
String description, ImmutableSet<String> superTypes, AtlasAttributeDef... 
attrDefs) {
+    public static AtlasClassificationDef createTraitTypeDef(String name, 
String description, Set<String> superTypes, AtlasAttributeDef... attrDefs) {
         return createTraitTypeDef(name, description, "1.0", superTypes, 
attrDefs);
     }
 
-    public static AtlasClassificationDef createTraitTypeDef(String name, 
String description, String version, ImmutableSet<String> superTypes, 
AtlasAttributeDef... attrDefs) {
+    public static AtlasClassificationDef createTraitTypeDef(String name, 
String description, String version, Set<String> superTypes, 
AtlasAttributeDef... attrDefs) {
         return new AtlasClassificationDef(name, description, version, 
Arrays.asList(attrDefs), superTypes);
     }
 
-    public static AtlasClassificationDef createAtlasClassificationDef(String 
name, String description, String version, ImmutableSet<String> superTypes, 
ImmutableSet<String> entityTypes, AtlasAttributeDef... attrDefs) {
+    public static AtlasClassificationDef createAtlasClassificationDef(String 
name, String description, String version, Set<String> superTypes, Set<String> 
entityTypes, AtlasAttributeDef... attrDefs) {
         return new AtlasClassificationDef(name, description, version, 
Arrays.asList(attrDefs), superTypes, entityTypes, null);
     }
 
@@ -232,18 +245,15 @@ public class AtlasTypeUtil {
         return new AtlasStructDef(name, description, "1.0", 
Arrays.asList(attrDefs));
     }
 
-    public static AtlasEntityDef createClassTypeDef(String name,
-        ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
+    public static AtlasEntityDef createClassTypeDef(String name, Set<String> 
superTypes, AtlasAttributeDef... attrDefs) {
         return createClassTypeDef(name, null, "1.0", superTypes, attrDefs);
     }
 
-    public static AtlasEntityDef createClassTypeDef(String name, String 
description,
-        ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
+    public static AtlasEntityDef createClassTypeDef(String name, String 
description, Set<String> superTypes, AtlasAttributeDef... attrDefs) {
         return createClassTypeDef(name, description, "1.0", superTypes, 
attrDefs);
     }
 
-    public static AtlasEntityDef createClassTypeDef(String name, String 
description, String version,
-        ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
+    public static AtlasEntityDef createClassTypeDef(String name, String 
description, String version, Set<String> superTypes, AtlasAttributeDef... 
attrDefs) {
         return new AtlasEntityDef(name, description, version, 
Arrays.asList(attrDefs), superTypes);
     }
 
@@ -409,6 +419,129 @@ public class AtlasTypeUtil {
         return sb.toString();
     }
 
+    public static ClassTypeDefinition toClassTypeDefinition(final 
AtlasEntityType entityType) {
+        ClassTypeDefinition ret = null;
+
+        if (entityType != null) {
+            AtlasEntityDef entityDef = entityType.getEntityDef();
+            ret = new ClassTypeDefinition();
+            ret.setTypeName(entityDef.getName());
+            ret.setTypeDescription(entityDef.getDescription());
+            ret.setTypeVersion(entityDef.getTypeVersion());
+            ret.setSuperTypes(entityDef.getSuperTypes());
+
+            if (MapUtils.isNotEmpty(entityType.getAllAttributes())) {
+                List<AttributeDefinition> attributeDefinitions = 
entityType.getAllAttributes()
+                                                                           
.entrySet()
+                                                                           
.stream()
+                                                                           
.map(e -> toV1AttributeDefinition(e.getValue()))
+                                                                           
.collect(Collectors.toList());
+
+                ret.setAttributeDefinitions(attributeDefinitions);
+            }
+        }
+
+        return ret;
+    }
+
+    public static AttributeDefinition 
toV1AttributeDefinition(AtlasStructType.AtlasAttribute attribute) {
+        AtlasAttributeDef   attributeDef = attribute.getAttributeDef();
+        AttributeDefinition ret = new AttributeDefinition();
+
+        ret.setName(attributeDef.getName());
+        ret.setDataTypeName(attributeDef.getTypeName());
+        ret.setIsUnique(attributeDef.getIsUnique());
+        ret.setIsIndexable(attributeDef.getIsIndexable());
+        ret.setIsComposite(attribute.isOwnedRef());
+        ret.setReverseAttributeName(attribute.getInverseRefAttributeName());
+        ret.setDefaultValue(attributeDef.getDefaultValue());
+        ret.setDescription(attributeDef.getDescription());
+
+        final int lower;
+        final int upper;
+
+        if (attributeDef.getCardinality() == 
AtlasAttributeDef.Cardinality.SINGLE) {
+            lower = attributeDef.getIsOptional() ? 0 : 1;
+            upper = 1;
+        } else {
+            if(attributeDef.getIsOptional()) {
+                lower = 0;
+            } else {
+                lower = attributeDef.getValuesMinCount() < 1 ? 1 : 
attributeDef.getValuesMinCount();
+            }
+
+            upper = attributeDef.getValuesMaxCount() < 2 ? Integer.MAX_VALUE : 
attributeDef.getValuesMaxCount();
+        }
+
+        Multiplicity multiplicity = new Multiplicity();
+        multiplicity.setLower(lower);
+        multiplicity.setUpper(upper);
+        
multiplicity.setIsUnique(AtlasAttributeDef.Cardinality.SET.equals(attributeDef.getCardinality()));
+
+        ret.setMultiplicity(multiplicity);
+
+        return ret;
+    }
+
+    public static Map<String, Object> toMap(AtlasEntity entity) {
+        Map<String, Object> ret = null;
+
+        if (entity != null) {
+            ret = new LinkedHashMap<>();
+
+            // Id type
+            ret.put("$typeName$", entity.getTypeName());
+            ret.put("$id$", new LinkedHashMap<String, Object>(){{
+                put("id", entity.getGuid());
+                put("$typeName$", entity.getTypeName());
+                put("version", entity.getVersion().intValue());
+                put("state", entity.getStatus().name());
+            }});
+
+            // System attributes
+            ret.put("$systemAttributes$", new LinkedHashMap<String, String>() 
{{
+                put("createdBy", entity.getCreatedBy());
+                put("modifiedBy", entity.getUpdatedBy());
+                put("createdTime", entity.getCreateTime().toString());
+                put("modifiedTime", entity.getUpdateTime().toString());
+            }});
+
+            // Traits
+            if (CollectionUtils.isNotEmpty(entity.getClassifications())) {
+                Map<String, HashMap> traitDetails = entity.getClassifications()
+                                                          .stream()
+                                                          
.collect(Collectors.toMap(AtlasStruct::getTypeName, 
AtlasTypeUtil::getNestedTraitDetails));
+                ret.put("$traits$", traitDetails);
+            }
+
+            // All attributes
+            if (MapUtils.isNotEmpty(entity.getAttributes())) {
+                for (Map.Entry<String, Object> entry : 
entity.getAttributes().entrySet()) {
+                    if (entry.getValue() instanceof AtlasObjectId) {
+                        ret.put(entry.getKey(), new LinkedHashMap<String, 
Object>(){{
+                            put("id", ((AtlasObjectId) 
entry.getValue()).getGuid());
+                            put("$typeName$", ((AtlasObjectId) 
entry.getValue()).getTypeName());
+//                        put("version", entity.getVersion().intValue());
+//                        put("state", entity.getStatus().name());
+                        }});
+                    } else {
+                        ret.put(entry.getKey(), entry.getValue());
+                    }
+                }
+            }
+
+        }
+
+        return ret;
+    }
+
+    private static HashMap getNestedTraitDetails(final AtlasClassification 
atlasClassification) {
+        return new HashMap<String, Object>() {{
+            put("$typeName$", atlasClassification.getTypeName());
+            putAll(atlasClassification.getAttributes());
+        }};
+    }
+
     private static void dumpTypeNames(List<? extends AtlasBaseTypeDef> 
typeDefs, StringBuilder sb) {
         if (CollectionUtils.isNotEmpty(typeDefs)) {
             for (int i = 0; i < typeDefs.size(); i++) {

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java 
b/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
new file mode 100644
index 0000000..dba2d88
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
@@ -0,0 +1,35 @@
+/**
+ * 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.types;
+
+/*
+ * this enum must be in package org.apache.atlas.typesystem.types, since 
vertex property in GraphDB has reference to this type
+ */
+public class DataTypes {
+    public enum TypeCategory {
+        PRIMITIVE,
+        ENUM,
+        ARRAY,
+        MAP,
+        STRUCT,
+        TRAIT,
+        CLASS,
+        RELATIONSHIP
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/instance/AtlasSystemAttributes.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/v1/model/instance/AtlasSystemAttributes.java
 
b/intg/src/main/java/org/apache/atlas/v1/model/instance/AtlasSystemAttributes.java
new file mode 100644
index 0000000..0b74365
--- /dev/null
+++ 
b/intg/src/main/java/org/apache/atlas/v1/model/instance/AtlasSystemAttributes.java
@@ -0,0 +1,156 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.v1.model.instance;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class AtlasSystemAttributes implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String createdBy;
+    private String modifiedBy;
+    private Date   createdTime;
+    private Date   modifiedTime;
+
+
+    public AtlasSystemAttributes() {
+    }
+
+    public AtlasSystemAttributes(AtlasSystemAttributes that) {
+        if (that != null) {
+            this.createdBy    = that.createdBy;
+            this.modifiedBy   = that.modifiedBy;
+            this.createdTime  = that.createdTime;
+            this.modifiedTime = that.modifiedTime;
+        }
+    }
+
+    public AtlasSystemAttributes(String createdBy, String modifiedBy, Date 
createdTime, Date modifiedTime){
+        this.createdBy    = createdBy;
+        this.modifiedBy   = modifiedBy;
+        this.createdTime  = createdTime;
+        this.modifiedTime = modifiedTime;
+    }
+
+    public AtlasSystemAttributes(Map<String, Object> map) {
+        this();
+
+        if (map != null) {
+            this.createdBy    = Id.asString(map.get("createdBy"));
+            this.modifiedBy   = Id.asString(map.get("modifiedBy"));
+            this.createdTime  = Id.asDate(map.get("createdTime"));
+            this.modifiedTime = Id.asDate(map.get("modifiedTime"));
+        }
+    }
+
+    public String getCreatedBy(){
+        return createdBy;
+    }
+
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public String getModifiedBy(){
+        return modifiedBy;
+    }
+
+    public void setModifiedBy(String modifiedBy) {
+        this.modifiedBy = modifiedBy;
+    }
+
+    public Date getCreatedTime(){
+        return createdTime;
+    }
+
+    public void setCreatedTime(Date createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public Date getModifiedTime(){
+        return modifiedTime;
+    }
+
+    public void setModifiedTime(Date modifiedTime) {
+        this.modifiedTime = modifiedTime;
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        AtlasSystemAttributes obj = (AtlasSystemAttributes) o;
+
+        return Objects.equals(createdBy, obj.createdBy) &&
+               Objects.equals(modifiedBy, obj.modifiedBy) &&
+               Objects.equals(createdTime, obj.createdTime) &&
+               Objects.equals(modifiedTime, obj.modifiedTime);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(createdBy, modifiedBy, createdTime, modifiedTime);
+    }
+
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("AtlasSystemAttributes{")
+                .append("createdBy=").append(createdBy)
+                .append(", modifiedBy=").append(modifiedBy)
+                .append(", createdTime=").append(createdTime)
+                .append(", modifiedTime=").append(modifiedTime)
+                .append("}");
+
+        return sb;
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/instance/Id.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/v1/model/instance/Id.java 
b/intg/src/main/java/org/apache/atlas/v1/model/instance/Id.java
new file mode 100644
index 0000000..f3087d1
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/v1/model/instance/Id.java
@@ -0,0 +1,270 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.v1.model.instance;
+
+
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class Id implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @JsonIgnore
+    private static AtomicLong s_nextId = new AtomicLong(System.nanoTime());
+
+    public static final String JSON_CLASS_ID = 
"org.apache.atlas.typesystem.json.InstanceSerialization$_Id";
+
+    public enum EntityState { ACTIVE, DELETED }
+
+    private String      id;
+    private String      typeName;
+    private int         version;
+    private EntityState state;
+
+
+    public Id() {
+    }
+
+    public Id(Id that) {
+        if (that != null) {
+            this.id       = that.id;
+            this.typeName = that.typeName;
+            this.version  = that.version;
+            this.state    = that.state;
+        }
+    }
+
+    public Id(String typeName) {
+        this("" + nextNegativeLong(), 0, typeName);
+    }
+
+    public Id(String id, int version, String typeName) {
+        this(id, version, typeName, null);
+    }
+
+    public Id(long id, int version, String typeName) {
+        this(id, version, typeName, null);
+    }
+
+    public Id(long id, int version, String typeName, String state) {
+        this("" + id, version, typeName, state);
+    }
+
+    public Id(String id, int version, String typeName, String state) {
+        this.id       = id;
+        this.typeName = typeName;
+        this.version  = version;
+        this.state    = state == null ? EntityState.ACTIVE : 
EntityState.valueOf(state.toUpperCase());
+    }
+
+    public Id(Map<String, Object> map) {
+        this();
+
+        if (map != null) {
+            this.id       = Id.asString(map.get("id"));
+            this.typeName = Id.asString(map.get("typeName"));
+            this.version  = Id.asInt(map.get("id"));
+            this.state    = Id.asEntityState(map.get("state"));
+        }
+    }
+
+    // for serialization backward compatibility
+    public String getJsonClass() {
+        return JSON_CLASS_ID;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getTypeName() {
+        return typeName;
+    }
+
+    public void setTypeName(String typeName) {
+        this.typeName = typeName;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public EntityState getState() {
+        return state;
+    }
+
+    public void setState(EntityState state) {
+        this.state = state;
+    }
+
+    @JsonIgnore
+    public String _getId() {
+        return id;
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        Id obj = (Id) o;
+
+        return version == obj.version &&
+               Objects.equals(id, obj.id) &&
+               Objects.equals(typeName, obj.typeName) &&
+                Objects.equals(state, obj.state);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, typeName, version, state);
+    }
+
+
+    @Override
+    public String toString() {
+        return asString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder asString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("Id{")
+          .append("id=").append(id)
+          .append(", typeName=").append(typeName)
+          .append(", version=").append(version)
+          .append(", state=").append(state)
+          .append("}");
+
+        return sb;
+    }
+
+    private static long nextNegativeLong() {
+        long ret = s_nextId.getAndDecrement();
+
+        if (ret > 0) {
+            ret *= -1;
+        } else if (ret == 0) {
+            ret = Long.MIN_VALUE;
+        }
+
+        return ret;
+    }
+
+    static String asString(Object val) {
+        return val == null ? null : val.toString();
+    }
+
+    static int asInt(Object val) {
+        if (val != null) {
+            if (val instanceof Number) {
+                return ((Number)val).intValue();
+            }
+
+            try {
+                return Integer.parseInt(val.toString());
+            } catch (NumberFormatException excp) {
+                // ignore
+            }
+        }
+
+        return 0;
+    }
+
+    static Date asDate(Object val) {
+        if (val != null) {
+            if (val instanceof Date) {
+                return (Date) val;
+            } else if (val instanceof Number) {
+                return new Date(((Number)val).longValue());
+            }
+
+            try {
+                return AtlasBaseTypeDef.DATE_FORMATTER.parse(val.toString());
+            } catch (ParseException excp) {
+                // ignore
+            }
+        }
+
+        return null;
+    }
+
+    static EntityState asEntityState(Object val) {
+        if (val != null) {
+            if (val instanceof EntityState) {
+                return (EntityState) val;
+            }
+
+            try {
+                return EntityState.valueOf(val.toString());
+            } catch (Exception excp) {
+                // ignore
+            }
+        }
+
+        return EntityState.ACTIVE;
+    }
+
+    static Map asMap(Object val) {
+        return (val instanceof Map) ? ((Map) val) : null;
+    }
+
+    static List asList(Object val) {
+        return (val instanceof List) ? ((List) val) : null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/instance/Referenceable.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/v1/model/instance/Referenceable.java 
b/intg/src/main/java/org/apache/atlas/v1/model/instance/Referenceable.java
new file mode 100644
index 0000000..f1d28d1
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/v1/model/instance/Referenceable.java
@@ -0,0 +1,252 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.v1.model.instance;
+
+
+
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.commons.collections.MapUtils;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonFilter;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class Referenceable extends Struct implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public static final String JSON_CLASS_REFERENCE = 
"org.apache.atlas.typesystem.json.InstanceSerialization$_Reference";
+
+    private Id                    id;
+    private Map<String, Struct>   traits     = new HashMap<>();
+    private List<String>          traitNames = new ArrayList<>();
+    private AtlasSystemAttributes systemAttributes;
+
+
+    public Referenceable() {
+        super();
+    }
+
+    public Referenceable(Referenceable that) {
+        super(that);
+
+        if (that != null) {
+            this.id = new Id(that.id);
+
+            if (that.traits != null) {
+                this.traits.putAll(that.traits);
+            }
+
+            if (that.traitNames != null) {
+                this.traitNames.addAll(that.traitNames);
+            }
+
+            this.systemAttributes = new 
AtlasSystemAttributes(that.systemAttributes);
+        }
+    }
+
+    public Referenceable(String typeName, String... traitNames) {
+        super(typeName);
+
+        this.id               = new Id(typeName);
+        this.systemAttributes = null;
+
+        if (traitNames != null) {
+            for (String traitName : traitNames) {
+                this.traitNames.add(traitName);
+                this.traits.put(traitName, new Struct(traitName));
+            }
+        }
+    }
+
+    public Referenceable(String typeName, Map<String, Object> values) {
+        this(new Id(typeName), typeName, values, null, null);
+    }
+
+    public Referenceable(String guid, String typeName, Map<String, Object> 
values) {
+        this(new Id(guid, 0, typeName), typeName, values, null, null, null);
+    }
+
+    public Referenceable(String guid, String typeName, Map<String, Object> 
values, AtlasSystemAttributes systemAttributes) {
+        this(new Id(guid, 0, typeName), typeName, values, systemAttributes, 
null, null);
+    }
+
+    public Referenceable(String guid, String typeName, Map<String, Object> 
values, AtlasSystemAttributes systemAttributes, List<String> traitNames, 
Map<String, Struct> traits) {
+        this(new Id(guid, 0, typeName), typeName, values, systemAttributes, 
traitNames, traits);
+    }
+
+    public Referenceable(String guid, String typeName, Map<String, Object> 
values, List<String> traitNames, Map<String, Struct> traits) {
+        this(new Id(guid, 0, typeName), typeName, values, null, traitNames, 
traits);
+    }
+
+    public Referenceable(Id id, String typeName, Map<String, Object> values, 
List<String> traitNames, Map<String, Struct> traits) {
+        this(id, typeName, values, null, traitNames, traits);
+    }
+
+    public Referenceable(Id id, String typeName, Map<String, Object> values, 
AtlasSystemAttributes systemAttributes, List<String> traitNames, Map<String, 
Struct> traits) {
+        super(typeName, values);
+
+        this.id               = id;
+        this.systemAttributes = systemAttributes;
+
+        if (traitNames != null) {
+            this.traitNames = traitNames;
+        }
+
+        if (traits != null) {
+            this.traits = traits;
+        }
+    }
+
+    public Referenceable(Map<String, Object> map) {
+        super(map);
+
+        if (map != null) {
+            this.id               = new Id((Map)map.get("id"));
+            this.traitNames       = Id.asList(map.get("traitNames"));
+            this.systemAttributes = new AtlasSystemAttributes((Map) 
map.get("systemAttributes"));
+
+            Map traits = Id.asMap(map.get("traits"));
+
+            if (MapUtils.isNotEmpty(traits)) {
+                this.traits = new HashMap<>(traits.size());
+
+                for (Object key : traits.keySet()) {
+                    this.traits.put(Id.asString(key), new 
Struct(Id.asMap(traits.get(key))));
+                }
+            }
+        }
+    }
+
+
+    // for serialization backward compatibility
+    public String getJsonClass() {
+        return JSON_CLASS_REFERENCE;
+    }
+
+    public Id getId() {
+        return id;
+    }
+
+    public void setId(Id id) {
+        this.id = id;
+    }
+
+    public Map<String, Struct> getTraits() {
+        return traits;
+    }
+
+    public void setTraits(Map<String, Struct> traits) {
+        this.traits = traits;
+    }
+
+    public List<String> getTraitNames() {
+        return traitNames;
+    }
+
+    public void setTraitNames(List<String> traitNames) {
+        this.traitNames = traitNames;
+    }
+
+    public AtlasSystemAttributes getSystemAttributes() {
+        return systemAttributes;
+    }
+
+    public void setSystemAttributes(AtlasSystemAttributes systemAttributes) {
+        this.systemAttributes = systemAttributes;
+    }
+
+    @JsonIgnore
+    public Struct getTrait(String name) {
+        return traits != null ? traits.get(name) : null;
+    }
+
+    @JsonIgnore
+    public String toShortString() {
+        return String.format("entity[type=%s guid=%s]", getTypeName(), 
id._getId());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || o.getClass() != getClass()) {
+            return false;
+        }
+
+        Referenceable obj = (Referenceable)o;
+
+        return Objects.equals(id, obj.id) &&
+               Objects.equals(traits, obj.traits) &&
+               Objects.equals(traitNames, obj.traitNames) &&
+               Objects.equals(systemAttributes, obj.systemAttributes);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, traits, traitNames, systemAttributes);
+    }
+
+
+    @Override
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("Referenceable{");
+        super.toString(sb);
+        sb.append(", id=");
+        if (id != null) {
+            id.asString(sb);
+        }
+        sb.append(", triats={");
+        AtlasBaseTypeDef.dumpObjects(this.traits, sb);
+        sb.append("}, traitNames=[");
+        AtlasBaseTypeDef.dumpObjects(traitNames, sb);
+        sb.append("], systemAttributes=");
+        if (systemAttributes != null) {
+            systemAttributes.toString(sb);
+        }
+        sb.append("}");
+
+        return sb;
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/instance/Struct.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/v1/model/instance/Struct.java 
b/intg/src/main/java/org/apache/atlas/v1/model/instance/Struct.java
new file mode 100644
index 0000000..5aebd4b
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/v1/model/instance/Struct.java
@@ -0,0 +1,211 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.v1.model.instance;
+
+
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.commons.collections.MapUtils;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.*;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class Struct implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public static final String JSON_CLASS_STRUCT = 
"org.apache.atlas.typesystem.json.InstanceSerialization$_Struct";
+
+    private String              typeName;
+    private Map<String, Object> values;
+
+
+    public Struct() {
+    }
+
+    public Struct(Struct that) {
+        if (that != null) {
+            this.typeName = that.typeName;
+
+            if (that.values != null) {
+                this.values = new HashMap<>(that.values);
+            }
+        }
+    }
+
+    public Struct(String typeName) {
+        this(typeName, null);
+    }
+
+    public Struct(String typeName, Map<String, Object> values) {
+        this.typeName = typeName;
+        this.values   = values;
+    }
+
+    public Struct(Map<String, Object> map) {
+        this();
+
+        if (map != null) {
+            this.typeName = Id.asString(map.get("typeName"));
+            this.values   = Id.asMap(map.get("values"));
+
+            this.normailze();
+        }
+    }
+
+    // for serialization backward compatibility
+    public String getJsonClass() {
+        return JSON_CLASS_STRUCT;
+    }
+
+    public String getTypeName() {
+        return typeName;
+    }
+
+    public void setTypeName(String typeName) {
+        this.typeName = typeName;
+    }
+
+    public Map<String, Object> getValues() {
+        return values;
+    }
+
+    public void setValues(Map<String, Object> values) {
+        this.values = values;
+    }
+
+    @JsonIgnore
+    public Map<String, Object> getValuesMap() {
+        return values;
+    }
+
+    @JsonIgnore
+    public void set(String attrName, Object attrValue) {
+        if (values == null) {
+            values = new HashMap<>();
+        }
+
+        values.put(attrName, attrValue);
+    }
+
+    @JsonIgnore
+    public Object get(String attrName) {
+        return values != null ? values.get(attrName) : null;
+    }
+
+    @JsonIgnore
+    public void setNull(String attrName) {
+        if (values != null) {
+            values.remove(attrName);
+        }
+    }
+
+    public void normailze() {
+        if (MapUtils.isEmpty(values)) {
+            return;
+        }
+
+        for (Map.Entry<String, Object> entry : values.entrySet()) {
+            entry.setValue(normalizeAttributeValue(entry.getValue()));
+        }
+    }
+
+    private Object normalizeAttributeValue(Object value) {
+        if (value instanceof Map) {
+            Map    mapValue  = (Map) value;
+            String jsonClass = (String)mapValue.get("jsonClass");
+
+            if (jsonClass != null) {
+                if (Id.JSON_CLASS_ID.equals(jsonClass)) {
+                    value = new Id(mapValue);
+                } else if (Struct.JSON_CLASS_STRUCT.equals(jsonClass)) {
+                    value = new Struct(mapValue);
+                } else if 
(Referenceable.JSON_CLASS_REFERENCE.equals(jsonClass)) {
+                    value = new Referenceable(mapValue);
+                }
+            }
+        } else if (value instanceof List) {
+            List<Object> listValue       = (List) value;
+            List<Object> normalizedValue = new ArrayList<>(listValue.size());
+
+            for (Object val : listValue) {
+                normalizedValue.add(normalizeAttributeValue(val));
+            }
+
+            value = normalizedValue;
+        }
+
+        return value;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || o.getClass() != getClass()) {
+            return false;
+        }
+
+        Struct obj = (Struct)o;
+
+        return Objects.equals(typeName, obj.typeName) &&
+               Objects.equals(values, obj.values);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(typeName, values);
+    }
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("Struct{");
+        sb.append("typeName=").append(typeName);
+        sb.append(", values={");
+        AtlasBaseTypeDef.dumpObjects(values, sb);
+        sb.append("}");
+        sb.append("}");
+
+        return sb;
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/lineage/DataSetLineageResponse.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/v1/model/lineage/DataSetLineageResponse.java
 
b/intg/src/main/java/org/apache/atlas/v1/model/lineage/DataSetLineageResponse.java
new file mode 100644
index 0000000..b073bac
--- /dev/null
+++ 
b/intg/src/main/java/org/apache/atlas/v1/model/lineage/DataSetLineageResponse.java
@@ -0,0 +1,65 @@
+/**
+ * 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.v1.model.lineage;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = 
PUBLIC_ONLY, fieldVisibility = NONE)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class DataSetLineageResponse extends LineageResponse {
+    private String tableName;
+
+    public DataSetLineageResponse() {
+    }
+
+    public DataSetLineageResponse(final DataSetLineageResponse other) {
+        super(other);
+        this.tableName = other.tableName;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public void setTableName(final String tableName) {
+        this.tableName = tableName;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        final DataSetLineageResponse that = (DataSetLineageResponse) o;
+        return Objects.equals(tableName, that.tableName);
+    }
+
+    @Override
+    public int hashCode() {
+
+        return Objects.hash(super.hashCode(), tableName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/lineage/LineageResponse.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/v1/model/lineage/LineageResponse.java 
b/intg/src/main/java/org/apache/atlas/v1/model/lineage/LineageResponse.java
new file mode 100644
index 0000000..aadbba1
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/v1/model/lineage/LineageResponse.java
@@ -0,0 +1,75 @@
+/**
+ * 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.v1.model.lineage;
+
+import org.apache.atlas.v1.model.instance.Struct;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = 
PUBLIC_ONLY, fieldVisibility = NONE)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LineageResponse {
+    private String requestId;
+    private Struct results;
+
+    public LineageResponse() {
+    }
+
+    public LineageResponse(final LineageResponse other) {
+        this.requestId = other.requestId;
+        this.results = other.results;
+    }
+
+    public Struct getResults() {
+        return results;
+    }
+
+    public void setResults(final Struct results) {
+        this.results = results;
+    }
+
+    public String getRequestId() {
+        return requestId;
+    }
+
+    public void setRequestId(final String requestId) {
+        this.requestId = requestId;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        final LineageResponse that = (LineageResponse) o;
+        return Objects.equals(requestId, that.requestId) &&
+                Objects.equals(results, that.results);
+    }
+
+    @Override
+    public int hashCode() {
+
+        return Objects.hash(requestId, results);
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/lineage/SchemaResponse.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/v1/model/lineage/SchemaResponse.java 
b/intg/src/main/java/org/apache/atlas/v1/model/lineage/SchemaResponse.java
new file mode 100644
index 0000000..e17553e
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/v1/model/lineage/SchemaResponse.java
@@ -0,0 +1,116 @@
+/**
+ * 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.v1.model.lineage;
+
+import org.apache.atlas.v1.model.typedef.ClassTypeDefinition;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = 
PUBLIC_ONLY, fieldVisibility = NONE)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SchemaResponse {
+    private String        requestId;
+    private String        tableName;
+    private SchemaDetails results;
+
+    public SchemaResponse() {
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public void setTableName(final String tableName) {
+        this.tableName = tableName;
+    }
+
+    public String getRequestId() {
+        return requestId;
+    }
+
+    public void setRequestId(final String requestId) {
+        this.requestId = requestId;
+    }
+
+    public SchemaDetails getResults() {
+        return results;
+    }
+
+    public void setResults(final SchemaDetails results) {
+        this.results = results;
+    }
+
+    /**
+     * Represents the column schema for a given hive table
+     */
+    @JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = 
PUBLIC_ONLY, fieldVisibility = NONE)
+    @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class SchemaDetails {
+        private ClassTypeDefinition       dataType;   // Data type of the 
(hive) columns
+        private List<Map<String, Object>> rows;       // Column instances for 
the given table
+
+        public SchemaDetails() {
+        }
+
+        public SchemaDetails(final SchemaDetails other) {
+            this.dataType = other.dataType;
+            this.rows = other.rows;
+        }
+
+        public ClassTypeDefinition getDataType() {
+            return dataType;
+        }
+
+        public void setDataType(final ClassTypeDefinition dataType) {
+            this.dataType = dataType;
+        }
+
+        public List<Map<String, Object>> getRows() {
+            return rows;
+        }
+
+        public void setRows(final List<Map<String, Object>> rows) {
+            this.rows = rows;
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            final SchemaDetails that = (SchemaDetails) o;
+            return Objects.equals(dataType, that.dataType) &&
+                    Objects.equals(rows, that.rows);
+        }
+
+        @Override
+        public int hashCode() {
+
+            return Objects.hash(dataType, rows);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/intg/src/main/java/org/apache/atlas/v1/model/notification/EntityNotificationV1.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/v1/model/notification/EntityNotificationV1.java
 
b/intg/src/main/java/org/apache/atlas/v1/model/notification/EntityNotificationV1.java
new file mode 100644
index 0000000..549dbe3
--- /dev/null
+++ 
b/intg/src/main/java/org/apache/atlas/v1/model/notification/EntityNotificationV1.java
@@ -0,0 +1,231 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.v1.model.notification;
+
+import org.apache.atlas.model.notification.EntityNotification;
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.atlas.v1.model.instance.Referenceable;
+import org.apache.atlas.v1.model.instance.Struct;
+import org.apache.atlas.type.AtlasClassificationType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static 
org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+/**
+ * Entity notification
+ */
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class EntityNotificationV1 extends EntityNotification implements 
Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public enum OperationType {
+        ENTITY_CREATE,
+        ENTITY_UPDATE,
+        ENTITY_DELETE,
+        TRAIT_ADD,
+        TRAIT_DELETE,
+        TRAIT_UPDATE
+    }
+
+    private Referenceable entity;
+    private OperationType operationType;
+    private List<Struct>  traits;
+
+
+    // ----- Constructors 
------------------------------------------------------
+
+    /**
+     * No-arg constructor for serialization.
+     */
+    public EntityNotificationV1() {
+    }
+
+    /**
+     * Construct an EntityNotificationV1.
+     *
+     * @param entity            the entity subject of the notification
+     * @param operationType     the type of operation that caused the 
notification
+     * @param traits            the traits for the given entity
+     */
+    public EntityNotificationV1(Referenceable entity, OperationType 
operationType, List<Struct> traits) {
+        this.entity        = entity;
+        this.operationType = operationType;
+        this.traits        = traits;
+    }
+
+    /**
+     * Construct an EntityNotificationV1.
+     *
+     * @param entity         the entity subject of the notification
+     * @param operationType  the type of operation that caused the notification
+     * @param typeRegistry     the Atlas type system
+     */
+    public EntityNotificationV1(Referenceable entity, OperationType 
operationType, AtlasTypeRegistry typeRegistry) {
+        this(entity, operationType, getAllTraits(entity, typeRegistry));
+    }
+
+    public Referenceable getEntity() {
+        return entity;
+    }
+
+    public void setEntity(Referenceable entity) {
+        this.entity = entity;
+    }
+
+    public OperationType getOperationType() {
+        return operationType;
+    }
+
+    public void setOperationType(OperationType operationType) {
+        this.operationType = operationType;
+    }
+
+    public List<Struct> getTraits() {
+        return traits;
+    }
+
+    public void setTraits(List<Struct> traits) {
+        this.traits = traits;
+    }
+
+    @JsonIgnore
+    public List<Struct> getAllTraits() {
+        return traits;
+    }
+
+    public void normalize() {
+        super.normalize();
+
+        if (entity != null) {
+            entity.normailze();
+        }
+
+        if (traits != null) {
+            for (Struct trait : traits) {
+                if (trait != null) {
+                    trait.normailze();
+                }
+            }
+        }
+    }
+
+    // ----- Object overrides 
--------------------------------------------------
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        EntityNotificationV1 that = (EntityNotificationV1) o;
+        return Objects.equals(entity, that.entity) &&
+                operationType == that.operationType &&
+                Objects.equals(traits, that.traits);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(entity, operationType, traits);
+    }
+
+    @Override
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("EntityNotificationV1{");
+        super.toString(sb);
+        sb.append(", entity=");
+        if (entity != null) {
+            entity.toString(sb);
+        } else {
+            sb.append(entity);
+        }
+        sb.append(", operationType=").append(operationType);
+        sb.append(", traits=[");
+        AtlasBaseTypeDef.dumpObjects(traits, sb);
+        sb.append("]");
+        sb.append("}");
+
+        return sb;
+    }
+
+
+    // ----- helper methods 
----------------------------------------------------
+
+    private static List<Struct> getAllTraits(Referenceable entityDefinition, 
AtlasTypeRegistry typeRegistry) {
+        List<Struct> ret = new LinkedList<>();
+
+        for (String traitName : entityDefinition.getTraitNames()) {
+            Struct                  trait          = 
entityDefinition.getTrait(traitName);
+            AtlasClassificationType traitType      = 
typeRegistry.getClassificationTypeByName(traitName);
+            Set<String>             superTypeNames = traitType != null ? 
traitType.getAllSuperTypes() : null;
+
+            ret.add(trait);
+
+            if (CollectionUtils.isNotEmpty(superTypeNames)) {
+                for (String superTypeName : superTypeNames) {
+                    Struct superTypeTrait = new Struct(superTypeName);
+
+                    if (MapUtils.isNotEmpty(trait.getValues())) {
+                        AtlasClassificationType superType = 
typeRegistry.getClassificationTypeByName(superTypeName);
+
+                        if (superType != null && 
MapUtils.isNotEmpty(superType.getAllAttributes())) {
+                            Map<String, Object> superTypeTraitAttributes = new 
HashMap<>();
+
+                            for (Map.Entry<String, Object> attrEntry : 
trait.getValues().entrySet()) {
+                                String attrName = attrEntry.getKey();
+
+                                if 
(superType.getAllAttributes().containsKey(attrName)) {
+                                    superTypeTraitAttributes.put(attrName, 
attrEntry.getValue());
+                                }
+                            }
+
+                            superTypeTrait.setValues(superTypeTraitAttributes);
+                        }
+                    }
+
+                    ret.add(superTypeTrait);
+                }
+            }
+        }
+
+        return ret;
+    }
+}

Reply via email to