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 @@
]
},
{
"name": "__internal",
"superTypes": [],
"typeVersion": "1.0",
"attributeDefs": []
},
{
"name": "Asset",
"superTypes": [],
"typeVersion": "1.0",
......@@ -108,6 +114,85 @@
"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": [
......@@ -150,4 +235,4 @@
"propagateTags": "NONE"
}
]
}
\ No newline at end of file
}
......@@ -35,6 +35,7 @@ public final class Constants {
* Entity type name property key.
*/
public static final String ENTITY_TYPE_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "typeName";
public static final String TYPE_NAME_INTERNAL = INTERNAL_PROPERTY_KEY_PREFIX + "internal";
/**
* Entity type's super types property key.
......
......@@ -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_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."),
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
TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"),
......@@ -122,6 +123,7 @@ public enum AtlasErrorCode {
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}"),
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
INTERNAL_ERROR(500, "ATLAS-500-00-001", "Internal server error {0}"),
......@@ -141,7 +143,10 @@ public enum AtlasErrorCode {
STORM_TOPOLOGY_UTIL(500, "ATLAS-500-00-00E", "StormToplogyUtil: {0}"),
SQOOP_HOOK(500, "ATLAS-500-00-00F", "SqoopHook: {0}"),
HIVE_HOOK(500, "ATLAS-500-00-010", "HiveHook: {0}"),
HIVE_HOOK_METASTORE_BRIDGE(500, "ATLAS-500-00-011", "HiveHookMetaStoreBridge: {0}");
HIVE_HOOK_METASTORE_BRIDGE(500, "ATLAS-500-00-011", "HiveHookMetaStoreBridge: {0}"),
DATA_ACCESS_SAVE_FAILED(500, "ATLAS-500-00-00B", "Save failed: {0}"),
DATA_ACCESS_LOAD_FAILED(500, "ATLAS-500-00-00C", "Load failed: {0}");
private String errorCode;
private String errorMessage;
......
/**
* 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 {
public static final String PARAM_NAME = "name";
public static final String PARAM_SUPERTYPE = "supertype";
public static final String PARAM_NOT_SUPERTYPE = "notsupertype";
public static final String PARAM_NOT_NAME = "notname";
/**
* to specify whether the result should be sorted? If yes, whether asc or desc.
......
......@@ -24,6 +24,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonValue;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -36,7 +37,9 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL
@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class SearchParameters {
public class SearchParameters implements Serializable {
private static final long serialVersionUID = 1L;
private String query;
private String typeName;
private String classification;
......
/**
* 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;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
import java.util.List;
public interface AtlasDiscoveryService {
/**
......@@ -79,4 +82,41 @@ public interface AtlasDiscoveryService {
* @return AtlasSearchResult
*/
AtlasSearchResult searchRelatedEntities(String guid, String relation, String sortByAttribute, SortOrder sortOrder, boolean excludeDeletedEntities, int limit, int offset) throws AtlasBaseException;
/**
*
*
* @param savedSearch Search to be saved
* @throws AtlasBaseException
*/
void addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
/**
*
* @param savedSearch Search to be saved
* @throws AtlasBaseException
*/
void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
/**
*
* @param userName Name of the user for whom the saved searches are to be retrieved
* @return List of saved searches for the user
* @throws AtlasBaseException
*/
List<AtlasUserSavedSearch> getSavedSearches(String userName) throws AtlasBaseException;
/**
*
* @param userName Name of the user who the search belongs
* @param searchName Name of the search to be retrieved
* @return Search object identified by the name
* @throws AtlasBaseException
*/
AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException;
/**
* @param guid Guid for the saved search
*/
void deleteSavedSearch(String guid) throws AtlasBaseException;
}
......@@ -30,9 +30,9 @@ import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasQueryType;
import org.apache.atlas.model.discovery.AtlasSearchResult.AttributeSearchResult;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.instance.AtlasEntity.Status;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
import org.apache.atlas.query.Expressions.AliasExpression;
import org.apache.atlas.query.Expressions.Expression;
import org.apache.atlas.query.Expressions.SelectExpression;
......@@ -51,9 +51,15 @@ import org.apache.atlas.repository.graphdb.AtlasIndexQuery;
import org.apache.atlas.repository.graphdb.AtlasIndexQuery.Result;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v1.EntityGraphRetriever;
import org.apache.atlas.type.*;
import org.apache.atlas.repository.userprofile.UserProfileService;
import org.apache.atlas.type.AtlasArrayType;
import org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasMapType;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.util.AtlasGremlinQueryProvider;
import org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery;
import org.apache.atlas.util.SearchTracker;
......@@ -71,24 +77,25 @@ import javax.inject.Inject;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.util.*;
import static org.apache.atlas.AtlasErrorCode.CLASSIFICATION_NOT_FOUND;
import static org.apache.atlas.AtlasErrorCode.DISCOVERY_QUERY_FAILED;
import static org.apache.atlas.AtlasErrorCode.UNKNOWN_TYPENAME;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.atlas.AtlasErrorCode.*;
import static org.apache.atlas.SortOrder.ASCENDING;
import static org.apache.atlas.SortOrder.DESCENDING;
import static org.apache.atlas.model.TypeCategory.ARRAY;
import static org.apache.atlas.model.TypeCategory.MAP;
import static org.apache.atlas.model.TypeCategory.OBJECT_ID_TYPE;
import static org.apache.atlas.model.TypeCategory.*;
import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE;
import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED;
import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX;
import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.BASIC_SEARCH_STATE_FILTER;
import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH;
import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH_DESCENDING_SORT;
import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH_ASCENDING_SORT;
import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.TO_RANGE_LIST;
import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.*;
@Component
public class EntityDiscoveryService implements AtlasDiscoveryService {
......@@ -105,10 +112,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private final int maxResultSetSize;
private final int maxTypesLengthInIdxQuery;
private final int maxTagsLengthInIdxQuery;
private final UserProfileService userProfileService;
@Inject
EntityDiscoveryService(MetadataRepository metadataRepository, AtlasTypeRegistry typeRegistry,
AtlasGraph graph, GraphBackedSearchIndexer indexer, SearchTracker searchTracker) throws AtlasException {
AtlasGraph graph, GraphBackedSearchIndexer indexer, SearchTracker searchTracker,
UserProfileService userProfileService) throws AtlasException {
this.graph = graph;
this.graphPersistenceStrategy = new DefaultGraphPersistenceStrategy(metadataRepository);
this.entityRetriever = new EntityGraphRetriever(typeRegistry);
......@@ -119,6 +128,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
this.maxResultSetSize = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_MAX_RESULT_SET_SIZE, 150);
this.maxTypesLengthInIdxQuery = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_TYPES_MAX_QUERY_STR_LENGTH, 512);
this.maxTagsLengthInIdxQuery = ApplicationProperties.get().getInt(Constants.INDEX_SEARCH_TAGS_MAX_QUERY_STR_LENGTH, 512);
this.userProfileService = userProfileService;
}
@Override
......@@ -791,4 +801,51 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private Set<String> getEntityStates() {
return new HashSet<>(Arrays.asList(ACTIVE.toString(), DELETED.toString()));
}
}
\ No newline at end of file
@Override
public void addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
try {
userProfileService.addSavedSearch(savedSearch);
} catch (AtlasBaseException e) {
LOG.error("addSavedSearch({})", savedSearch, e);
throw e;
}
}
@Override
public void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
try {
userProfileService.updateSavedSearch(savedSearch);
} catch (AtlasBaseException e) {
LOG.error("updateSavedSearch({})", savedSearch, e);
throw e;
}
}
@Override
public List<AtlasUserSavedSearch> getSavedSearches(String userName) throws AtlasBaseException {
try {
return userProfileService.getSavedSearches(userName);
} catch (AtlasBaseException e) {
LOG.error("getSavedSearches({})", userName, e);
throw e;
}
}
@Override
public AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException {
try {
return userProfileService.getSavedSearch(userName, searchName);
} catch (AtlasBaseException e) {
LOG.error("getSavedSearch({}, {})", userName, searchName, e);
throw e;
}
}
@Override
public void deleteSavedSearch(String guid) throws AtlasBaseException {
userProfileService.deleteSavedSearch(guid);
}
}
......@@ -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) {
String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
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;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
......@@ -42,8 +41,10 @@ import java.util.regex.Pattern;
protected final AtlasTypeDefGraphStoreV1 typeDefStore;
protected final AtlasTypeRegistry typeRegistry;
private static final String NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ ]*";
private static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX);
private static final String NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ ]*";
private static final String INTERNAL_NAME_REGEX = "__" + NAME_REGEX;
private static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX);
private static final Pattern INTERNAL_NAME_PATTERN = Pattern.compile(INTERNAL_NAME_REGEX);
public static final String ALLOW_RESERVED_KEYWORDS = "atlas.types.allowReservedKeywords";
......@@ -75,9 +76,7 @@ import java.util.regex.Pattern;
}
public boolean isValidName(String typeName) {
Matcher m = NAME_PATTERN.matcher(typeName);
return m.matches();
return NAME_PATTERN.matcher(typeName).matches() || INTERNAL_NAME_PATTERN.matcher(typeName).matches();
}
@Override
......
......@@ -227,6 +227,10 @@ public class AtlasEntityChangeNotifier {
}
for (AtlasEntityHeader atlasEntityHeader : atlasEntityHeaders) {
if(GraphHelper.isInternalType(atlasEntityHeader.getTypeName())) {
continue;
}
String guid = atlasEntityHeader.getGuid();
AtlasVertex atlasVertex = AtlasGraphUtilsV1.findByGuid(guid);
......
/**
* 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 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
*
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......@@ -19,12 +19,11 @@ package org.apache.atlas.repository.util;
import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;
import org.apache.commons.collections.functors.NotPredicate;
......@@ -38,10 +37,11 @@ public class FilterUtil {
public static Predicate getPredicateFromSearchFilter(SearchFilter searchFilter) {
List<Predicate> predicates = new ArrayList<>();
final String type = searchFilter.getParam(SearchFilter.PARAM_TYPE);
final String name = searchFilter.getParam(SearchFilter.PARAM_NAME);
final String supertype = searchFilter.getParam(SearchFilter.PARAM_SUPERTYPE);
final String notSupertype = searchFilter.getParam(SearchFilter.PARAM_NOT_SUPERTYPE);
final String type = searchFilter.getParam(SearchFilter.PARAM_TYPE);
final String name = searchFilter.getParam(SearchFilter.PARAM_NAME);
final String supertype = searchFilter.getParam(SearchFilter.PARAM_SUPERTYPE);
final String notSupertype = searchFilter.getParam(SearchFilter.PARAM_NOT_SUPERTYPE);
final List<String> notNames = searchFilter.getParams(SearchFilter.PARAM_NOT_NAME);
// Add filter for the type/category
if (StringUtils.isNotBlank(type)) {
......@@ -63,6 +63,13 @@ public class FilterUtil {
predicates.add(new NotPredicate(getSuperTypePredicate(notSupertype)));
}
// Add filter for the type negation
if (CollectionUtils.isNotEmpty(notNames)) {
for (String notName : notNames) {
predicates.add(new NotPredicate(getNamePredicate(notName)));
}
}
return PredicateUtils.allPredicate(predicates);
}
......@@ -91,8 +98,8 @@ public class FilterUtil {
@Override
public boolean evaluate(Object o) {
return (isClassificationType(o) && ((AtlasClassificationType) o).getAllSuperTypes().contains(supertype))||
(isEntityType(o) && ((AtlasEntityType)o).getAllSuperTypes().contains(supertype));
return (isClassificationType(o) && ((AtlasClassificationType) o).getAllSuperTypes().contains(supertype)) ||
(isEntityType(o) && ((AtlasEntityType) o).getAllSuperTypes().contains(supertype));
}
};
}
......@@ -102,7 +109,7 @@ public class FilterUtil {
@Override
public boolean evaluate(Object o) {
if (o instanceof AtlasType) {
AtlasType atlasType = (AtlasType)o;
AtlasType atlasType = (AtlasType) o;
switch (type.toUpperCase()) {
case "CLASS":
......@@ -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;
import com.google.inject.matcher.Matchers;
import com.google.inject.multibindings.Multibinder;
import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.discovery.*;
import org.apache.atlas.discovery.AtlasDiscoveryService;
import org.apache.atlas.discovery.AtlasLineageService;
import org.apache.atlas.discovery.DataSetLineageService;
import org.apache.atlas.discovery.DiscoveryService;
import org.apache.atlas.discovery.EntityDiscoveryService;
import org.apache.atlas.discovery.EntityLineageService;
import org.apache.atlas.discovery.LineageService;
import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
import org.apache.atlas.graph.GraphSandboxUtil;
import org.apache.atlas.listener.EntityChangeListener;
......@@ -40,8 +46,18 @@ import org.apache.atlas.repository.graph.HardDeleteHandler;
import org.apache.atlas.repository.graph.SoftDeleteHandler;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.impexp.ExportService;
import org.apache.atlas.repository.store.graph.*;
import org.apache.atlas.repository.store.graph.v1.*;
import org.apache.atlas.repository.store.graph.AtlasEntityStore;
import org.apache.atlas.repository.store.graph.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.ITypeStore;
import org.apache.atlas.repository.typestore.StoreBackedTypeCache;
......@@ -101,6 +117,7 @@ public class TestModules {
@Override
protected void configure() {
GraphSandboxUtil.create();
bindAuditRepository(binder());
......
......@@ -38,6 +38,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -70,13 +71,43 @@ public class ZipFileResourceTestUtils {
}
public static String getModelJson(String fileName) throws IOException {
final String userDir = System.getProperty("user.dir");
String filePath = userDir + "/../addons/models/" + fileName;
File f = new File(filePath);
String s = FileUtils.readFileToString(f);
assertFalse(StringUtils.isEmpty(s), "Model file read correctly!");
String ret = null;
File topModelsDir = new File(System.getProperty("user.dir") + "/../addons/models");
File[] topModelsDirContents = topModelsDir.exists() ? topModelsDir.listFiles() : null;
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 {
......
......@@ -23,6 +23,7 @@ import org.apache.atlas.AtlasException;
import org.apache.atlas.listener.EntityChangeListener;
import org.apache.atlas.notification.entity.EntityNotification;
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.IStruct;
import org.apache.atlas.typesystem.ITypedReferenceableInstance;
......@@ -165,6 +166,10 @@ public class NotificationEntityChangeListener implements EntityChangeListener {
List<EntityNotification> messages = new LinkedList<>();
for (IReferenceableInstance entityDefinition : entityDefinitions) {
if(GraphHelper.isInternalType(entityDefinition.getTypeName())) {
continue;
}
Referenceable entity = new Referenceable(entityDefinition);
Map<String, Object> attributesMap = entity.getValuesMap();
List<String> entityNotificationAttrs = getNotificationAttributes(entity.getTypeName());
......
......@@ -19,7 +19,15 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.exception.AtlasBaseException;
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.type.AtlasTypeUtil;
import org.apache.atlas.utils.AtlasPerfTracer;
......@@ -386,6 +394,7 @@ public class TypesREST {
ret.setParam(String.valueOf(key), String.valueOf(httpServletRequest.getParameter(key)));
}
FilterUtil.addParamsToHideInternalType(ret);
return ret;
}
}
......@@ -184,7 +184,7 @@ public final class Servlets {
return httpServletRequest.getLocalName();
}
public static String getUserName(HttpServletRequest httpServletRequest) throws IOException {
public static String getUserName(HttpServletRequest httpServletRequest) {
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