Commit ccd121e7 by ashutoshm Committed by Madhan Neethiraj

ATLAS-2100: UserProfile & SavedSearch API implementation

Signed-off-by: 's avatarMadhan Neethiraj <madhan@apache.org> (cherry picked from commit fd144e018f2af046a4b44760f34c7d95b5948ecf)
parent d67b0498
...@@ -35,6 +35,12 @@ ...@@ -35,6 +35,12 @@
] ]
}, },
{ {
"name": "__internal",
"superTypes": [],
"typeVersion": "1.0",
"attributeDefs": []
},
{
"name": "Asset", "name": "Asset",
"superTypes": [], "superTypes": [],
"typeVersion": "1.0", "typeVersion": "1.0",
...@@ -108,6 +114,85 @@ ...@@ -108,6 +114,85 @@
"isUnique": false "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": "uniqueName",
"typeName": "string",
"cardinality": "SINGLE",
"isIndexable": true,
"isOptional": false,
"isUnique": true
},
{
"name": "searchParameters",
"typeName": "string",
"cardinality": "SINGLE",
"isIndexable": false,
"isOptional": false,
"isUnique": false
}
]
} }
], ],
"relationshipDefs": [ "relationshipDefs": [
...@@ -150,4 +235,4 @@ ...@@ -150,4 +235,4 @@
"propagateTags": "NONE" "propagateTags": "NONE"
} }
] ]
} }
\ No newline at end of file
...@@ -35,6 +35,7 @@ public final class Constants { ...@@ -35,6 +35,7 @@ public final class Constants {
* Entity type name property key. * Entity type name property key.
*/ */
public static final String ENTITY_TYPE_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "typeName"; 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. * Entity type's super types property key.
......
...@@ -100,6 +100,7 @@ public enum AtlasErrorCode { ...@@ -100,6 +100,7 @@ public enum AtlasErrorCode {
CLASSIFICATIONDEF_PARENTS_ENTITYTYPES_DISJOINT(400, "ATLAS-400-00-053", "ClassificationDef ‘{0}‘ has supertypes whose entityTypes are disjoint; e.g. 2 supertypes that are not related by inheritance specify different non empty entityType lists. This means the child cannot honour the restrictions specified in both parents."), CLASSIFICATIONDEF_PARENTS_ENTITYTYPES_DISJOINT(400, "ATLAS-400-00-053", "ClassificationDef ‘{0}‘ has supertypes whose entityTypes are disjoint; e.g. 2 supertypes that are not related by inheritance specify different non empty entityType lists. This means the child cannot honour the restrictions specified in both parents."),
CLASSIFICATIONDEF_ENTITYTYPES_NOT_PARENTS_SUBSET(400, "ATLAS-400-00-054", "ClassificationDef ‘{0}‘ has entityTypes ‘{1}‘ which are not subsets of it's supertypes entityTypes"), CLASSIFICATIONDEF_ENTITYTYPES_NOT_PARENTS_SUBSET(400, "ATLAS-400-00-054", "ClassificationDef ‘{0}‘ has entityTypes ‘{1}‘ which are not subsets of it's supertypes entityTypes"),
INVALID_ENTITY_FOR_CLASSIFICATION (400, "ATLAS-400-00-055", "Entity (guid=‘{0}‘,typename=‘{1}‘) cannot be classified by Classification ‘{2}‘, because ‘{1}‘ is not in the ClassificationDef's restrictions."), INVALID_ENTITY_FOR_CLASSIFICATION (400, "ATLAS-400-00-055", "Entity (guid=‘{0}‘,typename=‘{1}‘) cannot be classified by Classification ‘{2}‘, because ‘{1}‘ is not in the ClassificationDef's restrictions."),
SAVED_SEARCH_CHANGE_USER(400, "ATLAS-400-00-056", "saved-search {0} can not be moved from user {1} to {2}"),
// All Not found enums go here // All Not found enums go here
TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"), TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"),
...@@ -122,6 +123,7 @@ public enum AtlasErrorCode { ...@@ -122,6 +123,7 @@ public enum AtlasErrorCode {
INSTANCE_ALREADY_EXISTS(409, "ATLAS-409-00-003", "failed to update entity: {0}"), INSTANCE_ALREADY_EXISTS(409, "ATLAS-409-00-003", "failed to update entity: {0}"),
RELATIONSHIP_ALREADY_EXISTS(409, "ATLAS-409-00-004", "relationship {0} already exists between entities {1} and {2}"), RELATIONSHIP_ALREADY_EXISTS(409, "ATLAS-409-00-004", "relationship {0} already exists between entities {1} and {2}"),
TYPE_HAS_RELATIONSHIPS(409, "ATLAS-409-00-005", "Given type {0} has associated relationshipDefs"), TYPE_HAS_RELATIONSHIPS(409, "ATLAS-409-00-005", "Given type {0} has associated relationshipDefs"),
SAVED_SEARCH_ALREADY_EXISTS(409, "ATLAS-409-00-006", "search named {0} already exists for user {1}"),
// All internal errors go here // All internal errors go here
INTERNAL_ERROR(500, "ATLAS-500-00-001", "Internal server error {0}"), INTERNAL_ERROR(500, "ATLAS-500-00-001", "Internal server error {0}"),
...@@ -141,7 +143,10 @@ public enum AtlasErrorCode { ...@@ -141,7 +143,10 @@ public enum AtlasErrorCode {
STORM_TOPOLOGY_UTIL(500, "ATLAS-500-00-00E", "StormToplogyUtil: {0}"), STORM_TOPOLOGY_UTIL(500, "ATLAS-500-00-00E", "StormToplogyUtil: {0}"),
SQOOP_HOOK(500, "ATLAS-500-00-00F", "SqoopHook: {0}"), SQOOP_HOOK(500, "ATLAS-500-00-00F", "SqoopHook: {0}"),
HIVE_HOOK(500, "ATLAS-500-00-010", "HiveHook: {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 errorCode;
private String errorMessage; private String errorMessage;
......
/**
* 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);
}
...@@ -44,6 +44,7 @@ public class SearchFilter { ...@@ -44,6 +44,7 @@ public class SearchFilter {
public static final String PARAM_NAME = "name"; public static final String PARAM_NAME = "name";
public static final String PARAM_SUPERTYPE = "supertype"; public static final String PARAM_SUPERTYPE = "supertype";
public static final String PARAM_NOT_SUPERTYPE = "notsupertype"; 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. * to specify whether the result should be sorted? If yes, whether asc or desc.
......
...@@ -24,6 +24,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties; ...@@ -24,6 +24,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonValue; import org.codehaus.jackson.annotate.JsonValue;
import org.codehaus.jackson.map.annotate.JsonSerialize; import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -36,7 +37,9 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL ...@@ -36,7 +37,9 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL
@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE) @JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class SearchParameters { public class SearchParameters implements Serializable {
private static final long serialVersionUID = 1L;
private String query; private String query;
private String typeName; private String typeName;
private String classification; private String classification;
......
/**
* 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;
}
}
/**
* 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;
}
}
...@@ -23,6 +23,9 @@ import org.apache.atlas.SortOrder; ...@@ -23,6 +23,9 @@ import org.apache.atlas.SortOrder;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult; import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.SearchParameters; import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
import java.util.List;
public interface AtlasDiscoveryService { public interface AtlasDiscoveryService {
/** /**
...@@ -79,4 +82,41 @@ public interface AtlasDiscoveryService { ...@@ -79,4 +82,41 @@ public interface AtlasDiscoveryService {
* @return AtlasSearchResult * @return AtlasSearchResult
*/ */
AtlasSearchResult searchRelatedEntities(String guid, String relation, String sortByAttribute, SortOrder sortOrder, boolean excludeDeletedEntities, int limit, int offset) throws AtlasBaseException; 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;
} }
...@@ -30,9 +30,9 @@ import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult; ...@@ -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.AtlasQueryType;
import org.apache.atlas.model.discovery.AtlasSearchResult.AttributeSearchResult; import org.apache.atlas.model.discovery.AtlasSearchResult.AttributeSearchResult;
import org.apache.atlas.model.discovery.SearchParameters; 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.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId; 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.AliasExpression;
import org.apache.atlas.query.Expressions.Expression; import org.apache.atlas.query.Expressions.Expression;
import org.apache.atlas.query.Expressions.SelectExpression; import org.apache.atlas.query.Expressions.SelectExpression;
...@@ -51,9 +51,15 @@ import org.apache.atlas.repository.graphdb.AtlasIndexQuery; ...@@ -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.AtlasIndexQuery.Result;
import org.apache.atlas.repository.graphdb.AtlasVertex; import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v1.EntityGraphRetriever; 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.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.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;
import org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery; import org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery;
import org.apache.atlas.util.SearchTracker; import org.apache.atlas.util.SearchTracker;
...@@ -71,24 +77,25 @@ import javax.inject.Inject; ...@@ -71,24 +77,25 @@ import javax.inject.Inject;
import javax.script.Bindings; import javax.script.Bindings;
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
import javax.script.ScriptException; import javax.script.ScriptException;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import static org.apache.atlas.AtlasErrorCode.CLASSIFICATION_NOT_FOUND; import java.util.Collection;
import static org.apache.atlas.AtlasErrorCode.DISCOVERY_QUERY_FAILED; import java.util.Collections;
import static org.apache.atlas.AtlasErrorCode.UNKNOWN_TYPENAME; 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.ASCENDING;
import static org.apache.atlas.SortOrder.DESCENDING; import static org.apache.atlas.SortOrder.DESCENDING;
import static org.apache.atlas.model.TypeCategory.ARRAY; import static org.apache.atlas.model.TypeCategory.*;
import static org.apache.atlas.model.TypeCategory.MAP;
import static org.apache.atlas.model.TypeCategory.OBJECT_ID_TYPE;
import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE; 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.model.instance.AtlasEntity.Status.DELETED;
import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX; 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.*;
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;
@Component @Component
public class EntityDiscoveryService implements AtlasDiscoveryService { public class EntityDiscoveryService implements AtlasDiscoveryService {
...@@ -105,10 +112,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -105,10 +112,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private final int maxResultSetSize; private final int maxResultSetSize;
private final int maxTypesLengthInIdxQuery; private final int maxTypesLengthInIdxQuery;
private final int maxTagsLengthInIdxQuery; private final int maxTagsLengthInIdxQuery;
private final UserProfileService userProfileService;
@Inject @Inject
EntityDiscoveryService(MetadataRepository metadataRepository, AtlasTypeRegistry typeRegistry, 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.graph = graph;
this.graphPersistenceStrategy = new DefaultGraphPersistenceStrategy(metadataRepository); this.graphPersistenceStrategy = new DefaultGraphPersistenceStrategy(metadataRepository);
this.entityRetriever = new EntityGraphRetriever(typeRegistry); this.entityRetriever = new EntityGraphRetriever(typeRegistry);
...@@ -119,6 +128,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -119,6 +128,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
this.maxResultSetSize = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_MAX_RESULT_SET_SIZE, 150); 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.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.maxTagsLengthInIdxQuery = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_TAGS_MAX_QUERY_STR_LENGTH, 512);
this.userProfileService = userProfileService;
} }
@Override @Override
...@@ -791,4 +801,51 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -791,4 +801,51 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private Set<String> getEntityStates() { private Set<String> getEntityStates() {
return new HashSet<>(Arrays.asList(ACTIVE.toString(), DELETED.toString())); 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);
}
}
...@@ -1079,6 +1079,10 @@ public final class GraphHelper { ...@@ -1079,6 +1079,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) { public static void setArrayElementsProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName, List<Object> values) {
String actualPropertyName = GraphHelper.encodePropertyKey(propertyName); String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
if(GraphHelper.isReference(elementType)) { if(GraphHelper.isReference(elementType)) {
......
/**
* 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());
}
}
/**
* 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();
}
}
/**
* 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;
}
}
/**
* 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);
}
}
/**
* 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)
)
);
}
}
/**
* 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);
}
...@@ -31,7 +31,6 @@ import org.slf4j.Logger; ...@@ -31,7 +31,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
...@@ -42,8 +41,10 @@ import java.util.regex.Pattern; ...@@ -42,8 +41,10 @@ import java.util.regex.Pattern;
protected final AtlasTypeDefGraphStoreV1 typeDefStore; protected final AtlasTypeDefGraphStoreV1 typeDefStore;
protected final AtlasTypeRegistry typeRegistry; protected final AtlasTypeRegistry typeRegistry;
private static final String NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ ]*"; 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 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"; public static final String ALLOW_RESERVED_KEYWORDS = "atlas.types.allowReservedKeywords";
...@@ -75,9 +76,7 @@ import java.util.regex.Pattern; ...@@ -75,9 +76,7 @@ import java.util.regex.Pattern;
} }
public boolean isValidName(String typeName) { public boolean isValidName(String typeName) {
Matcher m = NAME_PATTERN.matcher(typeName); return NAME_PATTERN.matcher(typeName).matches() || INTERNAL_NAME_PATTERN.matcher(typeName).matches();
return m.matches();
} }
@Override @Override
......
...@@ -227,6 +227,10 @@ public class AtlasEntityChangeNotifier { ...@@ -227,6 +227,10 @@ public class AtlasEntityChangeNotifier {
} }
for (AtlasEntityHeader atlasEntityHeader : atlasEntityHeaders) { for (AtlasEntityHeader atlasEntityHeader : atlasEntityHeaders) {
if(GraphHelper.isInternalType(atlasEntityHeader.getTypeName())) {
continue;
}
String guid = atlasEntityHeader.getGuid(); String guid = atlasEntityHeader.getGuid();
AtlasVertex atlasVertex = AtlasGraphUtilsV1.findByGuid(guid); AtlasVertex atlasVertex = AtlasGraphUtilsV1.findByGuid(guid);
......
/**
* 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));
}
}
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the * to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* * <p>
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* * <p>
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...@@ -19,12 +19,11 @@ package org.apache.atlas.repository.util; ...@@ -19,12 +19,11 @@ package org.apache.atlas.repository.util;
import org.apache.atlas.model.SearchFilter; import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.TypeCategory; import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import org.apache.atlas.repository.Constants;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.type.AtlasClassificationType; import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate; import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils; import org.apache.commons.collections.PredicateUtils;
import org.apache.commons.collections.functors.NotPredicate; import org.apache.commons.collections.functors.NotPredicate;
...@@ -38,10 +37,11 @@ public class FilterUtil { ...@@ -38,10 +37,11 @@ public class FilterUtil {
public static Predicate getPredicateFromSearchFilter(SearchFilter searchFilter) { public static Predicate getPredicateFromSearchFilter(SearchFilter searchFilter) {
List<Predicate> predicates = new ArrayList<>(); List<Predicate> predicates = new ArrayList<>();
final String type = searchFilter.getParam(SearchFilter.PARAM_TYPE); final String type = searchFilter.getParam(SearchFilter.PARAM_TYPE);
final String name = searchFilter.getParam(SearchFilter.PARAM_NAME); final String name = searchFilter.getParam(SearchFilter.PARAM_NAME);
final String supertype = searchFilter.getParam(SearchFilter.PARAM_SUPERTYPE); final String supertype = searchFilter.getParam(SearchFilter.PARAM_SUPERTYPE);
final String notSupertype = searchFilter.getParam(SearchFilter.PARAM_NOT_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 // Add filter for the type/category
if (StringUtils.isNotBlank(type)) { if (StringUtils.isNotBlank(type)) {
...@@ -63,6 +63,13 @@ public class FilterUtil { ...@@ -63,6 +63,13 @@ public class FilterUtil {
predicates.add(new NotPredicate(getSuperTypePredicate(notSupertype))); 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); return PredicateUtils.allPredicate(predicates);
} }
...@@ -91,8 +98,8 @@ public class FilterUtil { ...@@ -91,8 +98,8 @@ public class FilterUtil {
@Override @Override
public boolean evaluate(Object o) { public boolean evaluate(Object o) {
return (isClassificationType(o) && ((AtlasClassificationType) o).getAllSuperTypes().contains(supertype))|| return (isClassificationType(o) && ((AtlasClassificationType) o).getAllSuperTypes().contains(supertype)) ||
(isEntityType(o) && ((AtlasEntityType)o).getAllSuperTypes().contains(supertype)); (isEntityType(o) && ((AtlasEntityType) o).getAllSuperTypes().contains(supertype));
} }
}; };
} }
...@@ -102,7 +109,7 @@ public class FilterUtil { ...@@ -102,7 +109,7 @@ public class FilterUtil {
@Override @Override
public boolean evaluate(Object o) { public boolean evaluate(Object o) {
if (o instanceof AtlasType) { if (o instanceof AtlasType) {
AtlasType atlasType = (AtlasType)o; AtlasType atlasType = (AtlasType) o;
switch (type.toUpperCase()) { switch (type.toUpperCase()) {
case "CLASS": case "CLASS":
...@@ -126,4 +133,9 @@ public class FilterUtil { ...@@ -126,4 +133,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);
}
} }
...@@ -24,7 +24,13 @@ import com.google.inject.Singleton; ...@@ -24,7 +24,13 @@ import com.google.inject.Singleton;
import com.google.inject.matcher.Matchers; import com.google.inject.matcher.Matchers;
import com.google.inject.multibindings.Multibinder; import com.google.inject.multibindings.Multibinder;
import org.apache.atlas.annotation.GraphTransaction; 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.discovery.graph.GraphBackedDiscoveryService;
import org.apache.atlas.graph.GraphSandboxUtil; import org.apache.atlas.graph.GraphSandboxUtil;
import org.apache.atlas.listener.EntityChangeListener; import org.apache.atlas.listener.EntityChangeListener;
...@@ -40,8 +46,18 @@ import org.apache.atlas.repository.graph.HardDeleteHandler; ...@@ -40,8 +46,18 @@ import org.apache.atlas.repository.graph.HardDeleteHandler;
import org.apache.atlas.repository.graph.SoftDeleteHandler; import org.apache.atlas.repository.graph.SoftDeleteHandler;
import org.apache.atlas.repository.graphdb.AtlasGraph; import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.impexp.ExportService; import org.apache.atlas.repository.impexp.ExportService;
import org.apache.atlas.repository.store.graph.*; import org.apache.atlas.repository.store.graph.AtlasEntityStore;
import org.apache.atlas.repository.store.graph.v1.*; import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
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.AtlasRelationshipStoreV1;
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.GraphBackedTypeStore;
import org.apache.atlas.repository.typestore.ITypeStore; import org.apache.atlas.repository.typestore.ITypeStore;
import org.apache.atlas.repository.typestore.StoreBackedTypeCache; import org.apache.atlas.repository.typestore.StoreBackedTypeCache;
...@@ -101,6 +117,7 @@ public class TestModules { ...@@ -101,6 +117,7 @@ public class TestModules {
@Override @Override
protected void configure() { protected void configure() {
GraphSandboxUtil.create(); GraphSandboxUtil.create();
bindAuditRepository(binder()); bindAuditRepository(binder());
......
...@@ -38,6 +38,7 @@ import java.io.File; ...@@ -38,6 +38,7 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -70,13 +71,43 @@ public class ZipFileResourceTestUtils { ...@@ -70,13 +71,43 @@ public class ZipFileResourceTestUtils {
} }
public static String getModelJson(String fileName) throws IOException { public static String getModelJson(String fileName) throws IOException {
final String userDir = System.getProperty("user.dir"); String ret = null;
String filePath = userDir + "/../addons/models/" + fileName; File topModelsDir = new File(System.getProperty("user.dir") + "/../addons/models");
File f = new File(filePath); File[] topModelsDirContents = topModelsDir.exists() ? topModelsDir.listFiles() : null;
String s = FileUtils.readFileToString(f);
assertFalse(StringUtils.isEmpty(s), "Model file read correctly!");
return s; assertTrue(topModelsDirContents != null, topModelsDir.getAbsolutePath() + ": unable to find/read directory");
Arrays.sort(topModelsDirContents);
for (File modelDir : topModelsDirContents) {
if (modelDir.exists() && modelDir.isDirectory()) {
ret = getFileContents(modelDir, fileName);
if (ret != null) {
break;
}
}
}
if (ret == null) {
ret = getFileContents(topModelsDir, fileName);
}
assertTrue(ret != null, fileName + ": unable to find model file");
return ret;
}
public static String getFileContents(File dir, String fileName) throws IOException {
if (dir.exists() && dir.isDirectory()) {
File file = new File(dir, fileName);
if (file.exists() && file.isFile()) {
return FileUtils.readFileToString(file);
}
}
return null;
} }
public static String getModelJsonFromResources(String fileName) throws IOException { public static String getModelJsonFromResources(String fileName) throws IOException {
......
/**
* 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;
}
}
...@@ -23,6 +23,7 @@ import org.apache.atlas.AtlasException; ...@@ -23,6 +23,7 @@ import org.apache.atlas.AtlasException;
import org.apache.atlas.listener.EntityChangeListener; import org.apache.atlas.listener.EntityChangeListener;
import org.apache.atlas.notification.entity.EntityNotification; import org.apache.atlas.notification.entity.EntityNotification;
import org.apache.atlas.notification.entity.EntityNotificationImpl; import org.apache.atlas.notification.entity.EntityNotificationImpl;
import org.apache.atlas.repository.graph.GraphHelper;
import org.apache.atlas.typesystem.IReferenceableInstance; import org.apache.atlas.typesystem.IReferenceableInstance;
import org.apache.atlas.typesystem.IStruct; import org.apache.atlas.typesystem.IStruct;
import org.apache.atlas.typesystem.ITypedReferenceableInstance; import org.apache.atlas.typesystem.ITypedReferenceableInstance;
...@@ -165,6 +166,10 @@ public class NotificationEntityChangeListener implements EntityChangeListener { ...@@ -165,6 +166,10 @@ public class NotificationEntityChangeListener implements EntityChangeListener {
List<EntityNotification> messages = new LinkedList<>(); List<EntityNotification> messages = new LinkedList<>();
for (IReferenceableInstance entityDefinition : entityDefinitions) { for (IReferenceableInstance entityDefinition : entityDefinitions) {
if(GraphHelper.isInternalType(entityDefinition.getTypeName())) {
continue;
}
Referenceable entity = new Referenceable(entityDefinition); Referenceable entity = new Referenceable(entityDefinition);
Map<String, Object> attributesMap = entity.getValuesMap(); Map<String, Object> attributesMap = entity.getValuesMap();
List<String> entityNotificationAttrs = getNotificationAttributes(entity.getTypeName()); List<String> entityNotificationAttrs = getNotificationAttributes(entity.getTypeName());
......
...@@ -19,25 +19,33 @@ package org.apache.atlas.web.rest; ...@@ -19,25 +19,33 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.SortOrder; import org.apache.atlas.SortOrder;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.discovery.AtlasDiscoveryService; import org.apache.atlas.discovery.AtlasDiscoveryService;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult; import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.SearchParameters; import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.atlas.web.util.Servlets; import org.apache.atlas.web.util.Servlets;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import java.io.IOException;
import java.util.List;
/** /**
* REST interface for data discovery using dsl or full text search * REST interface for data discovery using dsl or full text search
...@@ -48,6 +56,9 @@ import javax.ws.rs.QueryParam; ...@@ -48,6 +56,9 @@ import javax.ws.rs.QueryParam;
public class DiscoveryREST { public class DiscoveryREST {
private static final Logger PERF_LOG = AtlasPerfTracer.getPerfLogger("rest.DiscoveryREST"); private static final Logger PERF_LOG = AtlasPerfTracer.getPerfLogger("rest.DiscoveryREST");
@Context
private HttpServletRequest httpServletRequest;
private final AtlasDiscoveryService atlasDiscoveryService; private final AtlasDiscoveryService atlasDiscoveryService;
@Inject @Inject
...@@ -57,11 +68,12 @@ public class DiscoveryREST { ...@@ -57,11 +68,12 @@ public class DiscoveryREST {
/** /**
* Retrieve data for the specified DSL * Retrieve data for the specified DSL
* @param query DSL query *
* @param typeName limit the result to only entities of specified type or its sub-types * @param query DSL query
* @param typeName limit the result to only entities of specified type or its sub-types
* @param classification limit the result to only entities tagged with the given classification or or its sub-types * @param classification limit the result to only entities tagged with the given classification or or its sub-types
* @param limit limit the result set to only include the specified number of entries * @param limit limit the result set to only include the specified number of entries
* @param offset start offset of the result set (useful for pagination) * @param offset start offset of the result set (useful for pagination)
* @return Search results * @return Search results
* @throws AtlasBaseException * @throws AtlasBaseException
* @HTTP 200 On successful DSL execution with some results, might return an empty list if execution succeeded * @HTTP 200 On successful DSL execution with some results, might return an empty list if execution succeeded
...@@ -82,7 +94,7 @@ public class DiscoveryREST { ...@@ -82,7 +94,7 @@ public class DiscoveryREST {
try { try {
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchUsingDSL(" + query + "," + typeName perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchUsingDSL(" + query + "," + typeName
+ "," + classification + "," + limit + "," + offset + ")"); + "," + classification + "," + limit + "," + offset + ")");
} }
String queryStr = query == null ? "" : query; String queryStr = query == null ? "" : query;
...@@ -106,8 +118,9 @@ public class DiscoveryREST { ...@@ -106,8 +118,9 @@ public class DiscoveryREST {
/** /**
* Retrieve data for the specified fulltext query * Retrieve data for the specified fulltext query
* @param query Fulltext query *
* @param limit limit the result set to only include the specified number of entries * @param query Fulltext query
* @param limit limit the result set to only include the specified number of entries
* @param offset start offset of the result set (useful for pagination) * @param offset start offset of the result set (useful for pagination)
* @return Search results * @return Search results
* @throws AtlasBaseException * @throws AtlasBaseException
...@@ -119,16 +132,16 @@ public class DiscoveryREST { ...@@ -119,16 +132,16 @@ public class DiscoveryREST {
@Path("/fulltext") @Path("/fulltext")
@Consumes(Servlets.JSON_MEDIA_TYPE) @Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE) @Produces(Servlets.JSON_MEDIA_TYPE)
public AtlasSearchResult searchUsingFullText(@QueryParam("query") String query, public AtlasSearchResult searchUsingFullText(@QueryParam("query") String query,
@QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities, @QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities,
@QueryParam("limit") int limit, @QueryParam("limit") int limit,
@QueryParam("offset") int offset) throws AtlasBaseException { @QueryParam("offset") int offset) throws AtlasBaseException {
AtlasPerfTracer perf = null; AtlasPerfTracer perf = null;
try { try {
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchUsingFullText(" + query + "," + perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchUsingFullText(" + query + "," +
limit + "," + offset + ")"); limit + "," + offset + ")");
} }
return atlasDiscoveryService.searchUsingFullTextQuery(query, excludeDeletedEntities, limit, offset); return atlasDiscoveryService.searchUsingFullTextQuery(query, excludeDeletedEntities, limit, offset);
...@@ -139,11 +152,12 @@ public class DiscoveryREST { ...@@ -139,11 +152,12 @@ public class DiscoveryREST {
/** /**
* Retrieve data for the specified fulltext query * Retrieve data for the specified fulltext query
* @param query Fulltext query *
* @param typeName limit the result to only entities of specified type or its sub-types * @param query Fulltext query
* @param typeName limit the result to only entities of specified type or its sub-types
* @param classification limit the result to only entities tagged with the given classification or or its sub-types * @param classification limit the result to only entities tagged with the given classification or or its sub-types
* @param limit limit the result set to only include the specified number of entries * @param limit limit the result set to only include the specified number of entries
* @param offset start offset of the result set (useful for pagination) * @param offset start offset of the result set (useful for pagination)
* @return Search results * @return Search results
* @throws AtlasBaseException * @throws AtlasBaseException
* @HTTP 200 On successful FullText lookup with some results, might return an empty list if execution succeeded * @HTTP 200 On successful FullText lookup with some results, might return an empty list if execution succeeded
...@@ -165,7 +179,7 @@ public class DiscoveryREST { ...@@ -165,7 +179,7 @@ public class DiscoveryREST {
try { try {
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchUsingBasic(" + query + "," + perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchUsingBasic(" + query + "," +
typeName + "," + classification + "," + limit + "," + offset + ")"); typeName + "," + classification + "," + limit + "," + offset + ")");
} }
SearchParameters searchParameters = new SearchParameters(); SearchParameters searchParameters = new SearchParameters();
...@@ -184,11 +198,12 @@ public class DiscoveryREST { ...@@ -184,11 +198,12 @@ public class DiscoveryREST {
/** /**
* Retrieve data for the specified attribute search query * Retrieve data for the specified attribute search query
* @param attrName Attribute name *
* @param attrName Attribute name
* @param attrValuePrefix Attibute value to search on * @param attrValuePrefix Attibute value to search on
* @param typeName limit the result to only entities of specified type or its sub-types * @param typeName limit the result to only entities of specified type or its sub-types
* @param limit limit the result set to only include the specified number of entries * @param limit limit the result set to only include the specified number of entries
* @param offset start offset of the result set (useful for pagination) * @param offset start offset of the result set (useful for pagination)
* @return Search results * @return Search results
* @throws AtlasBaseException * @throws AtlasBaseException
* @HTTP 200 On successful FullText lookup with some results, might return an empty list if execution succeeded * @HTTP 200 On successful FullText lookup with some results, might return an empty list if execution succeeded
...@@ -226,10 +241,10 @@ public class DiscoveryREST { ...@@ -226,10 +241,10 @@ public class DiscoveryREST {
/** /**
* Attribute based search for entities satisfying the search parameters * Attribute based search for entities satisfying the search parameters
*
* @param parameters Search parameters * @param parameters Search parameters
* @return Atlas search result * @return Atlas search result
* @throws AtlasBaseException * @throws AtlasBaseException
*
* @HTTP 200 On successful search * @HTTP 200 On successful search
* @HTTP 400 Tag/Entity doesn't exist or Tag/entity filter is present without tag/type name * @HTTP 400 Tag/Entity doesn't exist or Tag/entity filter is present without tag/type name
*/ */
...@@ -242,7 +257,7 @@ public class DiscoveryREST { ...@@ -242,7 +257,7 @@ public class DiscoveryREST {
try { try {
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchWithParameters("+ parameters + ")"); perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.searchWithParameters(" + parameters + ")");
} }
if (parameters.getLimit() < 0 || parameters.getOffset() < 0) { if (parameters.getLimit() < 0 || parameters.getOffset() < 0) {
...@@ -269,15 +284,15 @@ public class DiscoveryREST { ...@@ -269,15 +284,15 @@ public class DiscoveryREST {
/** /**
* Relationship search to search for related entities satisfying the search parameters * Relationship search to search for related entities satisfying the search parameters
* @param guid Attribute name *
* @param relation relationName * @param guid Attribute name
* @param relation relationName
* @param sortByAttribute sort the result using this attribute name, default value is 'name' * @param sortByAttribute sort the result using this attribute name, default value is 'name'
* @param sortOrder sorting order * @param sortOrder sorting order
* @param limit limit the result set to only include the specified number of entries * @param limit limit the result set to only include the specified number of entries
* @param offset start offset of the result set (useful for pagination) * @param offset start offset of the result set (useful for pagination)
* @return Atlas search result * @return Atlas search result
* @throws AtlasBaseException * @throws AtlasBaseException
*
* @HTTP 200 On successful search * @HTTP 200 On successful search
* @HTTP 400 guid is not a valid entity type or attributeName is not a valid relationship attribute * @HTTP 400 guid is not a valid entity type or attributeName is not a valid relationship attribute
*/ */
...@@ -285,13 +300,13 @@ public class DiscoveryREST { ...@@ -285,13 +300,13 @@ public class DiscoveryREST {
@Path("relationship") @Path("relationship")
@Consumes(Servlets.JSON_MEDIA_TYPE) @Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE) @Produces(Servlets.JSON_MEDIA_TYPE)
public AtlasSearchResult searchRelatedEntities(@QueryParam("guid") String guid, public AtlasSearchResult searchRelatedEntities(@QueryParam("guid") String guid,
@QueryParam("relation") String relation, @QueryParam("relation") String relation,
@QueryParam("sortBy") String sortByAttribute, @QueryParam("sortBy") String sortByAttribute,
@QueryParam("sortOrder") SortOrder sortOrder, @QueryParam("sortOrder") SortOrder sortOrder,
@QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities, @QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities,
@QueryParam("limit") int limit, @QueryParam("limit") int limit,
@QueryParam("offset") int offset) throws AtlasBaseException { @QueryParam("offset") int offset) throws AtlasBaseException {
AtlasPerfTracer perf = null; AtlasPerfTracer perf = null;
try { try {
...@@ -308,7 +323,7 @@ public class DiscoveryREST { ...@@ -308,7 +323,7 @@ public class DiscoveryREST {
private boolean isEmpty(SearchParameters.FilterCriteria filterCriteria) { private boolean isEmpty(SearchParameters.FilterCriteria filterCriteria) {
return filterCriteria == null || return filterCriteria == null ||
(StringUtils.isEmpty(filterCriteria.getAttributeName()) && CollectionUtils.isEmpty(filterCriteria.getCriterion())); (StringUtils.isEmpty(filterCriteria.getAttributeName()) && CollectionUtils.isEmpty(filterCriteria.getCriterion()));
} }
private String escapeTypeName(String typeName) { private String escapeTypeName(String typeName) {
...@@ -322,4 +337,68 @@ public class DiscoveryREST { ...@@ -322,4 +337,68 @@ public class DiscoveryREST {
return ret; return ret;
} }
}
\ No newline at end of file /**
* @param savedSearch
* @throws AtlasBaseException
* @throws IOException
*/
@POST
@Path("saved")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
public void createSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException, IOException {
savedSearch.setOwnerName(Servlets.getUserName(httpServletRequest));
atlasDiscoveryService.addSavedSearch(savedSearch);
}
/**
* @param savedSearch
* @throws AtlasBaseException
* @throws IOException
*/
@PUT
@Path("saved")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
public void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
atlasDiscoveryService.updateSavedSearch(savedSearch);
}
/**
* @param searchName Name of the saved search
* @return
*/
@GET
@Path("saved/{name}")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
public AtlasUserSavedSearch getSavedSearch(@QueryParam("user") String userName, @PathParam("name") String searchName) throws AtlasBaseException {
userName = StringUtils.isBlank(userName) ? Servlets.getUserName(httpServletRequest) : userName;
return atlasDiscoveryService.getSavedSearch(userName, searchName);
}
/**
* @return list of all saved searches for given user
*/
@GET
@Path("saved")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
public List<AtlasUserSavedSearch> getSavedSearches(@QueryParam("user") String userName) throws AtlasBaseException {
userName = StringUtils.isBlank(userName) ? Servlets.getUserName(httpServletRequest) : userName;
return atlasDiscoveryService.getSavedSearches(userName);
}
/**
* @param guid Name of the saved search
*/
@DELETE
@Path("saved/{guid}")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
public void deleteSavedSearch(@PathParam("guid") String guid) throws AtlasBaseException {
atlasDiscoveryService.deleteSavedSearch(guid);
}
}
...@@ -19,7 +19,15 @@ package org.apache.atlas.web.rest; ...@@ -19,7 +19,15 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.SearchFilter; import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.typedef.*; import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.repository.util.FilterUtil;
import org.apache.atlas.store.AtlasTypeDefStore; import org.apache.atlas.store.AtlasTypeDefStore;
import org.apache.atlas.type.AtlasTypeUtil; import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.utils.AtlasPerfTracer;
...@@ -386,6 +394,7 @@ public class TypesREST { ...@@ -386,6 +394,7 @@ public class TypesREST {
ret.setParam(String.valueOf(key), String.valueOf(httpServletRequest.getParameter(key))); ret.setParam(String.valueOf(key), String.valueOf(httpServletRequest.getParameter(key)));
} }
FilterUtil.addParamsToHideInternalType(ret);
return ret; return ret;
} }
} }
...@@ -184,7 +184,7 @@ public final class Servlets { ...@@ -184,7 +184,7 @@ public final class Servlets {
return httpServletRequest.getLocalName(); return httpServletRequest.getLocalName();
} }
public static String getUserName(HttpServletRequest httpServletRequest) throws IOException { public static String getUserName(HttpServletRequest httpServletRequest) {
return httpServletRequest.getRemoteUser(); return httpServletRequest.getRemoteUser();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment