ATLAS-2534: Atlas Glossary - REST API

Change-Id: I47210446be9e38c274bae0ee4a688187ba6e4fd0
Signed-off-by: Madhan Neethiraj <[email protected]>


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

Branch: refs/heads/master
Commit: 75415862cc2708ee866d2d29ca603a4e6306f408
Parents: 6812a7d
Author: apoorvnaik <[email protected]>
Authored: Wed Mar 14 21:03:37 2018 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Mon Apr 9 23:06:36 2018 -0700

----------------------------------------------------------------------
 .../models/0000-Area0/0011-glossary_model.json  |  880 +++++++++++++
 .../repository/graphdb/AtlasGraphQuery.java     |   11 +
 .../query/NativeTinkerpopGraphQuery.java        |    8 +
 .../tinkerpop/query/TinkerpopGraphQuery.java    |   11 +-
 .../tinkerpop/query/expr/OrderByPredicate.java  |   41 +
 .../graphdb/janus/AtlasJanusGraph.java          |   41 +-
 .../janus/query/NativeJanusGraphQuery.java      |    8 +
 .../titan0/query/NativeTitan0GraphQuery.java    |   13 +-
 .../java/org/apache/atlas/AtlasErrorCode.java   |    6 +-
 .../atlas/model/AtlasBaseModelObject.java       |   37 +-
 .../atlas/model/annotation/AtlasJSON.java       |   36 +
 .../atlas/model/glossary/AtlasGlossary.java     |  222 ++++
 .../model/glossary/AtlasGlossaryBaseObject.java |  129 ++
 .../model/glossary/AtlasGlossaryCategory.java   |  174 +++
 .../atlas/model/glossary/AtlasGlossaryTerm.java |  453 +++++++
 .../enums/AtlasTermAssignmentStatus.java        |   39 +
 .../enums/AtlasTermRelationshipStatus.java      |   37 +
 .../glossary/relations/AtlasGlossaryHeader.java |   79 ++
 .../relations/AtlasRelatedCategoryHeader.java   |   93 ++
 .../relations/AtlasRelatedTermHeader.java       |  139 +++
 .../relations/AtlasTermAssignmentHeader.java    |  162 +++
 .../AtlasTermCategorizationHeader.java          |  107 ++
 .../atlas/model/instance/AtlasEntity.java       |   31 +-
 .../atlas/model/instance/AtlasEntityHeader.java |   95 +-
 .../atlas/model/instance/AtlasRelationship.java |    3 -
 .../atlas/type/AtlasRelationshipType.java       |    2 -
 .../apache/atlas/glossary/GlossaryService.java  | 1159 ++++++++++++++++++
 .../ogm/AbstractDataTransferObject.java         |   20 +-
 .../repository/ogm/AtlasSavedSearchDTO.java     |  105 --
 .../repository/ogm/AtlasUserProfileDTO.java     |  115 --
 .../atlas/repository/ogm/DTORegistry.java       |   21 +-
 .../apache/atlas/repository/ogm/DataAccess.java |  196 ++-
 .../ogm/glossary/AbstractGlossaryDTO.java       |  163 +++
 .../ogm/glossary/AtlasGlossaryCategoryDTO.java  |  159 +++
 .../ogm/glossary/AtlasGlossaryDTO.java          |  155 +++
 .../ogm/glossary/AtlasGlossaryTermDTO.java      |  250 ++++
 .../ogm/profiles/AtlasSavedSearchDTO.java       |  110 ++
 .../ogm/profiles/AtlasUserProfileDTO.java       |  120 ++
 .../graph/v1/AtlasEntityChangeNotifier.java     |    6 +-
 .../store/graph/v1/AtlasGraphUtilsV1.java       |   20 +-
 .../store/graph/v1/EntityGraphRetriever.java    |    9 +
 .../userprofile/UserProfileService.java         |    4 +-
 .../test/java/org/apache/atlas/TestModules.java |   25 +-
 .../atlas/glossary/GlossaryServiceTest.java     |  641 ++++++++++
 .../atlas/glossary/PaginationHelperTest.java    |   64 +
 .../impexp/ZipFileResourceTestUtils.java        |   42 +-
 .../userprofile/UserProfileServiceTest.java     |   10 +-
 .../EntityNotificationListenerV2.java           |   35 +-
 .../org/apache/atlas/web/rest/GlossaryREST.java |  839 +++++++++++++
 49 files changed, 6735 insertions(+), 390 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/addons/models/0000-Area0/0011-glossary_model.json
----------------------------------------------------------------------
diff --git a/addons/models/0000-Area0/0011-glossary_model.json 
b/addons/models/0000-Area0/0011-glossary_model.json
new file mode 100644
index 0000000..ae7e5c7
--- /dev/null
+++ b/addons/models/0000-Area0/0011-glossary_model.json
@@ -0,0 +1,880 @@
+{
+  "enumDefs": [
+    {
+      "name": "__AtlasGlossaryTermRelationshipStatus",
+      "description": "TermRelationshipStatus defines how reliable the 
relationship is between two glossary terms",
+      "typeVersion": "1.0",
+      "elementDefs": [
+        {
+          "ordinal": 0,
+          "value": "DRAFT",
+          "description": "DRAFT means the relationship is under development."
+        },
+        {
+          "ordinal": 1,
+          "value": "ACTIVE",
+          "description": "ACTIVE means the relationship is validated and in 
use."
+        },
+        {
+          "ordinal": 2,
+          "value": "DEPRECATED",
+          "description": "DEPRECATED means the the relationship is being 
phased out."
+        },
+        {
+          "ordinal": 3,
+          "value": "OBSOLETE",
+          "description": "OBSOLETE means that the relationship should not be 
used anymore."
+        },
+        {
+          "ordinal": 99,
+          "value": "OTHER",
+          "description": "OTHER means that there is another status."
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryTermAssignmentStatus",
+      "description": "TermAssignmentStatus defines how much the semantic 
assignment should be trusted.",
+      "typeVersion": "1.0",
+      "elementDefs": [
+        {
+          "value": "DISCOVERED",
+          "ordinal": 0,
+          "description": "DISCOVERED means that the semantic assignment was 
added by a discovery engine."
+        },
+        {
+          "value": "PROPOSED",
+          "ordinal": 1,
+          "description": "PROPOSED means that the semantic assignment was 
proposed by person - they may be a subject matter expert, or consumer of the 
Referenceable asset"
+        },
+        {
+          "value": "IMPORTED",
+          "ordinal": 2,
+          "description": "IMPORTED means that the semantic assignment has been 
imported from outside of the open metadata cluster"
+        },
+        {
+          "value": "VALIDATED",
+          "ordinal": 3,
+          "description": "VALIDATED means that the semantic assignment has 
been reviewed and is highly trusted."
+        },
+        {
+          "value": "DEPRECATED",
+          "ordinal": 4,
+          "description": "DEPRECATED means that the semantic assignment is 
being phased out. There may be another semantic assignment to the Referenceable 
that will ultimately replace this one."
+        },
+        {
+          "value": "OBSOLETE",
+          "ordinal": 5,
+          "description": "OBSOLETE means that the semantic assignment is no 
longer in use,"
+        },
+        {
+          "value": "OTHER",
+          "ordinal": 6,
+          "description": "OTHER means that the semantic assignment value does 
not match any of the other Term Assignment Status values"
+        }
+      ]
+    }
+  ],
+  "structDefs": [],
+  "classificationDefs": [],
+  "entityDefs": [
+    {
+      "name": "__AtlasGlossary",
+      "superTypes": [
+        "__internal"
+      ],
+      "typeVersion": "1.0",
+      "attributeDefs": [
+        {
+          "name": "qualifiedName",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": false,
+          "isUnique": true
+        },
+        {
+          "name": "displayName",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": false,
+          "isUnique": false
+        },
+        {
+          "name": "shortDescription",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "longDescription",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "language",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "usage",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryTerm",
+      "superTypes": [
+        "__internal"
+      ],
+      "typeVersion": "1.0",
+      "attributeDefs": [
+        {
+          "name": "qualifiedName",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": false,
+          "isUnique": true
+        },
+        {
+          "name": "displayName",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": false,
+          "isUnique": false
+        },
+        {
+          "name": "shortDescription",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "longDescription",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "examples",
+          "typeName": "array<string>",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "abbreviation",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "usage",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryCategory",
+      "superTypes": [
+        "__internal"
+      ],
+      "typeVersion": "1.0",
+      "attributeDefs": [
+        {
+          "name": "qualifiedName",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": false,
+          "isUnique": true
+        },
+        {
+          "name": "displayName",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": false,
+          "isUnique": false
+        },
+        {
+          "name": "shortDescription",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "longDescription",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        }
+      ]
+    }
+  ],
+  "relationshipDefs": [
+    {
+      "name": "__AtlasGlossarySemanticAssignment",
+      "description": "SemanticAssignment is a relationship used to assign a 
term to a referenceable object. This means that the term describes the meaning 
of the referenceable object. The semantic assignment needs to be a controlled 
relationship when glossary definitions are used to provide classifications for 
the data assets and hence define how the data is to be governed.",
+      "typeVersion": "1.0",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the semantic assignment.",
+          "typeName": "string",
+          "isOptional": true,
+          "cardinality": "SINGLE",
+          "valuesMinCount": 0,
+          "valuesMaxCount": 1,
+          "isUnique": false,
+          "isIndexable": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "isOptional": true,
+          "cardinality": "SINGLE",
+          "valuesMinCount": 0,
+          "valuesMaxCount": 1,
+          "isUnique": false,
+          "isIndexable": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "isOptional": true,
+          "cardinality": "SINGLE",
+          "valuesMinCount": 0,
+          "valuesMaxCount": 1,
+          "isUnique": false,
+          "isIndexable": true
+        },
+        {
+          "name": "confidence",
+          "description": "The confidence attribute in the semantic assignment 
stores the level of confidence (0-100%) in the correctness of the semantic 
assignment - it is typically used by discovery engines.",
+          "typeName": "int",
+          "isOptional": true,
+          "cardinality": "SINGLE",
+          "valuesMinCount": 0,
+          "valuesMaxCount": 1,
+          "isUnique": false,
+          "isIndexable": true
+        },
+        {
+          "name": "createdBy",
+          "description": "The semantic assignment is created by the user 
(person or engine) identified by the createdBy attribute.",
+          "typeName": "string",
+          "isOptional": true,
+          "cardinality": "SINGLE",
+          "valuesMinCount": 0,
+          "valuesMaxCount": 1,
+          "isUnique": false,
+          "isIndexable": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the semantic assignment and deciding if it should be approved or not.",
+          "typeName": "string",
+          "isOptional": true,
+          "cardinality": "SINGLE",
+          "valuesMinCount": 0,
+          "valuesMaxCount": 1,
+          "isUnique": false,
+          "isIndexable": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "isOptional": true,
+          "cardinality": "SINGLE",
+          "valuesMinCount": 0,
+          "valuesMaxCount": 1,
+          "isUnique": false,
+          "isIndexable": true
+        }
+      ],
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "ONE_TO_TWO",
+      "endDef1": {
+        "type": "__AtlasGlossaryTerm",
+        "name": "assignedEntities",
+        "isContainer": false,
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "type": "Referenceable",
+        "name": "meanings",
+        "isContainer": false,
+        "cardinality": "SET"
+      }
+    },
+    {
+      "name": "__AtlasGlossaryTermAnchor",
+      "typeVersion": "1.0",
+      "description": "TermAnchor links each term to exactly one Glossary 
object. This means that this is its home glossary. If the Glossary object is 
deleted, then so are all of the terms linked to it.",
+      "endDef1": {
+        "name": "terms",
+        "type": "__AtlasGlossary",
+        "cardinality": "SET",
+        "isContainer": true
+      },
+      "endDef2": {
+        "name": "anchor",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SINGLE"
+      },
+      "relationshipCategory": "COMPOSITION",
+      "propagateTags": "NONE"
+    },
+    {
+      "name": "__AtlasGlossaryTermCategorization",
+      "typeVersion": "1.0",
+      "description": "TermCategorization is a relationship used to organize 
terms into categories. A term may be linked with many categories and a category 
may have many terms linked to it. This relationship may connect terms and 
categories both in the same glossary or in different glossaries.",
+      "endDef1": {
+        "name": "terms",
+        "type": "__AtlasGlossaryCategory",
+        "cardinality": "SET",
+        "isContainer": true
+      },
+      "endDef2": {
+        "name": "categories",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "AGGREGATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true,
+          "isUnique": false
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true,
+          "isUnique": false
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryCategoryAnchor",
+      "typeVersion": "1.0",
+      "description": "CategoryAnchor links each category to exactly one 
Glossary object. This means that this is its home glossary. If the Glossary 
object is deleted then so are all of the categories linked to it.",
+      "endDef1": {
+        "name": "categories",
+        "type": "__AtlasGlossary",
+        "cardinality": "SET",
+        "isContainer": true
+      },
+      "endDef2": {
+        "name": "anchor",
+        "type": "__AtlasGlossaryCategory",
+        "cardinality": "SINGLE"
+      },
+      "relationshipCategory": "COMPOSITION",
+      "propagateTags": "NONE"
+    },
+    {
+      "name": "__AtlasGlossaryCategoryHierarchyLink",
+      "typeVersion": "1.0",
+      "description": "CategoryHierarchyLink is a relationship used to organize 
categories into a hierarchy to, for example, create a structure for a taxonomy. 
A category may have none or one super-categories. This super-category may be in 
a different glossary.",
+      "endDef1": {
+        "name": "childrenCategories",
+        "type": "__AtlasGlossaryCategory",
+        "cardinality": "SET",
+        "isContainer": true
+      },
+      "endDef2": {
+        "name": "parentCategory",
+        "type": "__AtlasGlossaryCategory",
+        "cardinality": "SINGLE"
+      },
+      "relationshipCategory": "AGGREGATION",
+      "propagateTags": "NONE"
+    },
+    {
+      "name": "__AtlasGlossaryRelatedTerm",
+      "typeVersion": "1.0",
+      "description": "RelatedTerm is a relationship used to say that the 
linked glossary term may also be of interest. It is like a 'see also' link in a 
dictionary.",
+      "endDef1": {
+        "name": "seeAlso",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "seeAlso",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to explain why the 
linked term is of interest.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossarySynonym",
+      "typeVersion": "1.0",
+      "description": "Synonym is a relationship between glossary terms that 
have the same, or a very similar meaning in the same language. Notice that both 
ends of this relationship have the same name and refer to the same type; this 
results in one Synonym attribute being added to GlossaryTerm.",
+      "endDef1": {
+        "name": "synonyms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "synonyms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the relationship.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryAntonym",
+      "typeVersion": "1.0",
+      "description": "Antonym is a relationship between glossary terms that 
have the opposite (or near opposite) meaning, in the same language. Notice that 
both ends of this relationship have the same name and refer to the same type; 
this results in one Antonym attribute being added to GlossaryTerm.",
+      "endDef1": {
+        "name": "antonyms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "antonyms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the relationship.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryPreferredTerm",
+      "typeVersion": "1.0",
+      "description": "PreferredTerm is a relationship that indicates that the 
preferredTerm should be used in place of the preferredToTerm. This relationship 
can be used to encourage adoption of newer vocabularies. This is a weaker 
version of ReplacementTerm.",
+      "endDef1": {
+        "name": "preferredTerms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "preferredToTerms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the relationship.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryReplacementTerm",
+      "typeVersion": "1.0",
+      "description": "ReplacementTerm is a relationship that indicates that 
the replacementTerm must be used instead of the replacedByTerm. This is 
stronger version of the PreferredTerm.",
+      "endDef1": {
+        "name": "replacedBy",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "replacementTerms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the relationship.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryTranslation",
+      "typeVersion": "1.0",
+      "description": "Translation is a relationship that defines that the 
related terms represent the same meaning, but each are written in a different 
language. Hence one is a translation of the other. The language of each term is 
defined in the Glossary object that anchors the term.",
+      "endDef1": {
+        "name": "translatedTerms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "translationTerms",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the relationship.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryIsARelationship",
+      "typeVersion": "1.0",
+      "description": "IsA is a relationship that defines that the 'isA' term 
is a more generic term than the 'isOf' term. For example, this relationship 
would be use to say that 'Cat' ISA 'Animal'.",
+      "endDef1": {
+        "name": "classifies",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "isA",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the relationship.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    },
+    {
+      "name": "__AtlasGlossaryValidValue",
+      "typeVersion": "1.0",
+      "description": "ValidValue is a relationship that shows the validValue 
term represents one of the valid values that could be assigned to a data item 
that has the meaning described in the validValueFor term.",
+      "endDef1": {
+        "name": "validValuesFor",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "endDef2": {
+        "name": "validValues",
+        "type": "__AtlasGlossaryTerm",
+        "cardinality": "SET"
+      },
+      "relationshipCategory": "ASSOCIATION",
+      "propagateTags": "NONE",
+      "attributeDefs": [
+        {
+          "name": "description",
+          "description": "The description field can be used to add details 
about the relationship.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "expression",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "status",
+          "typeName": "__AtlasGlossaryTermRelationshipStatus",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "steward",
+          "description": "The steward is the person responsible for assessing 
the relationship and deciding if it should be approved or not.",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        },
+        {
+          "name": "source",
+          "typeName": "string",
+          "cardinality": "SINGLE",
+          "isIndexable": true,
+          "isOptional": true
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
----------------------------------------------------------------------
diff --git 
a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
 
b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
index 7bdbeab..883a31b 100644
--- 
a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
+++ 
b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
@@ -30,6 +30,8 @@ import java.util.List;
  */
 public interface AtlasGraphQuery<V, E> {
 
+    enum SortOrder { ASC, DESC }
+
     /**
      * Adds a predicate that the returned vertices must have the specified
      * property and that one of the values of the property must be the
@@ -106,6 +108,15 @@ public interface AtlasGraphQuery<V, E> {
      */
     AtlasGraphQuery<V, E> has(String propertyKey, QueryOperator op, Object 
values);
 
+
+    /**
+     * Adds a sorting predicate
+     * @param propertyKey property key to sort on
+     * @param order ASC or DESC
+     * @return
+     */
+    AtlasGraphQuery<V, E> orderBy(String propertyKey, SortOrder order);
+
     /**
      * Adds a predicate that the vertices returned must satisfy the
      * conditions in at least one of the child queries provided.

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/NativeTinkerpopGraphQuery.java
----------------------------------------------------------------------
diff --git 
a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/NativeTinkerpopGraphQuery.java
 
b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/NativeTinkerpopGraphQuery.java
index 7566559..19ec5e4 100644
--- 
a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/NativeTinkerpopGraphQuery.java
+++ 
b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/NativeTinkerpopGraphQuery.java
@@ -18,6 +18,7 @@
 package org.apache.atlas.repository.graphdb.tinkerpop.query;
 
 import org.apache.atlas.repository.graphdb.AtlasEdge;
+import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery.QueryOperator;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 
@@ -93,4 +94,11 @@ public interface NativeTinkerpopGraphQuery<V, E> {
      * @param value
      */
     void has(String propertyName, QueryOperator op, Object value);
+
+    /**
+     * Add sort predicate for give property
+     * @param propertyName
+     * @param sortOrder
+     */
+    void orderBy(String propertyName, AtlasGraphQuery.SortOrder sortOrder);
 }

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/TinkerpopGraphQuery.java
----------------------------------------------------------------------
diff --git 
a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/TinkerpopGraphQuery.java
 
b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/TinkerpopGraphQuery.java
index 96b9705..d680654 100644
--- 
a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/TinkerpopGraphQuery.java
+++ 
b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/TinkerpopGraphQuery.java
@@ -26,11 +26,13 @@ import 
org.apache.atlas.repository.graphdb.tinkerpop.query.expr.AndCondition;
 import org.apache.atlas.repository.graphdb.tinkerpop.query.expr.HasPredicate;
 import org.apache.atlas.repository.graphdb.tinkerpop.query.expr.InPredicate;
 import org.apache.atlas.repository.graphdb.tinkerpop.query.expr.OrCondition;
+import 
org.apache.atlas.repository.graphdb.tinkerpop.query.expr.OrderByPredicate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -129,7 +131,8 @@ public abstract class TinkerpopGraphQuery<V, E> implements 
AtlasGraphQuery<V, E>
         }
 
         // Compute the overall result by combining the results of all the 
AndConditions (nested within OR) together.
-        Set<AtlasVertex<V, E>> result = new HashSet<>();
+        Set<AtlasVertex<V, E>> result = new LinkedHashSet<>();
+
         for(AndCondition andExpr : queryCondition.getAndTerms()) {
             NativeTinkerpopGraphQuery<V, E> andQuery = 
andExpr.create(getQueryFactory());
             for(AtlasVertex<V, E> vertex : andQuery.vertices()) {
@@ -269,6 +272,12 @@ public abstract class TinkerpopGraphQuery<V, E> implements 
AtlasGraphQuery<V, E>
         return this;
     }
 
+    @Override
+    public AtlasGraphQuery<V, E> orderBy(final String propertyKey, final 
SortOrder order) {
+        queryCondition.andWith(new OrderByPredicate(propertyKey, order));
+        return this;
+    }
+
     private OrCondition getOrCondition() {
         return queryCondition;
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/expr/OrderByPredicate.java
----------------------------------------------------------------------
diff --git 
a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/expr/OrderByPredicate.java
 
b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/expr/OrderByPredicate.java
new file mode 100644
index 0000000..8ba97af
--- /dev/null
+++ 
b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/tinkerpop/query/expr/OrderByPredicate.java
@@ -0,0 +1,41 @@
+/**
+ * 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.repository.graphdb.tinkerpop.query.expr;
+
+import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
+import 
org.apache.atlas.repository.graphdb.tinkerpop.query.NativeTinkerpopGraphQuery;
+
+public class OrderByPredicate implements QueryPredicate {
+    private final String propertyKey;
+    private final AtlasGraphQuery.SortOrder sortOrder;
+
+    public OrderByPredicate(final String propertyKey, final 
AtlasGraphQuery.SortOrder sortOrder) {
+        this.propertyKey = propertyKey;
+        this.sortOrder = sortOrder;
+    }
+
+    @Override
+    public void addTo(final NativeTinkerpopGraphQuery query) {
+        query.orderBy(propertyKey, sortOrder);
+    }
+
+    @Override
+    public String toString() {
+        return "OrderBy [ propertyKey = " + propertyKey + ", order = " + 
sortOrder + " ]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
----------------------------------------------------------------------
diff --git 
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
 
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
index fdef800..2a1ce4e 100644
--- 
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
+++ 
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasJanusGraph.java
@@ -18,22 +18,11 @@
 package org.apache.atlas.repository.graphdb.janus;
 
 import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.atlas.ApplicationProperties;
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.type.AtlasType;
-import org.apache.commons.configuration.Configuration;
-import org.janusgraph.core.Cardinality;
-import org.janusgraph.core.JanusGraphFactory;
-import org.janusgraph.core.PropertyKey;
-import org.janusgraph.core.SchemaViolationException;
-import org.janusgraph.core.JanusGraph;
-import org.janusgraph.core.JanusGraphIndexQuery;
-import org.janusgraph.core.schema.JanusGraphIndex;
-import org.janusgraph.core.schema.JanusGraphManagement;
 import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.AtlasException;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.groovy.GroovyExpression;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
@@ -46,6 +35,8 @@ import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.graphdb.GremlinVersion;
 import org.apache.atlas.repository.graphdb.janus.query.AtlasJanusGraphQuery;
 import org.apache.atlas.repository.graphdb.utils.IteratorToIterableAdapter;
+import org.apache.atlas.type.AtlasType;
+import org.apache.commons.configuration.Configuration;
 import org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider;
 import org.apache.tinkerpop.gremlin.groovy.DefaultImportCustomizerProvider;
 import org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
@@ -58,6 +49,14 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.io.IoCore;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter;
+import org.janusgraph.core.Cardinality;
+import org.janusgraph.core.JanusGraph;
+import org.janusgraph.core.JanusGraphFactory;
+import org.janusgraph.core.JanusGraphIndexQuery;
+import org.janusgraph.core.PropertyKey;
+import org.janusgraph.core.SchemaViolationException;
+import org.janusgraph.core.schema.JanusGraphIndex;
+import org.janusgraph.core.schema.JanusGraphManagement;
 import org.janusgraph.diskstorage.BackendException;
 
 import javax.script.Bindings;
@@ -72,6 +71,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 
 import static 
org.apache.atlas.repository.Constants.INDEX_SEARCH_VERTEX_PREFIX_DEFAULT;
 import static 
org.apache.atlas.repository.Constants.INDEX_SEARCH_VERTEX_PREFIX_PROPERTY;
@@ -406,13 +407,7 @@ public class AtlasJanusGraph implements 
AtlasGraph<AtlasJanusVertex, AtlasJanusE
 
     public Iterable<AtlasVertex<AtlasJanusVertex, AtlasJanusEdge>> 
wrapVertices(Iterable<? extends Vertex> it) {
 
-        return Iterables.transform(it, new Function<Vertex, 
AtlasVertex<AtlasJanusVertex, AtlasJanusEdge>>() {
-
-            @Override
-            public AtlasVertex<AtlasJanusVertex, AtlasJanusEdge> apply(Vertex 
input) {
-                return GraphDbObjectFactory.createVertex(AtlasJanusGraph.this, 
input);
-            }
-        });
+        return StreamSupport.stream(it.spliterator(), false).map(input -> 
GraphDbObjectFactory.createVertex(AtlasJanusGraph.this, 
input)).collect(Collectors.toList());
 
     }
 
@@ -423,13 +418,7 @@ public class AtlasJanusGraph implements 
AtlasGraph<AtlasJanusVertex, AtlasJanusE
 
     public Iterable<AtlasEdge<AtlasJanusVertex, AtlasJanusEdge>> 
wrapEdges(Iterable<? extends Edge> it) {
 
-        return Iterables.transform(it, new Function<Edge, 
AtlasEdge<AtlasJanusVertex, AtlasJanusEdge>>() {
-
-            @Override
-            public AtlasEdge<AtlasJanusVertex, AtlasJanusEdge> apply(Edge 
input) {
-                return GraphDbObjectFactory.createEdge(AtlasJanusGraph.this, 
input);
-            }
-        });
+        return StreamSupport.stream(it.spliterator(), false).map(input -> 
GraphDbObjectFactory.createEdge(AtlasJanusGraph.this, 
input)).collect(Collectors.toList());
 
     }
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/query/NativeJanusGraphQuery.java
----------------------------------------------------------------------
diff --git 
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/query/NativeJanusGraphQuery.java
 
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/query/NativeJanusGraphQuery.java
index d3c976d..d63e1d7 100644
--- 
a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/query/NativeJanusGraphQuery.java
+++ 
b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/query/NativeJanusGraphQuery.java
@@ -17,6 +17,8 @@
  */
 package org.apache.atlas.repository.graphdb.janus.query;
 
+import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
+import org.apache.tinkerpop.gremlin.process.traversal.Order;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.janusgraph.core.JanusGraphEdge;
 import org.janusgraph.core.JanusGraphQuery;
@@ -126,6 +128,12 @@ public class NativeJanusGraphQuery implements 
NativeTinkerpopGraphQuery<AtlasJan
         query.has(propertyName, pred, value);
     }
 
+    @Override
+    public void orderBy(final String propertyName, final 
AtlasGraphQuery.SortOrder sortOrder) {
+        Order order = sortOrder == AtlasGraphQuery.SortOrder.ASC ? Order.incr 
: Order.decr;
+        query.orderBy(propertyName, order);
+    }
+
     private Text getGremlinPredicate(MatchingOperator op) {
         switch (op) {
             case CONTAINS:

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
----------------------------------------------------------------------
diff --git 
a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
 
b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
index 2903ae2..68a7048 100644
--- 
a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
+++ 
b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
@@ -17,7 +17,7 @@
  */
 package org.apache.atlas.repository.graphdb.titan0.query;
 
-import com.google.common.collect.Lists;
+import com.thinkaurelius.titan.core.Order;
 import com.thinkaurelius.titan.core.TitanGraphQuery;
 import com.thinkaurelius.titan.core.attribute.Contain;
 import com.thinkaurelius.titan.core.attribute.Text;
@@ -26,6 +26,7 @@ import com.tinkerpop.blueprints.Compare;
 import com.tinkerpop.blueprints.Edge;
 import com.tinkerpop.blueprints.Vertex;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
+import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery.MatchingOperator;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery.QueryOperator;
@@ -36,7 +37,10 @@ import 
org.apache.atlas.repository.graphdb.titan0.Titan0Graph;
 import org.apache.atlas.repository.graphdb.titan0.Titan0GraphDatabase;
 import org.apache.atlas.repository.graphdb.titan0.Titan0Vertex;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * Titan 0.5.4 implementation of NativeTitanGraphQuery.
@@ -129,6 +133,11 @@ public class NativeTitan0GraphQuery implements 
NativeTinkerpopGraphQuery<Titan0V
         query.has(propertyName, pred, value);
     }
 
+    @Override
+    public void orderBy(final String propertyName, final 
AtlasGraphQuery.SortOrder sortOrder) {
+        query.orderBy(propertyName, sortOrder == AtlasGraphQuery.SortOrder.ASC 
? Order.ASC : Order.DESC);
+    }
+
     private Text getGremlinPredicate(MatchingOperator op) {
         switch (op) {
             case CONTAINS:

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java 
b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 997ac68..3805c22 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -128,6 +128,9 @@ public enum AtlasErrorCode {
     NO_CLASSIFICATIONS_FOUND_FOR_ENTITY(400, "ATLAS-400-00-06E", "No 
classifications associated with entity: {0}"),
     INVALID_CLASSIFICATION_PARAMS(400, "ATLAS-400-00-06F", "Invalid 
classification parameters passed for {0} operation for entity: {1}"),
     PROPAGATED_CLASSIFICATION_NOT_ASSOCIATED_WITH_ENTITY(400, 
"ATLAS-400-00-070", "Propagated classification {0} is not associated with 
entity"),
+    // Glossary Related errors
+    INVALID_PARTIAL_UPDATE_ATTR_VAL(400, "ATLAS-400-00-071", "Invalid attrVal 
for partial update of {0}, expected = {1} found {2}"),
+    MISSING_MANDATORY_ANCHOR(400, "ATLAS-400-00-072", "Mandatory anchor 
attribute is missing"),
 
     UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to 
perform {1}"),
 
@@ -148,6 +151,7 @@ public enum AtlasErrorCode {
     RELATIONSHIP_ALREADY_DELETED(404, "ATLAS-404-00-00F", "Attempting to 
delete a relationship which is already deleted : {0}"),
     INVALID_ENTITY_GUID_FOR_CLASSIFICATION_UPDATE(404, "ATLAS-404-00-010", 
"Updating entityGuid of classification is not allowed."),
     INSTANCE_GUID_NOT_DATASET(404, "ATLAS-404-00-011", "Given instance guid 
{0} is not a dataset"),
+    INSTANCE_GUID_DELETED(404, "ATLAS-404-00-012", "Given instance guid {0} 
has been deleted"),
 
     // All data conflict errors go here
     TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already 
exists"),
@@ -177,7 +181,7 @@ public enum AtlasErrorCode {
     HIVE_HOOK_METASTORE_BRIDGE(500, "ATLAS-500-00-011", 
"HiveHookMetaStoreBridge: {0}"),
     DATA_ACCESS_SAVE_FAILED(500, "ATLAS-500-00-012", "Save failed: {0}"),
     DATA_ACCESS_LOAD_FAILED(500, "ATLAS-500-00-013", "Load failed: {0}"),
-    ENTITY_NOTIFICATION_FAILED(500, "ATLAS-500-00-014", "Notification failed 
for operation: {} : {}");
+    ENTITY_NOTIFICATION_FAILED(500, "ATLAS-500-00-014", "Notification failed 
for operation: {0} : {1}");
 
     private String errorCode;
     private String errorMessage;

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/intg/src/main/java/org/apache/atlas/model/AtlasBaseModelObject.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/AtlasBaseModelObject.java 
b/intg/src/main/java/org/apache/atlas/model/AtlasBaseModelObject.java
index 688f6f4..5f6654a 100644
--- a/intg/src/main/java/org/apache/atlas/model/AtlasBaseModelObject.java
+++ b/intg/src/main/java/org/apache/atlas/model/AtlasBaseModelObject.java
@@ -17,32 +17,18 @@
  */
 package org.apache.atlas.model;
 
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.apache.atlas.model.annotation.AtlasJSON;
 
-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.Objects;
 
-import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
-import static 
com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
-
-@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
-@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
-@JsonIgnoreProperties(ignoreUnknown=true)
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.PROPERTY)
+@AtlasJSON
 public abstract class AtlasBaseModelObject implements Serializable {
     private static final long serialVersionUID = 1L;
 
     private String guid;
 
-
-    protected AtlasBaseModelObject() {
-    }
-
+    protected AtlasBaseModelObject() {}
 
     public String getGuid() {
         return this.guid;
@@ -52,7 +38,6 @@ public abstract class AtlasBaseModelObject implements 
Serializable {
         this.guid = guid;
     }
 
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -63,5 +48,19 @@ public abstract class AtlasBaseModelObject implements 
Serializable {
         return sb.toString();
     }
 
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (!(o instanceof AtlasBaseModelObject)) return false;
+        final AtlasBaseModelObject that = (AtlasBaseModelObject) o;
+        return Objects.equals(guid, that.guid);
+    }
+
+    @Override
+    public int hashCode() {
+
+        return Objects.hash(guid);
+    }
+
     protected abstract StringBuilder toString(StringBuilder sb);
 }

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/intg/src/main/java/org/apache/atlas/model/annotation/AtlasJSON.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/annotation/AtlasJSON.java 
b/intg/src/main/java/org/apache/atlas/model/annotation/AtlasJSON.java
new file mode 100644
index 0000000..03d5603
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/annotation/AtlasJSON.java
@@ -0,0 +1,36 @@
+/**
+ * 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.model.annotation;
+
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
+import static 
com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, 
fieldVisibility=NONE)
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+@JsonIgnoreProperties(ignoreUnknown=true)
+public @interface AtlasJSON {}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
new file mode 100644
index 0000000..3c5f418
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
@@ -0,0 +1,222 @@
+/**
+ * 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.model.glossary;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.atlas.model.annotation.AtlasJSON;
+import org.apache.atlas.model.glossary.relations.AtlasRelatedCategoryHeader;
+import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+@AtlasJSON
+public class AtlasGlossary extends AtlasGlossaryBaseObject {
+    private String                      language;
+    private String                      usage;
+
+    private Set<AtlasRelatedTermHeader>     terms;
+    private Set<AtlasRelatedCategoryHeader> categories;
+
+    public AtlasGlossary() {
+    }
+
+    public AtlasGlossary(final AtlasGlossary other) {
+        super.setQualifiedName(other.getQualifiedName());
+        super.setGuid(other.getGuid());
+        super.setDisplayName(other.displayName);
+        super.setShortDescription(other.shortDescription);
+        super.setLongDescription(other.longDescription);
+        this.language = other.language;
+        this.usage = other.usage;
+        this.terms = other.terms;
+        this.categories = other.categories;
+    }
+
+    public String getLanguage() {
+        return language;
+    }
+
+    public void setLanguage(final String language) {
+        this.language = language;
+    }
+
+    public String getUsage() {
+        return usage;
+    }
+
+    public void setUsage(final String usage) {
+        this.usage = usage;
+    }
+
+    public Set<AtlasRelatedCategoryHeader> getCategories() {
+        return categories;
+    }
+
+    public void setCategories(final Set<AtlasRelatedCategoryHeader> 
categories) {
+        this.categories = categories;
+    }
+
+    public Set<AtlasRelatedTermHeader> getTerms() {
+        return terms;
+    }
+
+    public void setTerms(final Set<AtlasRelatedTermHeader> terms) {
+        this.terms = terms;
+    }
+
+    @JsonIgnore
+    @Override
+    public void setAttribute(String attrName, String attrVal) {
+        Objects.requireNonNull(attrName, "AtlasGlossary attribute name");
+        switch (attrName) {
+            case "displayName":
+                setDisplayName(attrVal);
+                break;
+            case "shortDescription":
+                setShortDescription(attrVal);
+                break;
+            case "longDescription":
+                setLongDescription(attrVal);
+                break;
+            case "language":
+                setLanguage(attrVal);
+                break;
+            case "usage":
+                setUsage(attrVal);
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid attribute '" + 
attrName + "' for object AtlasGlossary");
+        }
+    }
+
+    @JsonIgnore
+    public void addTerm(AtlasRelatedTermHeader relatedTermId) {
+        Set<AtlasRelatedTermHeader> terms = this.terms;
+        if (terms == null) {
+            terms = new HashSet<>();
+        }
+        terms.add(relatedTermId);
+        setTerms(terms);
+    }
+
+    @JsonIgnore
+    public void addCategory(AtlasRelatedCategoryHeader relatedCategoryId) {
+        Set<AtlasRelatedCategoryHeader> categories = this.categories;
+        if (categories == null) {
+            categories = new HashSet<>();
+        }
+        categories.add(relatedCategoryId);
+        setCategories(categories);
+    }
+
+    @JsonIgnore
+    public void removeTerm(AtlasRelatedTermHeader relatedTermId) {
+        if (CollectionUtils.isNotEmpty(terms)) {
+            terms.remove(relatedTermId);
+        }
+    }
+
+    @JsonIgnore
+    public void removeCategory(AtlasRelatedCategoryHeader relatedCategoryId) {
+        if (CollectionUtils.isNotEmpty(categories)) {
+            categories.remove(relatedCategoryId);
+        }
+    }
+
+    @Override
+    protected StringBuilder toString(final StringBuilder sb) {
+        return sb == null ? new StringBuilder(toString()) : 
sb.append(toString());
+    }
+
+
+    @AtlasJSON
+    public static class AtlasGlossaryExtInfo extends AtlasGlossary {
+        private Map<String, AtlasGlossaryTerm>     termInfo;
+        private Map<String, AtlasGlossaryCategory> categoryInfo;
+
+        public AtlasGlossaryExtInfo() {
+        }
+
+        public AtlasGlossaryExtInfo(AtlasGlossary glossary) {
+            super(glossary);
+        }
+
+        public Map<String, AtlasGlossaryTerm> getTermInfo() {
+            return termInfo;
+        }
+
+        public void addTermInfo(final AtlasGlossaryTerm term) {
+            if (termInfo == null) {
+                termInfo = new HashMap<>();
+            }
+            termInfo.put(term.getGuid(), term);
+        }
+
+        public void setTermInfo(final Map<String, AtlasGlossaryTerm> termInfo) 
{
+            this.termInfo = termInfo;
+        }
+
+        public Map<String, AtlasGlossaryCategory> getCategoryInfo() {
+            return categoryInfo;
+        }
+
+        public void addCategoryInfo(final AtlasGlossaryCategory category) {
+            if (categoryInfo == null) {
+                categoryInfo = new HashMap<>();
+            }
+            categoryInfo.put(category.getGuid(), category);
+        }
+
+        public void setCategoryInfo(final Map<String, AtlasGlossaryCategory> 
categoryInfo) {
+            this.categoryInfo = categoryInfo;
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (!(o instanceof AtlasGlossaryExtInfo)) return false;
+            if (!super.equals(o)) return false;
+            final AtlasGlossaryExtInfo that = (AtlasGlossaryExtInfo) o;
+            return Objects.equals(termInfo, that.termInfo) &&
+                           Objects.equals(categoryInfo, that.categoryInfo);
+        }
+
+        @Override
+        public int hashCode() {
+
+            return Objects.hash(super.hashCode(), termInfo, categoryInfo);
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new 
StringBuilder("AtlasGlossaryExtInfo{");
+            sb.append(super.toString());
+            sb.append(", termInfo=").append(termInfo);
+            sb.append(", categoryInfo=").append(categoryInfo);
+            sb.append('}');
+            return sb.toString();
+        }
+
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
new file mode 100644
index 0000000..a3e0a37
--- /dev/null
+++ 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
@@ -0,0 +1,129 @@
+/**
+ * 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.model.glossary;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.atlas.model.AtlasBaseModelObject;
+import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public abstract class AtlasGlossaryBaseObject extends AtlasBaseModelObject {
+    // Core attributes
+    protected String                    displayName;
+    protected String                    shortDescription;
+    protected String                    longDescription;
+
+    // Classifications
+    protected List<AtlasClassification> classifications;
+    private   String                    qualifiedName;
+
+    public String getQualifiedName() {
+        return qualifiedName;
+    }
+
+    public void setQualifiedName(final String qualifiedName) {
+        this.qualifiedName = qualifiedName;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(final String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getShortDescription() {
+        return shortDescription;
+    }
+
+    public void setShortDescription(final String shortDescription) {
+        this.shortDescription = shortDescription;
+    }
+
+    public String getLongDescription() {
+        return longDescription;
+    }
+
+    public void setLongDescription(final String longDescription) {
+        this.longDescription = longDescription;
+    }
+
+    abstract public void setAttribute(String attrName, String attrVal);
+
+    public List<AtlasClassification> getClassifications() {
+        return classifications;
+    }
+
+    public void setClassifications(final List<AtlasClassification> 
classifications) {
+        this.classifications = classifications;
+    }
+
+    @JsonIgnore
+    public void addClassification(AtlasClassification classification) {
+        List<AtlasClassification> classifications = this.classifications;
+        if (classifications == null) {
+            classifications = new ArrayList<>();
+        }
+        classifications.add(classification);
+        setClassifications(classifications);
+    }
+
+    @JsonIgnore
+    public void removeClassification(AtlasClassification classification) {
+        if (CollectionUtils.isNotEmpty(classifications)) {
+            classifications.remove(classification);
+        }
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (!(o instanceof AtlasGlossaryBaseObject)) return false;
+        if (!super.equals(o)) return false;
+        final AtlasGlossaryBaseObject that = (AtlasGlossaryBaseObject) o;
+        return Objects.equals(displayName, that.displayName) &&
+                       Objects.equals(shortDescription, that.shortDescription) 
&&
+                       Objects.equals(longDescription, that.longDescription) &&
+                       Objects.equals(classifications, that.classifications) &&
+                       Objects.equals(qualifiedName, that.qualifiedName);
+    }
+
+    @Override
+    public int hashCode() {
+
+        return Objects.hash(super.hashCode(), displayName, shortDescription, 
longDescription, classifications, qualifiedName);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("AtlasGlossaryBaseObject{");
+        sb.append("displayName='").append(displayName).append('\'');
+        sb.append(", 
shortDescription='").append(shortDescription).append('\'');
+        sb.append(", longDescription='").append(longDescription).append('\'');
+        sb.append(", classifications=").append(classifications);
+        sb.append(", qualifiedName='").append(qualifiedName).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/75415862/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
new file mode 100644
index 0000000..55fb580
--- /dev/null
+++ 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
@@ -0,0 +1,174 @@
+/**
+ * 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.model.glossary;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.atlas.model.annotation.AtlasJSON;
+import org.apache.atlas.model.glossary.relations.AtlasGlossaryHeader;
+import org.apache.atlas.model.glossary.relations.AtlasRelatedCategoryHeader;
+import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+@AtlasJSON
+public class AtlasGlossaryCategory extends AtlasGlossaryBaseObject {
+    // Inherited attributes from relations
+    private AtlasGlossaryHeader anchor;
+
+    // Category hierarchy links
+    private AtlasRelatedCategoryHeader      parentCategory;
+    private Set<AtlasRelatedCategoryHeader> childrenCategories;
+
+    // Terms associated with this category
+    private Set<AtlasRelatedTermHeader> terms;
+
+    public AtlasGlossaryCategory() {
+    }
+
+    public AtlasGlossaryHeader getAnchor() {
+        return anchor;
+    }
+
+    public void setAnchor(final AtlasGlossaryHeader anchor) {
+        this.anchor = anchor;
+    }
+
+    public AtlasRelatedCategoryHeader getParentCategory() {
+        return parentCategory;
+    }
+
+    public void setParentCategory(final AtlasRelatedCategoryHeader 
parentCategory) {
+        this.parentCategory = parentCategory;
+    }
+
+    public Set<AtlasRelatedCategoryHeader> getChildrenCategories() {
+        return childrenCategories;
+    }
+
+    public void setChildrenCategories(final Set<AtlasRelatedCategoryHeader> 
childrenCategories) {
+        this.childrenCategories = childrenCategories;
+    }
+
+    public Set<AtlasRelatedTermHeader> getTerms() {
+        return terms;
+    }
+
+    public void setTerms(final Set<AtlasRelatedTermHeader> terms) {
+        this.terms = terms;
+    }
+
+    @JsonIgnore
+    public void addChild(AtlasRelatedCategoryHeader child) {
+        Set<AtlasRelatedCategoryHeader> children = this.childrenCategories ;
+        if (children == null) {
+            children = new HashSet<>();
+        }
+        children.add(child);
+        setChildrenCategories(children);
+    }
+
+    @JsonIgnore
+    public void removeChild(AtlasRelatedCategoryHeader child) {
+        if (CollectionUtils.isNotEmpty(childrenCategories)) {
+            childrenCategories.remove(child);
+        }
+    }
+
+    @JsonIgnore
+    public void addTerm(AtlasRelatedTermHeader term) {
+        Set<AtlasRelatedTermHeader> terms = this.terms;
+        if (terms == null) {
+            terms = new HashSet<>();
+        }
+        terms.add(term);
+        setTerms(terms);
+    }
+
+    @JsonIgnore
+    public void removeTerm(AtlasRelatedTermHeader term) {
+        if (CollectionUtils.isNotEmpty(terms)) {
+            terms.remove(term);
+        }
+    }
+
+    @JsonIgnore
+    @Override
+    public void setAttribute(String attrName, String attrVal) {
+        Objects.requireNonNull(attrName, "AtlasGlossary attribute name");
+        switch(attrName) {
+            case "displayName":
+                setDisplayName(attrVal);
+                break;
+            case "shortDescription":
+                setShortDescription(attrVal);
+                break;
+            case "longDescription":
+                setLongDescription(attrVal);
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid attribute '" + 
attrName + "' for object AtlasGlossaryCategory");
+        }
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer("AtlasGlossaryCategory{");
+        sb.append("displayName='").append(getDisplayName()).append('\'');
+        sb.append(", 
shortDescription='").append(getShortDescription()).append('\'');
+        sb.append(", 
longDescription='").append(getLongDescription()).append('\'');
+        sb.append(", anchor=").append(anchor);
+        sb.append(", parentCategory=").append(parentCategory);
+        sb.append(", childrenCategories=").append(childrenCategories);
+        sb.append(", terms=").append(terms);
+        sb.append(", classifications=").append(getClassifications());
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    protected StringBuilder toString(final StringBuilder sb) {
+        return sb == null ? new StringBuilder(toString()) : 
sb.append(toString());
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (!(o instanceof AtlasGlossaryCategory)) return false;
+        if (!super.equals(o)) return false;
+        final AtlasGlossaryCategory category = (AtlasGlossaryCategory) o;
+        return Objects.equals(getDisplayName(), category.getDisplayName()) &&
+                       Objects.equals(getShortDescription(), 
category.getShortDescription()) &&
+                       Objects.equals(getLongDescription(), 
category.getLongDescription()) &&
+                       Objects.equals(anchor, category.anchor) &&
+                       Objects.equals(parentCategory, category.parentCategory) 
&&
+                       Objects.equals(childrenCategories, 
category.childrenCategories) &&
+                       Objects.equals(terms, category.terms) &&
+                       Objects.equals(getClassifications(), 
category.getClassifications());
+    }
+
+    @Override
+    public int hashCode() {
+
+        return Objects.hash(super.hashCode(), getDisplayName(), 
getShortDescription(), getLongDescription(),
+                            anchor, parentCategory, childrenCategories,
+                            terms, getClassifications());
+    }
+}

Reply via email to