You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2017/09/17 07:48:13 UTC
[2/2] atlas git commit: ATLAS-2100: UserProfile & SavedSearch API
implementation
ATLAS-2100: UserProfile & SavedSearch API implementation
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/fd144e01
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/fd144e01
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/fd144e01
Branch: refs/heads/branch-0.8
Commit: fd144e018f2af046a4b44760f34c7d95b5948ecf
Parents: 4d5e69a
Author: ashutoshm <am...@hortonworks.com>
Authored: Sat Sep 16 13:46:00 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Sun Sep 17 00:17:38 2017 -0700
----------------------------------------------------------------------
addons/models/0010-base_model.json | 267 ++++++++++++-------
.../org/apache/atlas/repository/Constants.java | 1 +
.../java/org/apache/atlas/AtlasErrorCode.java | 9 +-
.../atlas/model/AtlasBaseModelObject.java | 67 +++++
.../org/apache/atlas/model/SearchFilter.java | 1 +
.../atlas/model/discovery/SearchParameters.java | 5 +-
.../atlas/model/profile/AtlasUserProfile.java | 96 +++++++
.../model/profile/AtlasUserSavedSearch.java | 99 +++++++
.../atlas/discovery/AtlasDiscoveryService.java | 40 +++
.../atlas/discovery/EntityDiscoveryService.java | 91 +++++--
.../atlas/repository/graph/GraphHelper.java | 4 +
.../ogm/AbstractDataTransferObject.java | 66 +++++
.../repository/ogm/AtlasSavedSearchDTO.java | 97 +++++++
.../repository/ogm/AtlasUserProfileDTO.java | 115 ++++++++
.../atlas/repository/ogm/DTORegistry.java | 49 ++++
.../apache/atlas/repository/ogm/DataAccess.java | 90 +++++++
.../repository/ogm/DataTransferObject.java | 43 +++
.../store/graph/v1/AtlasAbstractDefStoreV1.java | 11 +-
.../graph/v1/AtlasEntityChangeNotifier.java | 4 +
.../userprofile/UserProfileService.java | 150 +++++++++++
.../atlas/repository/util/FilterUtil.java | 36 ++-
.../test/java/org/apache/atlas/TestModules.java | 21 +-
.../userprofile/UserProfileServiceTest.java | 267 +++++++++++++++++++
.../NotificationEntityChangeListener.java | 5 +
.../apache/atlas/web/rest/DiscoveryREST.java | 157 ++++++++---
.../org/apache/atlas/web/rest/TypesREST.java | 2 +
.../org/apache/atlas/web/util/Servlets.java | 2 +-
27 files changed, 1615 insertions(+), 180 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/addons/models/0010-base_model.json
----------------------------------------------------------------------
diff --git a/addons/models/0010-base_model.json b/addons/models/0010-base_model.json
index 9ab4c44..db95d7e 100644
--- a/addons/models/0010-base_model.json
+++ b/addons/models/0010-base_model.json
@@ -1,113 +1,182 @@
{
- "enumDefs": [],
- "structDefs": [],
- "classificationDefs": [
+ "enumDefs": [],
+ "structDefs": [],
+ "classificationDefs": [],
+ "entityDefs": [
+ {
+ "name": "Referenceable",
+ "superTypes": [],
+ "typeVersion": "1.0",
+ "attributeDefs": [
{
- "name": "TaxonomyTerm",
- "superTypes": [],
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "atlas.taxonomy",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- }
- ]
+ "name": "qualifiedName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": true
}
- ],
- "entityDefs": [
+ ]
+ },
+ {
+ "name": "__internal",
+ "superTypes": [],
+ "typeVersion": "1.0",
+ "attributeDefs": []
+ },
+ {
+ "name": "Asset",
+ "superTypes": [],
+ "typeVersion": "1.0",
+ "attributeDefs": [
{
- "name": "Referenceable",
- "superTypes": [],
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "qualifiedName",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": true
- }
- ]
+ "name": "name",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "Asset",
- "superTypes": [],
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "name",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": false,
- "isUnique": false
- },
- {
- "name": "description",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "owner",
- "typeName": "string",
- "cardinality": "SINGLE",
- "isIndexable": true,
- "isOptional": true,
- "isUnique": false
- }
- ]
+ "name": "description",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
},
{
- "name": "DataSet",
- "superTypes": [
- "Referenceable",
- "Asset"
- ],
- "typeVersion": "1.0",
- "attributeDefs": []
+ "name": "owner",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": true,
+ "isUnique": false
+ }
+ ]
+ },
+ {
+ "name": "DataSet",
+ "superTypes": [
+ "Referenceable",
+ "Asset"
+ ],
+ "typeVersion": "1.0",
+ "attributeDefs": []
+ },
+ {
+ "name": "Infrastructure",
+ "superTypes": [
+ "Referenceable",
+ "Asset"
+ ],
+ "typeVersion": "1.0",
+ "attributeDefs": []
+ },
+ {
+ "name": "Process",
+ "superTypes": [
+ "Referenceable",
+ "Asset"
+ ],
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "inputs",
+ "typeName": "array<DataSet>",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ },
+ {
+ "name": "outputs",
+ "typeName": "array<DataSet>",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ }
+ ]
+ },
+ {
+ "name": "__AtlasUserProfile",
+ "superTypes": [
+ "__internal"
+ ],
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "name",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": true
+ },
+ {
+ "name": "fullName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ },
+ {
+ "name": "savedSearches",
+ "typeName": "array<__AtlasUserSavedSearch>",
+ "cardinality": "LIST",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false,
+ "constraints": [
+ {
+ "type": "ownedRef"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "__AtlasUserSavedSearch",
+ "superTypes": [
+ "__internal"
+ ],
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "name",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": false,
+ "isUnique": false
+ },
+ {
+ "name": "ownerName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": false,
+ "isUnique": false
},
{
- "name": "Infrastructure",
- "superTypes": [
- "Referenceable",
- "Asset"
- ],
- "typeVersion": "1.0",
- "attributeDefs": []
+ "name": "uniqueName",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": true
},
{
- "name": "Process",
- "superTypes": [
- "Referenceable",
- "Asset"
- ],
- "typeVersion": "1.0",
- "attributeDefs": [
- {
- "name": "inputs",
- "typeName": "array<DataSet>",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- },
- {
- "name": "outputs",
- "typeName": "array<DataSet>",
- "cardinality": "SINGLE",
- "isIndexable": false,
- "isOptional": true,
- "isUnique": false
- }
- ]
+ "name": "searchParameters",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": false,
+ "isUnique": false
}
- ]
+ ]
+ }
+ ]
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/common/src/main/java/org/apache/atlas/repository/Constants.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java b/common/src/main/java/org/apache/atlas/repository/Constants.java
index 62d74f8..1817929 100644
--- a/common/src/main/java/org/apache/atlas/repository/Constants.java
+++ b/common/src/main/java/org/apache/atlas/repository/Constants.java
@@ -35,6 +35,7 @@ public final class Constants {
* Entity type name property key.
*/
public static final String ENTITY_TYPE_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "typeName";
+ public static final String TYPE_NAME_INTERNAL = INTERNAL_PROPERTY_KEY_PREFIX + "internal";
/**
* Entity type's super types property key.
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/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 b20f586..2044785 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -72,8 +72,9 @@ public enum AtlasErrorCode {
PARAMETER_PARSING_FAILED(400, "ATLAS-400-00-02A", "Parameter parsing failed at: {0}"),
MISSING_MANDATORY_ATTRIBUTE(400, "ATLAS-400-00-02B", "Mandatory field {0}.{1} has empty/null value"),
INVALID_RELATIONSHIP_ATTRIBUTE(400, "ATLAS-400-00-02C", "Expected attribute {0} to be a relationship but found type {}"),
- INVALID_RELATIONSHIP_TYPE(400, "ATLAS-400-00-02D", "Invalid entity type '{0}', guid '{1}' in relationship search"),
+ INVALID_RELATIONSHIP_TYPE(400, "ATLAS-400-00-02D", "Invalid entity type {0}, guid {1} in relationship search"),
INVALID_IMPORT_ATTRIBUTE_TYPE_CHANGED(400, "ATLAS-400-00-050", "Attribute {0}.{1} is of type {2}. Import has this attribute type as {3}"),
+ SAVED_SEARCH_CHANGE_USER(400, "ATLAS-400-00-051", "saved-search {0} can not be moved from user {1} to {2}"),
// All Not found enums go here
UNKNOWN_CLASSIFICATION(400, "ATLAS-400-00-046", "{0}: Unknown/invalid classification"),
@@ -93,6 +94,7 @@ public enum AtlasErrorCode {
TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"),
TYPE_HAS_REFERENCES(409, "ATLAS-409-00-002", "Given type {0} has references"),
INSTANCE_ALREADY_EXISTS(409, "ATLAS-409-00-003", "failed to update entity: {0}"),
+ SAVED_SEARCH_ALREADY_EXISTS(409, "ATLAS-409-00-004", "search named {0} already exists for user {1}"),
// All internal errors go here
INTERNAL_ERROR(500, "ATLAS-500-00-001", "Internal server error {0}"),
@@ -112,7 +114,10 @@ public enum AtlasErrorCode {
STORM_TOPOLOGY_UTIL(500, "ATLAS-500-00-00E", "StormToplogyUtil: {0}"),
SQOOP_HOOK(500, "ATLAS-500-00-00F", "SqoopHook: {0}"),
HIVE_HOOK(500, "ATLAS-500-00-010", "HiveHook: {0}"),
- HIVE_HOOK_METASTORE_BRIDGE(500, "ATLAS-500-00-011", "HiveHookMetaStoreBridge: {0}");
+ HIVE_HOOK_METASTORE_BRIDGE(500, "ATLAS-500-00-011", "HiveHookMetaStoreBridge: {0}"),
+
+ DATA_ACCESS_SAVE_FAILED(500, "ATLAS-500-00-00B", "Save failed: {0}"),
+ DATA_ACCESS_LOAD_FAILED(500, "ATLAS-500-00-00C", "Load failed: {0}");
private String errorCode;
private String errorMessage;
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/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
new file mode 100644
index 0000000..ea6660d
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/AtlasBaseModelObject.java
@@ -0,0 +1,67 @@
+/**
+ * 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;
+
+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;
+
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public abstract class AtlasBaseModelObject implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String guid;
+
+
+ protected AtlasBaseModelObject() {
+ }
+
+
+ public String getGuid() {
+ return this.guid;
+ }
+
+ public void setGuid(String guid) {
+ this.guid = guid;
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ sb.append("guid=").append(guid);
+ toString(sb);
+ sb.append("}");
+ return sb.toString();
+ }
+
+ protected abstract StringBuilder toString(StringBuilder sb);
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/intg/src/main/java/org/apache/atlas/model/SearchFilter.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/SearchFilter.java b/intg/src/main/java/org/apache/atlas/model/SearchFilter.java
index 7dccf5e..172fd26 100644
--- a/intg/src/main/java/org/apache/atlas/model/SearchFilter.java
+++ b/intg/src/main/java/org/apache/atlas/model/SearchFilter.java
@@ -44,6 +44,7 @@ public class SearchFilter {
public static final String PARAM_NAME = "name";
public static final String PARAM_SUPERTYPE = "supertype";
public static final String PARAM_NOT_SUPERTYPE = "notsupertype";
+ public static final String PARAM_NOT_NAME = "notname";
/**
* to specify whether the result should be sorted? If yes, whether asc or desc.
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java
index c79b5b9..a7a71b7 100644
--- a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java
+++ b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java
@@ -24,6 +24,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonValue;
import org.codehaus.jackson.map.annotate.JsonSerialize;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -36,7 +37,9 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL
@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
-public class SearchParameters {
+public class SearchParameters implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private String query;
private String typeName;
private String classification;
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserProfile.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserProfile.java b/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserProfile.java
new file mode 100644
index 0000000..3fd61f3
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserProfile.java
@@ -0,0 +1,96 @@
+/**
+ * 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.profile;
+
+import org.apache.atlas.model.AtlasBaseModelObject;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.dumpObjects;
+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 AtlasUserProfile extends AtlasBaseModelObject implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String name;
+ private String fullName;
+ private List<AtlasUserSavedSearch> savedSearches;
+
+
+ public AtlasUserProfile() {
+ this(null, null);
+ }
+
+ public AtlasUserProfile(String name) {
+ this(name, null);
+ }
+
+ public AtlasUserProfile(String name, String fullName) {
+ this.name = name;
+ this.fullName = fullName;
+ this.savedSearches = new ArrayList<>();
+ }
+
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setFullName(String fullName) {
+ this.fullName = fullName;
+ }
+
+ public String getFullName() {
+ return this.fullName;
+ }
+
+ public void setSavedSearches(List<AtlasUserSavedSearch> searches) {
+ this.savedSearches = searches;
+ }
+
+ public List<AtlasUserSavedSearch> getSavedSearches() {
+ return savedSearches;
+ }
+
+
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append(", name=").append(name);
+ sb.append(", fullName=").append(fullName);
+ sb.append(", savedSearches=[");
+ if (savedSearches != null) {
+ dumpObjects(savedSearches, sb);
+ }
+ sb.append("]");
+
+ return sb;
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java b/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java
new file mode 100644
index 0000000..b0698fc
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java
@@ -0,0 +1,99 @@
+/**
+ * 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.profile;
+
+import org.apache.atlas.model.AtlasBaseModelObject;
+import org.apache.atlas.model.discovery.SearchParameters;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.io.Serializable;
+
+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 AtlasUserSavedSearch extends AtlasBaseModelObject implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String ownerName;
+ private String name;
+ private SearchParameters searchParameters;
+
+
+ public AtlasUserSavedSearch() {
+ this(null, null, null);
+ }
+
+ public AtlasUserSavedSearch(String name, SearchParameters searchParameters) {
+ this(null, name, searchParameters);
+ }
+
+ public AtlasUserSavedSearch(String ownerName, String name) {
+ this(ownerName, name, null);
+ }
+
+ public AtlasUserSavedSearch(String ownerName, String name, SearchParameters searchParameters) {
+ setOwnerName(ownerName);
+ setName(name);
+ setSearchParameters(searchParameters);
+ }
+
+
+ public String getOwnerName() {
+ return this.ownerName;
+ }
+
+ public void setOwnerName(String ownerName) {
+ this.ownerName = ownerName;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public SearchParameters getSearchParameters() {
+ return searchParameters;
+ }
+
+ public void setSearchParameters(SearchParameters searchParameters) {
+ this.searchParameters = searchParameters;
+ }
+
+
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append(", ownerName=").append(ownerName);
+ sb.append(", name=").append(name);
+ sb.append(", searchParameters=");
+ if (searchParameters == null) {
+ sb.append("null");
+ } else {
+ searchParameters.toString(sb);
+ }
+
+ return sb;
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
index 8196a67..baaee85 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
@@ -23,6 +23,9 @@ import org.apache.atlas.SortOrder;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+
+import java.util.List;
public interface AtlasDiscoveryService {
/**
@@ -79,4 +82,41 @@ public interface AtlasDiscoveryService {
* @return AtlasSearchResult
*/
AtlasSearchResult searchRelatedEntities(String guid, String relation, String sortByAttribute, SortOrder sortOrder, boolean excludeDeletedEntities, int limit, int offset) throws AtlasBaseException;
+
+ /**
+ *
+ *
+ * @param savedSearch Search to be saved
+ * @throws AtlasBaseException
+ */
+ void addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
+
+ /**
+ *
+ * @param savedSearch Search to be saved
+ * @throws AtlasBaseException
+ */
+ void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
+
+ /**
+ *
+ * @param userName Name of the user for whom the saved searches are to be retrieved
+ * @return List of saved searches for the user
+ * @throws AtlasBaseException
+ */
+ List<AtlasUserSavedSearch> getSavedSearches(String userName) throws AtlasBaseException;
+
+ /**
+ *
+ * @param userName Name of the user who the search belongs
+ * @param searchName Name of the search to be retrieved
+ * @return Search object identified by the name
+ * @throws AtlasBaseException
+ */
+ AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException;
+
+ /**
+ * @param guid Guid for the saved search
+ */
+ void deleteSavedSearch(String guid) throws AtlasBaseException;
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index 1e68835..ad21ee4 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -30,9 +30,9 @@ import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasQueryType;
import org.apache.atlas.model.discovery.AtlasSearchResult.AttributeSearchResult;
import org.apache.atlas.model.discovery.SearchParameters;
-import org.apache.atlas.model.instance.AtlasEntity.Status;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch;
import org.apache.atlas.query.Expressions.AliasExpression;
import org.apache.atlas.query.Expressions.Expression;
import org.apache.atlas.query.Expressions.SelectExpression;
@@ -51,9 +51,15 @@ import org.apache.atlas.repository.graphdb.AtlasIndexQuery;
import org.apache.atlas.repository.graphdb.AtlasIndexQuery.Result;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v1.EntityGraphRetriever;
-import org.apache.atlas.type.*;
+import org.apache.atlas.repository.userprofile.UserProfileService;
+import org.apache.atlas.type.AtlasArrayType;
import org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType;
+import org.apache.atlas.type.AtlasClassificationType;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasMapType;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.util.AtlasGremlinQueryProvider;
import org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery;
import org.apache.atlas.util.SearchTracker;
@@ -71,24 +77,25 @@ import javax.inject.Inject;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
-import java.util.*;
-
-import static org.apache.atlas.AtlasErrorCode.CLASSIFICATION_NOT_FOUND;
-import static org.apache.atlas.AtlasErrorCode.DISCOVERY_QUERY_FAILED;
-import static org.apache.atlas.AtlasErrorCode.UNKNOWN_TYPENAME;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.atlas.AtlasErrorCode.*;
import static org.apache.atlas.SortOrder.ASCENDING;
import static org.apache.atlas.SortOrder.DESCENDING;
-import static org.apache.atlas.model.TypeCategory.ARRAY;
-import static org.apache.atlas.model.TypeCategory.MAP;
-import static org.apache.atlas.model.TypeCategory.OBJECT_ID_TYPE;
+import static org.apache.atlas.model.TypeCategory.*;
import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE;
import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED;
import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX;
-import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.BASIC_SEARCH_STATE_FILTER;
-import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH;
-import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH_DESCENDING_SORT;
-import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH_ASCENDING_SORT;
-import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.TO_RANGE_LIST;
+import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.*;
@Component
public class EntityDiscoveryService implements AtlasDiscoveryService {
@@ -105,10 +112,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private final int maxResultSetSize;
private final int maxTypesLengthInIdxQuery;
private final int maxTagsLengthInIdxQuery;
+ private final UserProfileService userProfileService;
@Inject
EntityDiscoveryService(MetadataRepository metadataRepository, AtlasTypeRegistry typeRegistry,
- AtlasGraph graph, GraphBackedSearchIndexer indexer, SearchTracker searchTracker) throws AtlasException {
+ AtlasGraph graph, GraphBackedSearchIndexer indexer, SearchTracker searchTracker,
+ UserProfileService userProfileService) throws AtlasException {
this.graph = graph;
this.graphPersistenceStrategy = new DefaultGraphPersistenceStrategy(metadataRepository);
this.entityRetriever = new EntityGraphRetriever(typeRegistry);
@@ -119,6 +128,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
this.maxResultSetSize = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_MAX_RESULT_SET_SIZE, 150);
this.maxTypesLengthInIdxQuery = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_TYPES_MAX_QUERY_STR_LENGTH, 512);
this.maxTagsLengthInIdxQuery = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_TAGS_MAX_QUERY_STR_LENGTH, 512);
+ this.userProfileService = userProfileService;
}
@Override
@@ -791,4 +801,51 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private Set<String> getEntityStates() {
return new HashSet<>(Arrays.asList(ACTIVE.toString(), DELETED.toString()));
}
-}
\ No newline at end of file
+
+
+ @Override
+ public void addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ try {
+ userProfileService.addSavedSearch(savedSearch);
+ } catch (AtlasBaseException e) {
+ LOG.error("addSavedSearch({})", savedSearch, e);
+ throw e;
+ }
+ }
+
+
+ @Override
+ public void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ try {
+ userProfileService.updateSavedSearch(savedSearch);
+ } catch (AtlasBaseException e) {
+ LOG.error("updateSavedSearch({})", savedSearch, e);
+ throw e;
+ }
+ }
+
+ @Override
+ public List<AtlasUserSavedSearch> getSavedSearches(String userName) throws AtlasBaseException {
+ try {
+ return userProfileService.getSavedSearches(userName);
+ } catch (AtlasBaseException e) {
+ LOG.error("getSavedSearches({})", userName, e);
+ throw e;
+ }
+ }
+
+ @Override
+ public AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException {
+ try {
+ return userProfileService.getSavedSearch(userName, searchName);
+ } catch (AtlasBaseException e) {
+ LOG.error("getSavedSearch({}, {})", userName, searchName, e);
+ throw e;
+ }
+ }
+
+ @Override
+ public void deleteSavedSearch(String guid) throws AtlasBaseException {
+ userProfileService.deleteSavedSearch(guid);
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
index ca7fad0..9dec281 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
@@ -994,6 +994,10 @@ public final class GraphHelper {
}
+ public static boolean isInternalType(String typeName) {
+ return typeName.startsWith(Constants.INTERNAL_PROPERTY_KEY_PREFIX);
+ }
+
public static void setArrayElementsProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName, List<Object> values) {
String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
if(GraphHelper.isReference(elementType)) {
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/ogm/AbstractDataTransferObject.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/AbstractDataTransferObject.java b/repository/src/main/java/org/apache/atlas/repository/ogm/AbstractDataTransferObject.java
new file mode 100644
index 0000000..f1a8bc9
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/AbstractDataTransferObject.java
@@ -0,0 +1,66 @@
+/**
+ * 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.ogm;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.AtlasBaseModelObject;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.lang3.StringUtils;
+
+
+public abstract class AbstractDataTransferObject<T extends AtlasBaseModelObject> implements DataTransferObject<T> {
+ private final AtlasTypeRegistry typeRegistry;
+ private final Class<T> objectType;
+ private final String entityTypeName;
+
+ protected AbstractDataTransferObject(AtlasTypeRegistry typeRegistry, Class<T> tClass) {
+ this.typeRegistry = typeRegistry;
+ this.objectType = tClass;
+ this.entityTypeName = Constants.INTERNAL_PROPERTY_KEY_PREFIX + objectType.getSimpleName();
+ }
+
+ @Override
+ public Class getObjectType() {
+ return objectType;
+ }
+
+ @Override
+ public AtlasEntityType getEntityType() {
+ return typeRegistry.getEntityTypeByName(entityTypeName);
+ }
+
+
+ protected AtlasEntity getDefaultAtlasEntity(T obj) throws AtlasBaseException {
+ AtlasEntity ret = getEntityType().createDefaultValue();
+
+ if (obj != null) {
+ if (StringUtils.isNotEmpty(obj.getGuid())) {
+ ret.setGuid(obj.getGuid());
+ }
+ }
+
+ return ret;
+ }
+
+ public void setGuid(T o, AtlasEntity entity) {
+ o.setGuid(entity.getGuid());
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java b/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java
new file mode 100644
index 0000000..26eee20
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java
@@ -0,0 +1,97 @@
+/**
+ * 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.ogm;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class AtlasSavedSearchDTO extends AbstractDataTransferObject<AtlasUserSavedSearch> {
+ private static final String PROPERTY_NAME = "name";
+ private static final String PROPERTY_OWNER_NAME = "ownerName";
+ private static final String PROPERTY_SEARCH_PARAMETERS = "searchParameters";
+ private static final String PROPERTY_UNIQUE_NAME = "uniqueName";
+
+ public AtlasSavedSearchDTO(AtlasTypeRegistry typeRegistry) {
+ super(typeRegistry, AtlasUserSavedSearch.class);
+ }
+
+ @Override
+ public AtlasUserSavedSearch from(AtlasEntity entity) {
+ AtlasUserSavedSearch savedSearch = new AtlasUserSavedSearch();
+
+ savedSearch.setGuid(entity.getGuid());
+ savedSearch.setName((String) entity.getAttribute(PROPERTY_NAME));
+ savedSearch.setOwnerName((String) entity.getAttribute(PROPERTY_OWNER_NAME));
+
+ String jsonSearchParams = (String) entity.getAttribute(PROPERTY_SEARCH_PARAMETERS);
+
+ if (StringUtils.isNotEmpty(jsonSearchParams)) {
+ savedSearch.setSearchParameters(AtlasType.fromJson(jsonSearchParams, SearchParameters.class));
+ }
+
+ return savedSearch;
+ }
+
+ @Override
+ public AtlasUserSavedSearch from(AtlasEntityWithExtInfo entityWithExtInfo) {
+ return from(entityWithExtInfo.getEntity());
+ }
+
+ @Override
+ public AtlasEntity toEntity(AtlasUserSavedSearch obj) throws AtlasBaseException {
+ AtlasEntity entity = getDefaultAtlasEntity(obj);
+
+ entity.setAttribute(PROPERTY_NAME, obj.getName());
+ entity.setAttribute(PROPERTY_OWNER_NAME, obj.getOwnerName());
+ entity.setAttribute(PROPERTY_UNIQUE_NAME, getUniqueValue(obj));
+
+ if (obj.getSearchParameters() != null) {
+ entity.setAttribute(PROPERTY_SEARCH_PARAMETERS, AtlasType.toJson(obj.getSearchParameters()));
+ }
+
+ return entity;
+ }
+
+ @Override
+ public AtlasEntityWithExtInfo toEntityWithExtInfo(AtlasUserSavedSearch obj) throws AtlasBaseException {
+ return new AtlasEntityWithExtInfo(toEntity(obj));
+ }
+
+ @Override
+ public Map<String, Object> getUniqueAttributes(AtlasUserSavedSearch obj) {
+ Map<String, Object> ret = new HashMap<>();
+
+ ret.put(PROPERTY_UNIQUE_NAME, getUniqueValue(obj));
+
+ return ret;
+ }
+
+ private String getUniqueValue(AtlasUserSavedSearch obj) {
+ return obj.getOwnerName() + ":" + obj.getName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasUserProfileDTO.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasUserProfileDTO.java b/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasUserProfileDTO.java
new file mode 100644
index 0000000..bcf2b9d
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasUserProfileDTO.java
@@ -0,0 +1,115 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.ogm;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.profile.AtlasUserProfile;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.type.AtlasTypeRegistry;
+
+import java.util.*;
+
+public class AtlasUserProfileDTO extends AbstractDataTransferObject<AtlasUserProfile> {
+ private final String PROPERTY_USER_NAME = "name";
+ private final String PROPERTY_FULL_NAME = "fullName";
+ private final String PROPERTY_SAVED_SEARCHES = "savedSearches";
+
+ private final AtlasSavedSearchDTO savedSearchDTO;
+
+ public AtlasUserProfileDTO(AtlasTypeRegistry typeRegistry, AtlasSavedSearchDTO savedSearchDTO) {
+ super(typeRegistry, AtlasUserProfile.class);
+
+ this.savedSearchDTO = savedSearchDTO;
+ }
+
+ public AtlasUserProfile from(AtlasEntity entity) {
+ AtlasUserProfile profile = new AtlasUserProfile();
+
+ profile.setGuid(entity.getGuid());
+ profile.setName((String) entity.getAttribute(PROPERTY_USER_NAME));
+ profile.setFullName((String) entity.getAttribute(PROPERTY_FULL_NAME));
+
+ return profile;
+ }
+
+ public AtlasUserProfile from(AtlasEntityWithExtInfo entityWithExtInfo) {
+ AtlasUserProfile userProfile = from(entityWithExtInfo.getEntity());
+
+ Object savedSearches = entityWithExtInfo.getEntity().getAttribute(PROPERTY_SAVED_SEARCHES);
+
+ if (savedSearches instanceof Collection) {
+ for (Object o : (Collection) savedSearches) {
+ if (o instanceof AtlasObjectId) {
+ AtlasObjectId ssObjId = (AtlasObjectId) o;
+ AtlasEntity ssEntity = entityWithExtInfo.getReferredEntity(ssObjId.getGuid());
+
+ if (ssEntity != null && ssEntity.getStatus() == AtlasEntity.Status.ACTIVE) {
+ AtlasUserSavedSearch savedSearch = savedSearchDTO.from(ssEntity);
+ userProfile.getSavedSearches().add(savedSearch);
+ }
+ }
+ }
+ }
+
+ return userProfile;
+ }
+
+ @Override
+ public AtlasEntity toEntity(AtlasUserProfile obj) throws AtlasBaseException {
+ AtlasEntity entity = getDefaultAtlasEntity(obj);
+
+ entity.setAttribute(PROPERTY_USER_NAME, obj.getName());
+ entity.setAttribute(PROPERTY_FULL_NAME, obj.getFullName());
+
+ return entity;
+ }
+
+ @Override
+ public AtlasEntityWithExtInfo toEntityWithExtInfo(AtlasUserProfile obj) throws AtlasBaseException {
+ AtlasEntity entity = toEntity(obj);
+ AtlasEntityWithExtInfo entityWithExtInfo = new AtlasEntityWithExtInfo(entity);
+
+ List<AtlasObjectId> objectIds = new ArrayList<>();
+
+ for (AtlasUserSavedSearch ss : obj.getSavedSearches()) {
+ AtlasEntity ssEntity = savedSearchDTO.toEntity(ss);
+
+ entityWithExtInfo.addReferredEntity(ssEntity);
+
+ objectIds.add(new AtlasObjectId(ssEntity.getGuid(), savedSearchDTO.getEntityType().getTypeName(), savedSearchDTO.getUniqueAttributes(ss)));
+ }
+
+ if (objectIds.size() > 0) {
+ entity.setAttribute(PROPERTY_SAVED_SEARCHES, objectIds);
+ }
+
+ return entityWithExtInfo;
+ }
+
+ @Override
+ public Map<String, Object> getUniqueAttributes(AtlasUserProfile obj) {
+ Map<String, Object> ret = new HashMap<>();
+
+ ret.put(PROPERTY_USER_NAME, obj.getName());
+
+ return ret;
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/ogm/DTORegistry.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/DTORegistry.java b/repository/src/main/java/org/apache/atlas/repository/ogm/DTORegistry.java
new file mode 100644
index 0000000..818960d
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/DTORegistry.java
@@ -0,0 +1,49 @@
+/**
+ * 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.repository.ogm;
+
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class DTORegistry {
+ private final Map<Type, DataTransferObject> typeDTOMap = new HashMap<>();
+
+
+ @Inject
+ public DTORegistry(AtlasTypeRegistry typeRegistry) {
+ AtlasSavedSearchDTO savedSearchDTO = new AtlasSavedSearchDTO(typeRegistry);
+ AtlasUserProfileDTO userProfileDTO = new AtlasUserProfileDTO(typeRegistry, savedSearchDTO);
+
+ registerDTO(savedSearchDTO);
+ registerDTO(userProfileDTO);
+ }
+
+ public <T extends DataTransferObject> DataTransferObject get(Type t) {
+ return typeDTOMap.get(t);
+ }
+
+ private void registerDTO(DataTransferObject dto) {
+ typeDTOMap.put(dto.getObjectType(), dto);
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java b/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java
new file mode 100644
index 0000000..bc93cc6
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java
@@ -0,0 +1,90 @@
+/**
+ * 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.ogm;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.AtlasBaseModelObject;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.model.instance.EntityMutationResponse;
+import org.apache.atlas.repository.store.graph.AtlasEntityStore;
+import org.apache.atlas.repository.store.graph.v1.AtlasEntityStream;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+
+
+@Component
+public class DataAccess {
+ private final AtlasEntityStore entityStore;
+ private final DTORegistry dtoRegistry;
+
+ @Inject
+ public DataAccess(AtlasEntityStore entityStore, DTORegistry dtoRegistry) {
+ this.entityStore = entityStore;
+ this.dtoRegistry = dtoRegistry;
+ }
+
+ public <T extends AtlasBaseModelObject> T save(T obj) throws AtlasBaseException {
+ DataTransferObject<T> dto = (DataTransferObject<T>)dtoRegistry.get(obj.getClass());
+
+ AtlasEntityWithExtInfo entityWithExtInfo = dto.toEntityWithExtInfo(obj);
+ EntityMutationResponse entityMutationResponse = entityStore.createOrUpdate(new AtlasEntityStream(entityWithExtInfo), false);
+
+ if (hasError(entityMutationResponse)) {
+ throw new AtlasBaseException(AtlasErrorCode.DATA_ACCESS_SAVE_FAILED, obj.toString());
+ }
+
+ return obj;
+ }
+
+ public <T extends AtlasBaseModelObject> T load(T obj) throws AtlasBaseException {
+ DataTransferObject<T> dto = (DataTransferObject<T>)dtoRegistry.get(obj.getClass());
+
+ AtlasEntityWithExtInfo entityWithExtInfo;
+
+ if (StringUtils.isNotEmpty(obj.getGuid())) {
+ entityWithExtInfo = entityStore.getById(obj.getGuid());
+ } else {
+ entityWithExtInfo = entityStore.getByUniqueAttributes(dto.getEntityType(), dto.getUniqueAttributes(obj));
+ }
+
+ return dto.from(entityWithExtInfo);
+ }
+
+ public void deleteUsingGuid(String guid) throws AtlasBaseException {
+ entityStore.deleteById(guid);
+ }
+
+ public <T extends AtlasBaseModelObject> void delete(T obj) throws AtlasBaseException {
+ T object = load(obj);
+
+ if (object != null) {
+ deleteUsingGuid(object.getGuid());
+ }
+ }
+
+ private boolean hasError(EntityMutationResponse er) {
+ return (er == null ||
+ !((er.getCreatedEntities() != null && er.getCreatedEntities().size() > 0)
+ || (er.getUpdatedEntities() != null && er.getUpdatedEntities().size() > 0)
+ )
+ );
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/ogm/DataTransferObject.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/DataTransferObject.java b/repository/src/main/java/org/apache/atlas/repository/ogm/DataTransferObject.java
new file mode 100644
index 0000000..752df7d
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/DataTransferObject.java
@@ -0,0 +1,43 @@
+/**
+ * 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.ogm;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.AtlasBaseModelObject;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.type.AtlasEntityType;
+
+import java.util.Map;
+
+
+public interface DataTransferObject<T extends AtlasBaseModelObject> {
+ Class getObjectType();
+
+ AtlasEntityType getEntityType();
+
+ T from(AtlasEntity entity);
+
+ T from(AtlasEntityWithExtInfo entityWithExtInfo);
+
+ AtlasEntity toEntity(T obj) throws AtlasBaseException;
+
+ AtlasEntityWithExtInfo toEntityWithExtInfo(T obj) throws AtlasBaseException;
+
+ Map<String, Object> getUniqueAttributes(T obj);
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasAbstractDefStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasAbstractDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasAbstractDefStoreV1.java
index 2bf53a1..02dad46 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasAbstractDefStoreV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasAbstractDefStoreV1.java
@@ -31,7 +31,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
@@ -42,8 +41,10 @@ import java.util.regex.Pattern;
protected final AtlasTypeDefGraphStoreV1 typeDefStore;
protected final AtlasTypeRegistry typeRegistry;
- private static final String NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ ]*";
- private static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX);
+ private static final String NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ ]*";
+ private static final String INTERNAL_NAME_REGEX = "__" + NAME_REGEX;
+ private static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX);
+ private static final Pattern INTERNAL_NAME_PATTERN = Pattern.compile(INTERNAL_NAME_REGEX);
public static final String ALLOW_RESERVED_KEYWORDS = "atlas.types.allowReservedKeywords";
@@ -75,9 +76,7 @@ import java.util.regex.Pattern;
}
public boolean isValidName(String typeName) {
- Matcher m = NAME_PATTERN.matcher(typeName);
-
- return m.matches();
+ return NAME_PATTERN.matcher(typeName).matches() || INTERNAL_NAME_PATTERN.matcher(typeName).matches();
}
@Override
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityChangeNotifier.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityChangeNotifier.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityChangeNotifier.java
index 6423aea..db47627 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityChangeNotifier.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityChangeNotifier.java
@@ -227,6 +227,10 @@ public class AtlasEntityChangeNotifier {
}
for (AtlasEntityHeader atlasEntityHeader : atlasEntityHeaders) {
+ if(GraphHelper.isInternalType(atlasEntityHeader.getTypeName())) {
+ continue;
+ }
+
String guid = atlasEntityHeader.getGuid();
AtlasVertex atlasVertex = AtlasGraphUtilsV1.findByGuid(guid);
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java b/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java
new file mode 100644
index 0000000..766d1c7
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java
@@ -0,0 +1,150 @@
+/**
+ * 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.userprofile;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.annotation.AtlasService;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.profile.AtlasUserProfile;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.repository.ogm.DataAccess;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@AtlasService
+public class UserProfileService {
+ private static final Logger LOG = LoggerFactory.getLogger(UserProfileService.class);
+
+ private final DataAccess dataAccess;
+
+ @Inject
+ public UserProfileService(DataAccess dataAccess) {
+ this.dataAccess = dataAccess;
+ }
+
+ public void saveUserProfile(AtlasUserProfile profile) throws AtlasBaseException {
+ dataAccess.save(profile);
+ }
+
+ public AtlasUserProfile getUserProfile(String userName) throws AtlasBaseException {
+ AtlasUserProfile profile = new AtlasUserProfile(userName);
+
+ return dataAccess.load(profile);
+ }
+
+ public AtlasUserProfile addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ String userName = savedSearch.getOwnerName();
+ AtlasUserProfile userProfile = null;
+
+ try {
+ userProfile = getUserProfile(userName);
+ } catch (AtlasBaseException excp) {
+ // ignore
+ }
+
+ if (userProfile == null) {
+ userProfile = new AtlasUserProfile(userName);
+ }
+
+ checkIfQueryAlreadyExists(savedSearch, userProfile);
+ userProfile.getSavedSearches().add(savedSearch);
+ return dataAccess.save(userProfile);
+ }
+
+ private void checkIfQueryAlreadyExists(AtlasUserSavedSearch savedSearch, AtlasUserProfile userProfile) throws AtlasBaseException {
+ for (AtlasUserSavedSearch exisingSearch : userProfile.getSavedSearches()) {
+ if (StringUtils.equals(exisingSearch.getOwnerName(), savedSearch.getOwnerName()) &&
+ StringUtils.equals(exisingSearch.getName(), savedSearch.getName())) {
+ throw new AtlasBaseException(AtlasErrorCode.SAVED_SEARCH_ALREADY_EXISTS, savedSearch.getName(), savedSearch.getOwnerName());
+ }
+ }
+ }
+
+ public AtlasUserSavedSearch updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ if (StringUtils.isBlank(savedSearch.getGuid())) {
+ throw new AtlasBaseException(AtlasErrorCode.INVALID_OBJECT_ID, savedSearch.getGuid());
+ }
+
+ AtlasUserSavedSearch existingSearch = getSavedSearch(savedSearch.getGuid());
+
+ // ownerName change is not allowed
+ if (!StringUtils.equals(existingSearch.getOwnerName(), savedSearch.getOwnerName())) {
+ throw new AtlasBaseException(AtlasErrorCode.SAVED_SEARCH_CHANGE_USER, existingSearch.getName(), existingSearch.getOwnerName(), savedSearch.getOwnerName());
+ }
+
+ // if renamed, ensure that there no other search with the new name exists
+ if (!StringUtils.equals(existingSearch.getName(), savedSearch.getName())) {
+ AtlasUserProfile userProfile = getUserProfile(existingSearch.getOwnerName());
+
+ // check if a another search with this name already exists
+ for (AtlasUserSavedSearch search : userProfile.getSavedSearches()) {
+ if (StringUtils.equals(search.getName(), savedSearch.getName())) {
+ if (!StringUtils.equals(search.getGuid(), savedSearch.getGuid())) {
+ throw new AtlasBaseException(AtlasErrorCode.SAVED_SEARCH_ALREADY_EXISTS, savedSearch.getName(), savedSearch.getOwnerName());
+ }
+ }
+ }
+ }
+
+ return dataAccess.save(savedSearch);
+ }
+
+ public List<AtlasUserSavedSearch> getSavedSearches(String userName) throws AtlasBaseException {
+ AtlasUserProfile profile = null;
+
+ try {
+ profile = getUserProfile(userName);
+ } catch (AtlasBaseException excp) {
+ // ignore
+ }
+
+ return (profile != null) ? profile.getSavedSearches() : null;
+ }
+
+ public AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException {
+ AtlasUserSavedSearch ss = new AtlasUserSavedSearch(userName, searchName);
+
+ return dataAccess.load(ss);
+ }
+
+ public AtlasUserSavedSearch getSavedSearch(String guid) throws AtlasBaseException {
+ AtlasUserSavedSearch ss = new AtlasUserSavedSearch();
+
+ ss.setGuid(guid);
+
+ return dataAccess.load(ss);
+ }
+
+ public void deleteUserProfile(String userName) throws AtlasBaseException {
+ AtlasUserProfile profile = getUserProfile(userName);
+
+ dataAccess.deleteUsingGuid(profile.getGuid());
+ }
+
+ public void deleteSavedSearch(String guid) throws AtlasBaseException {
+ dataAccess.deleteUsingGuid(guid);
+ }
+
+ public void deleteSearchBySearchName(String userName, String searchName) throws AtlasBaseException {
+ dataAccess.delete(new AtlasUserSavedSearch(userName, searchName));
+ }
+}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/main/java/org/apache/atlas/repository/util/FilterUtil.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/util/FilterUtil.java b/repository/src/main/java/org/apache/atlas/repository/util/FilterUtil.java
index 54d6b40..206ad72 100644
--- a/repository/src/main/java/org/apache/atlas/repository/util/FilterUtil.java
+++ b/repository/src/main/java/org/apache/atlas/repository/util/FilterUtil.java
@@ -6,9 +6,9 @@
* 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.
@@ -19,12 +19,11 @@ package org.apache.atlas.repository.util;
import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.TypeCategory;
-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.repository.Constants;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasType;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;
import org.apache.commons.collections.functors.NotPredicate;
@@ -38,10 +37,11 @@ public class FilterUtil {
public static Predicate getPredicateFromSearchFilter(SearchFilter searchFilter) {
List<Predicate> predicates = new ArrayList<>();
- final String type = searchFilter.getParam(SearchFilter.PARAM_TYPE);
- final String name = searchFilter.getParam(SearchFilter.PARAM_NAME);
- final String supertype = searchFilter.getParam(SearchFilter.PARAM_SUPERTYPE);
- final String notSupertype = searchFilter.getParam(SearchFilter.PARAM_NOT_SUPERTYPE);
+ final String type = searchFilter.getParam(SearchFilter.PARAM_TYPE);
+ final String name = searchFilter.getParam(SearchFilter.PARAM_NAME);
+ final String supertype = searchFilter.getParam(SearchFilter.PARAM_SUPERTYPE);
+ final String notSupertype = searchFilter.getParam(SearchFilter.PARAM_NOT_SUPERTYPE);
+ final List<String> notNames = searchFilter.getParams(SearchFilter.PARAM_NOT_NAME);
// Add filter for the type/category
if (StringUtils.isNotBlank(type)) {
@@ -63,6 +63,13 @@ public class FilterUtil {
predicates.add(new NotPredicate(getSuperTypePredicate(notSupertype)));
}
+ // Add filter for the type negation
+ if (CollectionUtils.isNotEmpty(notNames)) {
+ for (String notName : notNames) {
+ predicates.add(new NotPredicate(getNamePredicate(notName)));
+ }
+ }
+
return PredicateUtils.allPredicate(predicates);
}
@@ -91,8 +98,8 @@ public class FilterUtil {
@Override
public boolean evaluate(Object o) {
- return (isClassificationType(o) && ((AtlasClassificationType) o).getAllSuperTypes().contains(supertype))||
- (isEntityType(o) && ((AtlasEntityType)o).getAllSuperTypes().contains(supertype));
+ return (isClassificationType(o) && ((AtlasClassificationType) o).getAllSuperTypes().contains(supertype)) ||
+ (isEntityType(o) && ((AtlasEntityType) o).getAllSuperTypes().contains(supertype));
}
};
}
@@ -102,7 +109,7 @@ public class FilterUtil {
@Override
public boolean evaluate(Object o) {
if (o instanceof AtlasType) {
- AtlasType atlasType = (AtlasType)o;
+ AtlasType atlasType = (AtlasType) o;
switch (type.toUpperCase()) {
case "CLASS":
@@ -124,4 +131,9 @@ public class FilterUtil {
}
};
}
+
+ public static void addParamsToHideInternalType(SearchFilter searchFilter) {
+ searchFilter.setParam(SearchFilter.PARAM_NOT_NAME, Constants.TYPE_NAME_INTERNAL);
+ searchFilter.setParam(SearchFilter.PARAM_NOT_SUPERTYPE, Constants.TYPE_NAME_INTERNAL);
+ }
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/test/java/org/apache/atlas/TestModules.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/TestModules.java b/repository/src/test/java/org/apache/atlas/TestModules.java
index af3189b..131d3ee 100644
--- a/repository/src/test/java/org/apache/atlas/TestModules.java
+++ b/repository/src/test/java/org/apache/atlas/TestModules.java
@@ -24,7 +24,13 @@ import com.google.inject.Singleton;
import com.google.inject.matcher.Matchers;
import com.google.inject.multibindings.Multibinder;
import org.apache.atlas.annotation.GraphTransaction;
-import org.apache.atlas.discovery.*;
+import org.apache.atlas.discovery.AtlasDiscoveryService;
+import org.apache.atlas.discovery.AtlasLineageService;
+import org.apache.atlas.discovery.DataSetLineageService;
+import org.apache.atlas.discovery.DiscoveryService;
+import org.apache.atlas.discovery.EntityDiscoveryService;
+import org.apache.atlas.discovery.EntityLineageService;
+import org.apache.atlas.discovery.LineageService;
import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
import org.apache.atlas.graph.GraphSandboxUtil;
import org.apache.atlas.listener.EntityChangeListener;
@@ -40,8 +46,16 @@ import org.apache.atlas.repository.graph.HardDeleteHandler;
import org.apache.atlas.repository.graph.SoftDeleteHandler;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.impexp.ExportService;
-import org.apache.atlas.repository.store.graph.*;
-import org.apache.atlas.repository.store.graph.v1.*;
+import org.apache.atlas.repository.store.graph.AtlasEntityStore;
+import org.apache.atlas.repository.store.graph.BulkImporter;
+import org.apache.atlas.repository.store.graph.v1.AtlasEntityChangeNotifier;
+import org.apache.atlas.repository.store.graph.v1.AtlasEntityStoreV1;
+import org.apache.atlas.repository.store.graph.v1.AtlasTypeDefGraphStoreV1;
+import org.apache.atlas.repository.store.graph.v1.BulkImporterImpl;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.EntityGraphMapper;
+import org.apache.atlas.repository.store.graph.v1.HardDeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
import org.apache.atlas.repository.typestore.GraphBackedTypeStore;
import org.apache.atlas.repository.typestore.ITypeStore;
import org.apache.atlas.repository.typestore.StoreBackedTypeCache;
@@ -101,6 +115,7 @@ public class TestModules {
@Override
protected void configure() {
+
GraphSandboxUtil.create();
bindAuditRepository(binder());
http://git-wip-us.apache.org/repos/asf/atlas/blob/fd144e01/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java b/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
new file mode 100644
index 0000000..4e83296
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
@@ -0,0 +1,267 @@
+/**
+ * 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.userprofile;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.SearchFilter;
+import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.model.profile.AtlasUserProfile;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.util.FilterUtil;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.loadModelFromJson;
+import static org.testng.Assert.*;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class UserProfileServiceTest {
+ private UserProfileService userProfileService;
+ private AtlasTypeDefStore typeDefStore;
+ private int max_searches = 4;
+
+ @Inject
+ public void UserProfileServiceTest(AtlasTypeRegistry typeRegistry,
+ AtlasTypeDefStore typeDefStore,
+ UserProfileService userProfileService) throws IOException, AtlasBaseException {
+ this.typeDefStore = typeDefStore;
+ this.userProfileService = userProfileService;
+
+ loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
+ }
+
+ @Test
+ public void filterInternalType() throws AtlasBaseException {
+ SearchFilter searchFilter = new SearchFilter();
+ AtlasTypesDef filteredTypeDefs = typeDefStore.searchTypesDef(searchFilter);
+ int maxTypeDefs = filteredTypeDefs.getEntityDefs().size();
+
+ FilterUtil.addParamsToHideInternalType(searchFilter);
+ filteredTypeDefs = typeDefStore.searchTypesDef(searchFilter);
+
+ assertNotNull(filteredTypeDefs);
+ assertEquals(filteredTypeDefs.getEntityDefs().size(), maxTypeDefs - 3);
+ }
+
+ @Test
+ public void createsNewProfile() throws AtlasBaseException {
+ int i = 0;
+ assertSaveLoadUserProfile(i++);
+ assertSaveLoadUserProfile(i);
+ }
+
+ @Test(dependsOnMethods = { "createsNewProfile", "savesQueryForAnNonExistentUser" }, expectedExceptions = AtlasBaseException.class)
+ public void savesAlreadyExistingQueryForAnExistingUser() throws AtlasBaseException {
+ SearchParameters expectedSearchParameter = getActualSearchParameters();
+
+ for (int i = 0; i < 2; i++) {
+ String userName = getIndexBasedUserName(i);
+
+ for (int j = 0; j < max_searches; j++) {
+ String queryName = getIndexBasedQueryName(j);
+ AtlasUserProfile actual = userProfileService.addSavedSearch(new AtlasUserSavedSearch(userName, queryName, expectedSearchParameter));
+ assertNotNull(actual);
+ }
+ }
+ }
+
+ @Test(dependsOnMethods = { "createsNewProfile", "savesQueryForAnNonExistentUser", "savesAlreadyExistingQueryForAnExistingUser" })
+ public void savesExistingQueryForAnExistingUser() throws AtlasBaseException {
+ SearchParameters expectedSearchParameter = getActualSearchParameters();
+
+ for (int i = 0; i < 2; i++) {
+ String userName = getIndexBasedUserName(i);
+
+ for (int j = 4; j < max_searches + 6; j++) {
+ String queryName = getIndexBasedQueryName(j);
+ AtlasUserProfile actual = userProfileService.addSavedSearch(new AtlasUserSavedSearch(userName, queryName, expectedSearchParameter));
+ assertNotNull(actual);
+
+ AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, queryName);
+ assertNotNull(savedSearch);
+ assertEquals(savedSearch.getSearchParameters(), expectedSearchParameter);
+ }
+ }
+ }
+
+ private SearchParameters getActualSearchParameters() {
+ SearchParameters sp = new SearchParameters();
+ sp.setClassification("test-classification");
+ sp.setQuery("g.v().has('__guid').__guid.toList()");
+ sp.setLimit(10);
+ sp.setTypeName("some-type");
+
+ return sp;
+ }
+
+ @Test(dependsOnMethods = "createsNewProfile")
+ public void savesQueryForAnNonExistentUser() throws AtlasBaseException {
+ String expectedUserName = "firstXYZ";
+ String expectedQueryName = "testQuery";
+ SearchParameters expectedSearchParam = getActualSearchParameters();
+
+ AtlasUserProfile actual = userProfileService.addSavedSearch(new AtlasUserSavedSearch(expectedUserName, expectedQueryName, expectedSearchParam));
+ assertEquals(actual.getName(), expectedUserName);
+ assertEquals(actual.getSavedSearches().size(), 1);
+ assertEquals(actual.getSavedSearches().get(0).getName(), expectedQueryName);
+ }
+
+ @Test(dependsOnMethods = "createsNewProfile")
+ public void savesMultipleQueriesForUser() throws AtlasBaseException {
+ final String userName = getIndexBasedUserName(0);
+ createUserWithSavedQueries(userName);
+ }
+
+ private void createUserWithSavedQueries(String userName) throws AtlasBaseException {
+ SearchParameters actualSearchParameter = getActualSearchParameters();
+
+ saveQueries(userName, actualSearchParameter);
+ for (int i = 0; i < max_searches; i++) {
+ AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, getIndexBasedQueryName(i));
+ assertEquals(savedSearch.getName(), getIndexBasedQueryName(i));
+ assertEquals(savedSearch.getSearchParameters(), actualSearchParameter);
+ }
+ }
+
+ private void saveQueries(String userName, SearchParameters sp) throws AtlasBaseException {
+ for (int i = 0; i < max_searches; i++) {
+ userProfileService.addSavedSearch(new AtlasUserSavedSearch(userName, getIndexBasedQueryName(i), sp));
+ }
+ }
+
+ @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser"})
+ public void verifyQueryNameListForUser() throws AtlasBaseException {
+ final String userName = getIndexBasedUserName(0);
+
+ List<AtlasUserSavedSearch> list = userProfileService.getSavedSearches(userName);
+ List<String> names = getIndexBasedQueryNamesList();
+ for (int i = 0; i < names.size(); i++) {
+ assertTrue(names.contains(list.get(i).getName()), list.get(i).getName() + " failed!");
+ }
+ }
+
+ @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser"}, enabled = false)
+ public void verifyQueryConversionFromJSON() throws AtlasBaseException {
+ List<AtlasUserSavedSearch> list = userProfileService.getSavedSearches("first-0");
+
+ for (int i = 0; i < max_searches; i++) {
+ SearchParameters sp = list.get(i).getSearchParameters();
+ String json = AtlasType.toJson(sp);
+ assertEquals(AtlasType.toJson(getActualSearchParameters()).replace("\n", "").replace(" ", ""), json);
+ }
+ }
+
+ @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser"})
+ public void updateSearch() throws AtlasBaseException {
+ final String queryName = getIndexBasedQueryName(0);
+ String userName = getIndexBasedUserName(0);
+ AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName);
+ assertNotNull(expected);
+
+ SearchParameters sp = expected.getSearchParameters();
+ sp.setClassification("new-classification");
+
+ AtlasUserSavedSearch actual = userProfileService.updateSavedSearch(expected);
+
+ assertNotNull(actual);
+ assertNotNull(actual.getSearchParameters());
+ assertEquals(actual.getSearchParameters().getClassification(), expected.getSearchParameters().getClassification());
+ }
+
+ @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser", "verifyQueryNameListForUser"}, expectedExceptions = AtlasBaseException.class)
+ public void deleteUsingGuid() throws AtlasBaseException {
+ final String queryName = getIndexBasedQueryName(1);
+ String userName = getIndexBasedUserName(0);
+
+ AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName);
+ assertNotNull(expected);
+
+ userProfileService.deleteSavedSearch(expected.getGuid());
+ userProfileService.getSavedSearch(userName, queryName);
+ }
+
+ @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser", "verifyQueryNameListForUser"})
+ public void deleteSavedQuery() throws AtlasBaseException {
+ final String userName = getIndexBasedUserName(0);
+ AtlasUserProfile expected = userProfileService.getUserProfile(userName);
+ assertNotNull(expected);
+
+ int new_max_searches = expected.getSavedSearches().size();
+ String queryNameToBeDeleted = getIndexBasedQueryName(max_searches - 2);
+ userProfileService.deleteSearchBySearchName(userName, queryNameToBeDeleted);
+
+ List<AtlasUserSavedSearch> savedSearchList = userProfileService.getSavedSearches(userName);
+ assertEquals(savedSearchList.size(), new_max_searches - 1);
+ }
+
+ @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser", "verifyQueryNameListForUser"})
+ void deleteUser() throws AtlasBaseException {
+ String userName = getIndexBasedUserName(1);
+
+ userProfileService.deleteUserProfile(userName);
+ try {
+ userProfileService.getUserProfile(userName);
+ }
+ catch(AtlasBaseException ex) {
+ assertEquals(ex.getAtlasErrorCode().name(), AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND.name());
+ }
+ }
+
+ private void assertSaveLoadUserProfile(int i) throws AtlasBaseException {
+ String s = String.valueOf(i);
+ AtlasUserProfile expected = getAtlasUserProfile(i);
+ userProfileService.saveUserProfile(expected);
+
+ AtlasUserProfile actual = userProfileService.getUserProfile(expected.getName());
+ assertNotNull(actual);
+ assertEquals(expected.getName(), actual.getName());
+ assertEquals(expected.getFullName(), actual.getFullName());
+ }
+
+ public static AtlasUserProfile getAtlasUserProfile(Integer s) {
+ return new AtlasUserProfile(getIndexBasedUserName(s), String.format("first-%s last-%s", s, s));
+ }
+
+ private static String getIndexBasedUserName(Integer i) {
+ return String.format("first-%s", i.toString());
+ }
+
+ private static String getIndexBasedQueryName(Integer i) {
+ return String.format("testQuery-%s", i.toString());
+ }
+
+ public List<String> getIndexBasedQueryNamesList() {
+ List<String> list = new ArrayList<>();
+ for (int i = 0; i < max_searches; i++) {
+ list.add(getIndexBasedQueryName(i));
+ }
+
+ return list;
+ }
+}