Commit a7d80449 by skoritala Committed by Madhan Neethiraj

ATLAS-3308: enhanced Quicksearch API to support parameters via POST method

parent ce5b6d7f
...@@ -47,8 +47,8 @@ public final class Constants { ...@@ -47,8 +47,8 @@ public final class Constants {
*/ */
public static final String ENTITY_TYPE_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "typeName"); public static final String ENTITY_TYPE_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "typeName");
public static final String TYPE_NAME_INTERNAL = INTERNAL_PROPERTY_KEY_PREFIX + "internal"; public static final String TYPE_NAME_INTERNAL = INTERNAL_PROPERTY_KEY_PREFIX + "internal";
public static final String ASSET_OWNER_PROPERTY_KEY = "Asset.owner"; public static final String ASSET_ENTITY_TYPE = "Asset";
public static final String OWNER_ATTRIBUTE = "owner";
/** /**
* Entity type's super types property key. * Entity type's super types property key.
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.repository.graphdb;
import org.apache.atlas.model.discovery.SearchParameters.FilterCriteria;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import java.util.Map;
import java.util.Set;
public class AggregationContext {
private final String queryString;
private final FilterCriteria filterCriteria;
private final AtlasEntityType searchForEntityType;
private final Set<String> aggregationFieldNames;
private final Set<AtlasAttribute> aggregationAttributes;
private final Map<String, String> indexFieldNameCache;
private final boolean excludeDeletedEntities;
private final boolean includeSubTypes;
/**
* @param queryString the query string whose aggregation metrics need to be retrieved.
* @param searchForEntityType
* @param aggregationFieldNames the set of aggregation fields.
* @param indexFieldNameCache
* @param excludeDeletedEntities a boolean flag to indicate if the deleted entities need to be excluded in search
*/
public AggregationContext(String queryString,
FilterCriteria filterCriteria,
AtlasEntityType searchForEntityType,
Set<String> aggregationFieldNames,
Set<AtlasAttribute> aggregationAttributes,
Map<String, String> indexFieldNameCache,
boolean excludeDeletedEntities,
boolean includeSubTypes) {
this.queryString = queryString;
this.filterCriteria = filterCriteria;
this.searchForEntityType = searchForEntityType;
this.aggregationFieldNames = aggregationFieldNames;
this.aggregationAttributes = aggregationAttributes;
this.indexFieldNameCache = indexFieldNameCache;
this.excludeDeletedEntities = excludeDeletedEntities;
this.includeSubTypes = includeSubTypes;
}
public String getQueryString() {
return queryString;
}
public FilterCriteria getFilterCriteria() {
return filterCriteria;
}
public AtlasEntityType getSearchForEntityType() {
return searchForEntityType;
}
public Set<String> getAggregationFieldNames() {
return aggregationFieldNames;
}
public Set<AtlasAttribute> getAggregationAttributes() {
return aggregationAttributes;
}
public Map<String, String> getIndexFieldNameCache() {
return indexFieldNameCache;
}
public boolean isExcludeDeletedEntities() {
return excludeDeletedEntities;
}
public boolean isIncludeSubTypes() {
return includeSubTypes;
}
}
...@@ -340,13 +340,6 @@ public interface AtlasGraph<V, E> { ...@@ -340,13 +340,6 @@ public interface AtlasGraph<V, E> {
boolean isMultiProperty(String name); boolean isMultiProperty(String name);
/** /**
* return the encoded name used for the attribute identified by property key and index name.
* @param propertyKey the property key of attributed
* @param indexName the name of the index containing the property.
* @return the encoded name of the property.
*/
String getIndexFieldName(AtlasPropertyKey propertyKey, String indexName);
/**
* Create Index query parameter for use with atlas graph. * Create Index query parameter for use with atlas graph.
* @param parameterName the name of the parameter that needs to be passed to index layer. * @param parameterName the name of the parameter that needs to be passed to index layer.
* @param parameterValue the value of the paratemeter that needs to be passed to the index layer. * @param parameterValue the value of the paratemeter that needs to be passed to the index layer.
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
package org.apache.atlas.repository.graphdb; package org.apache.atlas.repository.graphdb;
import org.apache.atlas.model.discovery.AtlasAggregationEntry; import org.apache.atlas.model.discovery.AtlasAggregationEntry;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.type.AtlasEntityType;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -30,11 +32,9 @@ public interface AtlasGraphIndexClient { ...@@ -30,11 +32,9 @@ public interface AtlasGraphIndexClient {
/** /**
* Gets aggregated metrics for the given query string and aggregation field names. * Gets aggregated metrics for the given query string and aggregation field names.
* @param queryString the query string whose aggregation metrics need to be retrieved.
* @param propertyKeyNames the set of aggregation fields.
* @return A map of aggregation field to value-count pairs. * @return A map of aggregation field to value-count pairs.
*/ */
Map<String, List<AtlasAggregationEntry>> getAggregatedMetrics(String queryString, Set<String> propertyKeyNames); Map<String, List<AtlasAggregationEntry>> getAggregatedMetrics(AggregationContext aggregationContext);
/** /**
* Returns top 5 suggestions for the given prefix string. * Returns top 5 suggestions for the given prefix string.
...@@ -46,9 +46,9 @@ public interface AtlasGraphIndexClient { ...@@ -46,9 +46,9 @@ public interface AtlasGraphIndexClient {
/** /**
* The implementers should apply the search weights for the passed in properties. * The implementers should apply the search weights for the passed in properties.
* @param collectionName the name of the collection for which the search weight needs to be applied * @param collectionName the name of the collection for which the search weight needs to be applied
* @param propertyName2SearchWeightMap the map containing search weights from property name to search weights. * @param indexFieldName2SearchWeightMap the map containing search weights from index field name to search weights.
*/ */
void applySearchWeight(String collectionName, Map<String, Integer> propertyName2SearchWeightMap); void applySearchWeight(String collectionName, Map<String, Integer> indexFieldName2SearchWeightMap);
/** /**
* The implementors should take the passed in list of suggestion properties for suggestions functionality. * The implementors should take the passed in list of suggestion properties for suggestions functionality.
......
...@@ -155,8 +155,9 @@ public interface AtlasGraphManagement { ...@@ -155,8 +155,9 @@ public interface AtlasGraphManagement {
* *
* @param vertexIndex * @param vertexIndex
* @param propertyKey * @param propertyKey
* @return the index field name used for the given property
*/ */
void addMixedIndex(String vertexIndex, AtlasPropertyKey propertyKey); String addMixedIndex(String vertexIndex, AtlasPropertyKey propertyKey);
/** /**
* Gets the index field name for the vertex property. * Gets the index field name for the vertex property.
......
...@@ -236,6 +236,12 @@ ...@@ -236,6 +236,12 @@
<classifier>tests</classifier> <classifier>tests</classifier>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
......
...@@ -75,12 +75,13 @@ import static org.apache.atlas.repository.graphdb.janus.AtlasJanusGraphDatabase. ...@@ -75,12 +75,13 @@ import static org.apache.atlas.repository.graphdb.janus.AtlasJanusGraphDatabase.
*/ */
public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusEdge> { public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusEdge> {
private static final Logger LOG = LoggerFactory.getLogger(AtlasJanusGraph.class); private static final Logger LOG = LoggerFactory.getLogger(AtlasJanusGraph.class);
private static Configuration APPLICATION_PROPERTIES = null;
private static final Parameter[] EMPTY_PARAMETER_ARRAY = new Parameter[0];
private static Configuration APPLICATION_PROPERTIES = null;
private final ConvertGremlinValueFunction GREMLIN_VALUE_CONVERSION_FUNCTION = new ConvertGremlinValueFunction(); private final ConvertGremlinValueFunction GREMLIN_VALUE_CONVERSION_FUNCTION = new ConvertGremlinValueFunction();
private final Set<String> multiProperties = new HashSet<>(); private final Set<String> multiProperties = new HashSet<>();
private final StandardJanusGraph janusGraph; private final StandardJanusGraph janusGraph;
private final Parameter[] EMPTY_PARAMETER_ARRAY = new Parameter[0];
public AtlasJanusGraph() { public AtlasJanusGraph() {
this(getGraphInstance()); this(getGraphInstance());
...@@ -198,7 +199,7 @@ public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusE ...@@ -198,7 +199,7 @@ public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusE
try { try {
initApplicationProperties(); initApplicationProperties();
return new AtlasJanusGraphIndexClient(this, APPLICATION_PROPERTIES); return new AtlasJanusGraphIndexClient(APPLICATION_PROPERTIES);
} catch (Exception e) { } catch (Exception e) {
LOG.error("Error encountered in creating Graph Index Client.", e); LOG.error("Error encountered in creating Graph Index Client.", e);
throw new AtlasException(e); throw new AtlasException(e);
...@@ -417,6 +418,13 @@ public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusE ...@@ -417,6 +418,13 @@ public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusE
} }
String getIndexFieldName(AtlasPropertyKey propertyKey, JanusGraphIndex graphIndex) {
PropertyKey janusKey = AtlasJanusObjectFactory.createPropertyKey(propertyKey);
return janusGraph.getIndexSerializer().getDefaultFieldName(janusKey, EMPTY_PARAMETER_ARRAY, graphIndex.getBackingIndex());
}
private String getIndexQueryPrefix() { private String getIndexQueryPrefix() {
final String ret; final String ret;
...@@ -524,9 +532,4 @@ public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusE ...@@ -524,9 +532,4 @@ public class AtlasJanusGraph implements AtlasGraph<AtlasJanusVertex, AtlasJanusE
return convertGremlinValue(input); return convertGremlinValue(input);
} }
} }
public String getIndexFieldName(AtlasPropertyKey propertyKey, String indexName) {
PropertyKey janusKey = AtlasJanusObjectFactory.createPropertyKey(propertyKey);
return janusGraph.getIndexSerializer().getDefaultFieldName(janusKey, EMPTY_PARAMETER_ARRAY, indexName);
}
} }
...@@ -23,10 +23,7 @@ import org.apache.tinkerpop.gremlin.structure.Direction; ...@@ -23,10 +23,7 @@ import org.apache.tinkerpop.gremlin.structure.Direction;
import org.janusgraph.core.Cardinality; import org.janusgraph.core.Cardinality;
import org.janusgraph.core.EdgeLabel; import org.janusgraph.core.EdgeLabel;
import org.janusgraph.core.PropertyKey; import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.schema.Mapping; import org.janusgraph.core.schema.*;
import org.janusgraph.core.schema.PropertyKeyMaker;
import org.janusgraph.core.schema.JanusGraphIndex;
import org.janusgraph.core.schema.JanusGraphManagement;
import org.janusgraph.core.schema.JanusGraphManagement.IndexBuilder; import org.janusgraph.core.schema.JanusGraphManagement.IndexBuilder;
import org.janusgraph.graphdb.internal.Token; import org.janusgraph.graphdb.internal.Token;
import org.apache.atlas.repository.graphdb.AtlasCardinality; import org.apache.atlas.repository.graphdb.AtlasCardinality;
...@@ -195,19 +192,24 @@ public class AtlasJanusGraphManagement implements AtlasGraphManagement { ...@@ -195,19 +192,24 @@ public class AtlasJanusGraphManagement implements AtlasGraphManagement {
} }
@Override @Override
public void addMixedIndex(String indexName, AtlasPropertyKey propertyKey) { public String addMixedIndex(String indexName, AtlasPropertyKey propertyKey) {
PropertyKey janusKey = AtlasJanusObjectFactory.createPropertyKey(propertyKey); PropertyKey janusKey = AtlasJanusObjectFactory.createPropertyKey(propertyKey);
JanusGraphIndex vertexIndex = management.getGraphIndex(indexName); JanusGraphIndex janusGraphIndex = management.getGraphIndex(indexName);
management.addIndexKey(janusGraphIndex, janusKey);
String encodedName = graph.getIndexFieldName(propertyKey, janusGraphIndex);
management.addIndexKey(vertexIndex, janusKey);
String encodedName = graph.getIndexFieldName(propertyKey, vertexIndex.getBackingIndex());
LOG.info("property '{}' is encoded to '{}'.", propertyKey.getName(), encodedName); LOG.info("property '{}' is encoded to '{}'.", propertyKey.getName(), encodedName);
return encodedName;
} }
@Override @Override
public String getIndexFieldName(String indexName, AtlasPropertyKey propertyKey) { public String getIndexFieldName(String indexName, AtlasPropertyKey propertyKey) {
JanusGraphIndex index = management.getGraphIndex(indexName); JanusGraphIndex janusGraphIndex = management.getGraphIndex(indexName);
return graph.getIndexFieldName(propertyKey, index.getBackingIndex());
return graph.getIndexFieldName(propertyKey, janusGraphIndex);
} }
@Override @Override
......
...@@ -20,6 +20,7 @@ package org.apache.atlas.repository.graphdb.janus; ...@@ -20,6 +20,7 @@ package org.apache.atlas.repository.graphdb.janus;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -27,81 +28,99 @@ import java.util.Map; ...@@ -27,81 +28,99 @@ import java.util.Map;
public class AtlasJanusGraphIndexClientTest { public class AtlasJanusGraphIndexClientTest {
@Test @Test
public void testGetTop5TermsAsendingInput() { public void testGetTopTermsAsendingInput() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 12, 15); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 12, 15);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
validateOrder(top5Terms, 2,1,0); assertOrder(top5Terms, 2,1,0);
} }
@Test @Test
public void testGetTop5TermsAsendingInput2() { public void testGetTopTermsAsendingInput2() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 12, 15, 20, 25, 26, 30, 40); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 12, 15, 20, 25, 26, 30, 40);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
validateOrder(top5Terms, 7, 6, 5, 4, 3); assertOrder(top5Terms, 7, 6, 5, 4, 3);
} }
@Test @Test
public void testGetTop5TermsDescendingInput() { public void testGetTopTermsDescendingInput() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 9, 8); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 9, 8);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
validateOrder(top5Terms, 0, 1, 2); assertOrder(top5Terms, 0, 1, 2);
} }
@Test @Test
public void testGetTop5TermsDescendingInput2() { public void testGetTopTermsDescendingInput2() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 9, 8, 7, 6, 5, 4, 3, 2); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 9, 8, 7, 6, 5, 4, 3, 2);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
validateOrder(top5Terms, 0, 1, 2, 3, 4); assertOrder(top5Terms, 0, 1, 2, 3, 4);
} }
@Test @Test
public void testGetTop5TermsRandom() { public void testGetTopTermsRandom() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 19, 28, 27, 16, 1, 30, 3, 36); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 19, 28, 27, 16, 1, 30, 3, 36);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
//10, 19, 28, 27, 16, 1, 30, 3, 36 //10, 19, 28, 27, 16, 1, 30, 3, 36
//0, 1, 2, 3, 4, 5, 6, 7, 8 //0, 1, 2, 3, 4, 5, 6, 7, 8
validateOrder(top5Terms, 8, 6, 2, 3, 1); assertOrder(top5Terms, 8, 6, 2, 3, 1);
} }
@Test @Test
public void testGetTop5TermsRandom2() { public void testGetTopTermsRandom2() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 36, 19, 28, 27, 16, 1, 30, 3, 10); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 36, 19, 28, 27, 16, 1, 30, 3, 10);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
//36, 19, 28, 27, 16, 1, 30, 3, 10 //36, 19, 28, 27, 16, 1, 30, 3, 10
//0, 1, 2, 3, 4, 5, 6, 7, 8 //0, 1, 2, 3, 4, 5, 6, 7, 8
validateOrder(top5Terms, 0, 6, 2, 3, 1); assertOrder(top5Terms, 0, 6, 2, 3, 1);
} }
@Test @Test
public void testGetTop5TermsRandom3() { public void testGetTopTermsRandom3() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 36, 36, 28, 27, 16, 1, 30, 3, 10); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 36, 36, 28, 27, 16, 1, 30, 3, 10);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
//36, 36, 28, 27, 16, 1, 30, 3, 10 //36, 36, 28, 27, 16, 1, 30, 3, 10
//0, 1, 2, 3, 4, 5, 6, 7, 8 //0, 1, 2, 3, 4, 5, 6, 7, 8
validateOrder(top5Terms, 0, 1, 6, 2, 3); assertOrder(top5Terms, 0, 1, 6, 2, 3);
} }
@Test @Test
public void testGetTop5TermsRandom4() { public void testGetTopTermsRandom4() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 10, 28, 27, 16, 1, 30, 36, 36); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 10, 10, 28, 27, 16, 1, 30, 36, 36);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
//10, 10, 28, 27, 16, 1, 30, 36, 36 //10, 10, 28, 27, 16, 1, 30, 36, 36
//0, 1, 2, 3, 4, 5, 6, 7, 8 //0, 1, 2, 3, 4, 5, 6, 7, 8
validateOrder(top5Terms, 7, 8, 6, 2, 3); assertOrder(top5Terms, 7, 8, 6, 2, 3);
} }
@Test @Test
public void testGetTop5TermsRandom5() { public void testGetTopTermsRandom5() {
Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 36, 10, 28, 27, 16, 1, 30, 36, 36); Map<String, AtlasJanusGraphIndexClient.TermFreq> terms = generateTerms( 36, 10, 28, 27, 16, 1, 30, 36, 36);
List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms); List<String> top5Terms = AtlasJanusGraphIndexClient.getTopTerms(terms);
//36, 10, 28, 27, 16, 1, 30, 36, 36 //36, 10, 28, 27, 16, 1, 30, 36, 36
//0, 1, 2, 3, 4, 5, 6, 7, 8 //0, 1, 2, 3, 4, 5, 6, 7, 8
validateOrder(top5Terms, 0, 7, 8, 6, 2); assertOrder(top5Terms, 0, 7, 8, 6, 2);
} }
@Test
public void testGenerateSuggestionString() {
List<String> fields = new ArrayList<>();
fields.add("one");
fields.add("two");
fields.add("three");
String generatedString = AtlasJanusGraphIndexClient.generateSuggestionsString(fields);
Assert.assertEquals(generatedString, "'one', 'two', 'three'");
}
@Test
public void testGenerateSearchWeightString() {
Map<String, Integer> fields = new HashMap<>();
fields.put("one", 10);
fields.put("two", 1);
fields.put("three", 15);
String generatedString = AtlasJanusGraphIndexClient.generateSearchWeightString(fields);
Assert.assertEquals(generatedString, " one^10 two^1 three^15");
}
private void validateOrder(List<String> topTerms, int ... indices) { private void assertOrder(List<String> topTerms, int ... indices) {
Assert.assertEquals(topTerms.size(), indices.length); Assert.assertEquals(topTerms.size(), indices.length);
int i = 0; int i = 0;
for(String term: topTerms) { for(String term: topTerms) {
......
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"AND",
"criterion":[
{
"attributeName":"comment",
"operator":"contains",
"attributeValue":"United States"
},
{
"attributeName":"description",
"operator":"contains",
"attributeValue":"nothing"
},
{
"attributeName":"name",
"operator":"contains",
"attributeValue":"t100"
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t10",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"AND",
"criterion":[
{
"attributeName":"created",
"operator":"gt",
"attributeValue":"100"
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t10",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"AND",
"criterion":[
{
"attributeName":"created",
"operator":"gte",
"attributeValue":100
},
{
"attributeName":"started",
"operator":"gte",
"attributeValue": 100
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t10",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"AND",
"criterion":[
{
"attributeName":"created",
"operator":"lt",
"attributeValue":"100"
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t10",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"AND",
"criterion":[
{
"attributeName":"created",
"operator":"lte",
"attributeValue":"100"
},
{
"attributeName":"started",
"operator":"lte",
"attributeValue": 100
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t10",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":
{
"condition":"AND",
"criterion":
[
{
"attributeName":"qualifiedName",
"operator":"startsWith",
"attributeValue":"testdb.t1"
}
]
},
"tagFilters":null,
"limit":25,
"offset":0,
"typeName":"hive_table"
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"attributeName":"name",
"operator":"eq",
"attributeValue":"t10"
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"AND",
"criterion":[
{
"attributeName":"name",
"operator":"eq",
"attributeValue":"t10"
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"OR",
"criterion":[
{
"attributeName":"name",
"operator":"eq",
"attributeValue":"t10"
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
\ No newline at end of file
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"AND",
"criterion":[
{
"attributeName":"name",
"operator":"eq",
"attributeValue":"t10"
},
{
"attributeName":"comment",
"operator":"contains",
"attributeValue":"t10"
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
{
"excludeDeletedEntities":true,
"includeSubClassifications":true,
"includeSubTypes":true,
"includeClassificationAttributes":true,
"entityFilters":{
"condition":"OR",
"criterion":[
{
"attributeName":"name",
"operator":"eq",
"attributeValue":"t10"
},
{
"attributeName":"comment",
"operator":"contains",
"attributeValue":"t10"
}
]
},
"tagFilters":null,
"attributes":[
"comment"
],
"query":"t",
"limit":25,
"offset":0,
"typeName":"hive_table",
"classification":null,
"termName":null
}
...@@ -21,4 +21,5 @@ import org.apache.atlas.exception.AtlasBaseException; ...@@ -21,4 +21,5 @@ import org.apache.atlas.exception.AtlasBaseException;
public interface TypeDefChangeListener { public interface TypeDefChangeListener {
void onChange(ChangedTypeDefs changedTypeDefs) throws AtlasBaseException; void onChange(ChangedTypeDefs changedTypeDefs) throws AtlasBaseException;
void onLoadCompletion() throws AtlasBaseException;
} }
/**
* 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.discovery;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.apache.atlas.model.discovery.SearchParameters.FilterCriteria;
import java.io.Serializable;
import java.util.Set;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
/**
* This is the root class representing the input for quick search puroposes.
*/
public class QuickSearchParameters implements Serializable {
private static final long serialVersionUID = 1L;
private String query;
private String typeName;
private FilterCriteria entityFilters;
private boolean includeSubTypes;
private boolean excludeDeletedEntities;
private int offset;
private int limit;
private Set<String> attributes;
/**
* for framework use.
*/
public QuickSearchParameters() {
}
public QuickSearchParameters(String query,
String typeName,
FilterCriteria entityFilters,
boolean includeSubTypes,
boolean excludeDeletedEntities,
int offset,
int limit,
Set<String> attributes) {
this.query = query;
this.typeName = typeName;
this.entityFilters = entityFilters;
this.includeSubTypes = includeSubTypes;
this.excludeDeletedEntities = excludeDeletedEntities;
this.offset = offset;
this.limit = limit;
this.attributes = attributes;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public FilterCriteria getEntityFilters() {
return entityFilters;
}
public void setEntityFilters(FilterCriteria entityFilters) {
this.entityFilters = entityFilters;
}
public boolean getIncludeSubTypes() {
return includeSubTypes;
}
public void setIncludeSubTypes(boolean includeSubTypes) {
this.includeSubTypes = includeSubTypes;
}
public boolean getExcludeDeletedEntities() {
return excludeDeletedEntities;
}
public void setExcludeDeletedEntities(boolean excludeDeletedEntities) {
this.excludeDeletedEntities = excludeDeletedEntities;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public Set<String> getAttributes() {
return attributes;
}
public void setAttributes(Set<String> attributes) {
this.attributes = attributes;
}
}
...@@ -106,4 +106,6 @@ public interface AtlasTypeDefStore { ...@@ -106,4 +106,6 @@ public interface AtlasTypeDefStore {
AtlasBaseTypeDef getByGuid(String guid) throws AtlasBaseException; AtlasBaseTypeDef getByGuid(String guid) throws AtlasBaseException;
void deleteTypeByName(String typeName) throws AtlasBaseException; void deleteTypeByName(String typeName) throws AtlasBaseException;
void notifyLoadCompletion();
} }
...@@ -33,10 +33,8 @@ import org.slf4j.LoggerFactory; ...@@ -33,10 +33,8 @@ import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
import static org.apache.atlas.model.TypeCategory.*; import static org.apache.atlas.model.TypeCategory.OBJECT_ID_TYPE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE; import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.*;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF;
/** /**
* class that implements behaviour of a struct-type. * class that implements behaviour of a struct-type.
...@@ -710,6 +708,7 @@ public class AtlasStructType extends AtlasType { ...@@ -710,6 +708,7 @@ public class AtlasStructType extends AtlasType {
private String relationshipEdgeLabel; private String relationshipEdgeLabel;
private AtlasRelationshipEdgeDirection relationshipEdgeDirection; private AtlasRelationshipEdgeDirection relationshipEdgeDirection;
private boolean isLegacyAttribute; private boolean isLegacyAttribute;
private String indexFieldName;
public AtlasAttribute(AtlasStructType definedInType, AtlasAttributeDef attrDef, AtlasType attributeType, String relationshipName, String relationshipLabel) { public AtlasAttribute(AtlasStructType definedInType, AtlasAttributeDef attrDef, AtlasType attributeType, String relationshipName, String relationshipLabel) {
this.definedInType = definedInType; this.definedInType = definedInType;
...@@ -821,6 +820,13 @@ public class AtlasStructType extends AtlasType { ...@@ -821,6 +820,13 @@ public class AtlasStructType extends AtlasType {
public void setLegacyAttribute(boolean legacyAttribute) { isLegacyAttribute = legacyAttribute; } public void setLegacyAttribute(boolean legacyAttribute) { isLegacyAttribute = legacyAttribute; }
public String getIndexFieldName() { return indexFieldName; }
public void setIndexFieldName(String indexFieldName) { this.indexFieldName = indexFieldName; }
public int getSearchWeight() { return attributeDef.getSearchWeight(); }
public static String getEdgeLabel(String property) { public static String getEdgeLabel(String property) {
return "__" + property; return "__" + property;
} }
......
...@@ -33,13 +33,7 @@ import org.slf4j.LoggerFactory; ...@@ -33,13 +33,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
...@@ -57,19 +51,22 @@ public class AtlasTypeRegistry { ...@@ -57,19 +51,22 @@ public class AtlasTypeRegistry {
protected RegistryData registryData; protected RegistryData registryData;
private final TypeRegistryUpdateSynchronizer updateSynchronizer; private final TypeRegistryUpdateSynchronizer updateSynchronizer;
private final Set<String> missingRelationshipDefs; private final Set<String> missingRelationshipDefs;
private final Map<String, String> commonIndexFieldNameCache;
public AtlasTypeRegistry() { public AtlasTypeRegistry() {
registryData = new RegistryData(); registryData = new RegistryData();
updateSynchronizer = new TypeRegistryUpdateSynchronizer(this); updateSynchronizer = new TypeRegistryUpdateSynchronizer(this);
missingRelationshipDefs = new HashSet<>(); missingRelationshipDefs = new HashSet<>();
commonIndexFieldNameCache = new HashMap<>();
} }
// used only by AtlasTransientTypeRegistry // used only by AtlasTransientTypeRegistry
protected AtlasTypeRegistry(AtlasTypeRegistry other) { protected AtlasTypeRegistry(AtlasTypeRegistry other) {
registryData = new RegistryData(); registryData = new RegistryData();
updateSynchronizer = other.updateSynchronizer; updateSynchronizer = other.updateSynchronizer;
missingRelationshipDefs = other.missingRelationshipDefs; missingRelationshipDefs = other.missingRelationshipDefs;
commonIndexFieldNameCache = other.commonIndexFieldNameCache;
} }
public Collection<String> getAllTypeNames() { return registryData.allTypes.getAllTypeNames(); } public Collection<String> getAllTypeNames() { return registryData.allTypes.getAllTypeNames(); }
...@@ -240,6 +237,19 @@ public class AtlasTypeRegistry { ...@@ -240,6 +237,19 @@ public class AtlasTypeRegistry {
} }
} }
public void addIndexFieldName(String propertyName, String indexFieldName) {
commonIndexFieldNameCache.put(propertyName, indexFieldName);
}
/**
* retrieves the index field name for the common field passed in.
* @param propertyName the name of the common field.
* @return the index name for the common field passed in.
*/
public String getIndexFieldName(String propertyName) {
return commonIndexFieldNameCache.get(propertyName);
}
static class RegistryData { static class RegistryData {
final TypeCache allTypes; final TypeCache allTypes;
final TypeDefCache<AtlasEnumDef, AtlasEnumType> enumDefs; final TypeDefCache<AtlasEnumDef, AtlasEnumType> enumDefs;
...@@ -1163,4 +1173,5 @@ class TypeDefCache<T1 extends AtlasBaseTypeDef, T2 extends AtlasType> { ...@@ -1163,4 +1173,5 @@ class TypeDefCache<T1 extends AtlasBaseTypeDef, T2 extends AtlasType> {
typeDefNameMap.clear(); typeDefNameMap.clear();
typeNameMap.clear(); typeNameMap.clear();
} }
} }
...@@ -19,12 +19,10 @@ ...@@ -19,12 +19,10 @@
package org.apache.atlas.discovery; package org.apache.atlas.discovery;
import com.sun.xml.bind.v2.model.annotation.Quick;
import org.apache.atlas.SortOrder; import org.apache.atlas.SortOrder;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasQuickSearchResult; import org.apache.atlas.model.discovery.*;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSuggestionsResult;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.profile.AtlasUserSavedSearch; import org.apache.atlas.model.profile.AtlasUserSavedSearch;
import java.util.List; import java.util.List;
...@@ -142,7 +140,13 @@ public interface AtlasDiscoveryService { ...@@ -142,7 +140,13 @@ public interface AtlasDiscoveryService {
*/ */
void deleteSavedSearch(String currentUser, String guid) throws AtlasBaseException; void deleteSavedSearch(String currentUser, String guid) throws AtlasBaseException;
AtlasQuickSearchResult quickSearchWithParameters(SearchParameters searchParameters) throws AtlasBaseException; /**
* Search for entities matching the search criteria
* @param searchParameters Search criteria
* @return Matching entities
* @throws AtlasBaseException
*/
AtlasQuickSearchResult quickSearch(QuickSearchParameters searchParameters) throws AtlasBaseException;
/** /**
* Should return top 5 suggestion strings for the given prefix. * Should return top 5 suggestion strings for the given prefix.
......
...@@ -26,14 +26,10 @@ import org.apache.atlas.annotation.GraphTransaction; ...@@ -26,14 +26,10 @@ import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.authorize.AtlasAuthorizationUtils; import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasSearchResultScrubRequest; import org.apache.atlas.authorize.AtlasSearchResultScrubRequest;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasQuickSearchResult; import org.apache.atlas.model.discovery.*;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult; 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.AtlasSuggestionsResult;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.discovery.AtlasAggregationEntry;
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.model.profile.AtlasUserSavedSearch;
...@@ -43,20 +39,14 @@ import org.apache.atlas.query.QueryParams; ...@@ -43,20 +39,14 @@ import org.apache.atlas.query.QueryParams;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graph.GraphBackedSearchIndexer; import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
import org.apache.atlas.repository.graph.GraphHelper; import org.apache.atlas.repository.graph.GraphHelper;
import org.apache.atlas.repository.graphdb.AtlasGraph; import org.apache.atlas.repository.graphdb.*;
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.store.graph.v2.AtlasGraphUtilsV2; import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever; import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
import org.apache.atlas.repository.userprofile.UserProfileService; import org.apache.atlas.repository.userprofile.UserProfileService;
import org.apache.atlas.type.AtlasArrayType; import org.apache.atlas.type.*;
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.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;
...@@ -80,6 +70,7 @@ import static org.apache.atlas.SortOrder.ASCENDING; ...@@ -80,6 +70,7 @@ 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.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.Constants.*;
import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.*; import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.*;
@Component @Component
...@@ -102,7 +93,9 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -102,7 +93,9 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
@Inject @Inject
EntityDiscoveryService(AtlasTypeRegistry typeRegistry, EntityDiscoveryService(AtlasTypeRegistry typeRegistry,
AtlasGraph graph, GraphBackedSearchIndexer indexer, SearchTracker searchTracker, AtlasGraph graph,
GraphBackedSearchIndexer indexer,
SearchTracker searchTracker,
UserProfileService userProfileService) throws AtlasException { UserProfileService userProfileService) throws AtlasException {
this.graph = graph; this.graph = graph;
this.entityRetriever = new EntityGraphRetriever(typeRegistry); this.entityRetriever = new EntityGraphRetriever(typeRegistry);
...@@ -421,8 +414,11 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -421,8 +414,11 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
@Override @Override
@GraphTransaction @GraphTransaction
public AtlasQuickSearchResult quickSearchWithParameters(SearchParameters searchParameters) throws AtlasBaseException { public AtlasQuickSearchResult quickSearch(QuickSearchParameters quickSearchParameters) throws AtlasBaseException {
SearchContext searchContext = new SearchContext(searchParameters, typeRegistry, graph, indexer.getVertexIndexKeys()); SearchContext searchContext = new SearchContext(createSearchParameters(quickSearchParameters),
typeRegistry,
graph,
indexer.getVertexIndexKeys());
if(LOG.isDebugEnabled()) { if(LOG.isDebugEnabled()) {
LOG.debug("Generating the search results for the query {} .", searchContext.getSearchParameters().getQuery()); LOG.debug("Generating the search results for the query {} .", searchContext.getSearchParameters().getQuery());
...@@ -434,9 +430,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -434,9 +430,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
LOG.debug("Generating the aggregated metrics for the query {} .", searchContext.getSearchParameters().getQuery()); LOG.debug("Generating the aggregated metrics for the query {} .", searchContext.getSearchParameters().getQuery());
} }
SearchAggregator searchAggregator = new SearchAggregatorImpl(searchContext); // load the facet fields and attributes.
Map<String, List<AtlasAggregationEntry>> aggregatedMetrics = searchAggregator.getAggregatedMetrics(); Set<String> aggregationFields = getAggregationFields();
AtlasQuickSearchResult ret = new AtlasQuickSearchResult(searchResult, aggregatedMetrics); Set<AtlasAttribute> aggregationAttributes = getAggregationAtlasAttributes();
SearchAggregator searchAggregator = new SearchAggregatorImpl(searchContext);
Map<String, List<AtlasAggregationEntry>> aggregatedMetrics = searchAggregator.getAggregatedMetrics(aggregationFields, aggregationAttributes);
AtlasQuickSearchResult ret = new AtlasQuickSearchResult(searchResult, aggregatedMetrics);
return ret; return ret;
} }
...@@ -946,6 +945,21 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -946,6 +945,21 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
return queryStr; return queryStr;
} }
public static SearchParameters createSearchParameters(QuickSearchParameters quickSearchParameters) {
SearchParameters searchParameters = new SearchParameters();
searchParameters.setQuery(quickSearchParameters.getQuery());
searchParameters.setTypeName(quickSearchParameters.getTypeName());
searchParameters.setExcludeDeletedEntities(quickSearchParameters.getExcludeDeletedEntities());
searchParameters.setIncludeSubTypes(quickSearchParameters.getIncludeSubTypes());
searchParameters.setLimit(quickSearchParameters.getLimit());
searchParameters.setOffset(quickSearchParameters.getOffset());
searchParameters.setEntityFilters(quickSearchParameters.getEntityFilters());
searchParameters.setAttributes(quickSearchParameters.getAttributes());
return searchParameters;
}
private String escapeTypeName(String typeName) { private String escapeTypeName(String typeName) {
String ret; String ret;
...@@ -968,4 +982,36 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { ...@@ -968,4 +982,36 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
private void scrubSearchResults(AtlasSearchResult result) throws AtlasBaseException { private void scrubSearchResults(AtlasSearchResult result) throws AtlasBaseException {
AtlasAuthorizationUtils.scrubSearchResults(new AtlasSearchResultScrubRequest(typeRegistry, result)); AtlasAuthorizationUtils.scrubSearchResults(new AtlasSearchResultScrubRequest(typeRegistry, result));
} }
private Set<String> getAggregationFields() {
Set<String> ret = new HashSet<>(); // for non-modeled attributes.
ret.add(Constants.ENTITY_TYPE_PROPERTY_KEY);
ret.add(Constants.STATE_PROPERTY_KEY);
return ret;
}
private Set<AtlasAttribute> getAggregationAtlasAttributes() {
Set<AtlasAttribute> ret = new HashSet<>(); // for modeled attributes, like Asset.owner
ret.add(getAtlasAttributeForAssetOwner());
return ret;
}
private AtlasAttribute getAtlasAttributeForAssetOwner() {
AtlasEntityType typeAsset = typeRegistry.getEntityTypeByName(ASSET_ENTITY_TYPE);
AtlasAttribute atttOwner = typeAsset != null ? typeAsset.getAttribute(OWNER_ATTRIBUTE) : null;
if(atttOwner == null) {
String msg = String.format("Unable to resolve the attribute %s.%s", ASSET_ENTITY_TYPE, OWNER_ATTRIBUTE);
LOG.error(msg);
throw new RuntimeException(msg);
}
return atttOwner;
}
} }
...@@ -18,10 +18,22 @@ ...@@ -18,10 +18,22 @@
package org.apache.atlas.discovery; package org.apache.atlas.discovery;
import org.apache.atlas.model.discovery.AtlasAggregationEntry; import org.apache.atlas.model.discovery.AtlasAggregationEntry;
import org.apache.atlas.type.AtlasStructType;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/**
* This is an interface to search aggregation mwntrics providers.
*/
public interface SearchAggregator { public interface SearchAggregator {
Map<String, List<AtlasAggregationEntry>> getAggregatedMetrics(); /**
* returns aggregation metrics for passed in aggregation fields.
* @param aggregationFields the set of aggregation attribute names.
* @param aggregationAttrbutes the set of aggregationAttributes
* @return the result of aggreggations by aggregation fields.
*/
Map<String, List<AtlasAggregationEntry>> getAggregatedMetrics(Set<String> aggregationFields,
Set<AtlasStructType.AtlasAttribute> aggregationAttrbutes);
} }
...@@ -19,10 +19,15 @@ package org.apache.atlas.discovery; ...@@ -19,10 +19,15 @@ package org.apache.atlas.discovery;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.model.discovery.AtlasAggregationEntry; import org.apache.atlas.model.discovery.AtlasAggregationEntry;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.AggregationContext;
import org.apache.atlas.repository.graphdb.AtlasGraph; import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasGraphIndexClient;
import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -34,31 +39,66 @@ public class SearchAggregatorImpl implements SearchAggregator { ...@@ -34,31 +39,66 @@ public class SearchAggregatorImpl implements SearchAggregator {
private final SearchContext searchContext; private final SearchContext searchContext;
public SearchAggregatorImpl(SearchContext searchContext) { public SearchAggregatorImpl(SearchContext searchContext) {
this.searchContext = searchContext; this.searchContext = searchContext;
} }
public Map<String, List<AtlasAggregationEntry>> getAggregatedMetrics() { public Map<String, List<AtlasAggregationEntry>> getAggregatedMetrics(Set<String> aggregationFields,
String queryString = searchContext.getSearchParameters().getQuery(); Set<AtlasAttribute> aggregationAttributes) {
AtlasGraph atlasGraph = searchContext.getGraph(); SearchParameters searchParameters = searchContext.getSearchParameters();
Set<String> aggregationFields = new HashSet<>(); AtlasGraph graph = searchContext.getGraph();
List<PostProcessor> postProcessors = new ArrayList<>(); AtlasTypeRegistry typeRegistry = searchContext.getTypeRegistry();
String queryString = searchParameters.getQuery();
aggregationFields.add(Constants.ENTITY_TYPE_PROPERTY_KEY); List<PostProcessor> postProcessors = new ArrayList<>();
aggregationFields.add(Constants.ASSET_OWNER_PROPERTY_KEY);
postProcessors.add(new ServiceTypeAggregator(searchContext.getTypeRegistry())); postProcessors.add(new ServiceTypeAggregator(searchContext.getTypeRegistry()));
try { try {
Map<String, List<AtlasAggregationEntry>> aggregatedMetrics = atlasGraph.getGraphIndexClient().getAggregatedMetrics(queryString, aggregationFields); AtlasGraphIndexClient graphIndexClient = graph.getGraphIndexClient();
Set<String> aggregationMetricNames = aggregatedMetrics.keySet(); String searchedOnTypeName = searchParameters.getTypeName();
AtlasEntityType searchForEntityType = null;
if (searchedOnTypeName != null) {
searchForEntityType = typeRegistry.getEntityTypeByName(searchedOnTypeName);
}
Map<String, String> indexFieldNameCache = new HashMap<>();
for (String fieldName: aggregationFields) {
String indexFieldName = getIndexFieldNameForCommonFieldName(typeRegistry, fieldName);
indexFieldNameCache.put(fieldName, indexFieldName);
}
for (AtlasAttribute attribute: aggregationAttributes) {
String indexFieldName = attribute.getIndexFieldName();
for(String aggregationMetricName: aggregationMetricNames) { if (indexFieldName == null) {
for(PostProcessor postProcessor: postProcessors) { //there is no index field name.
if(postProcessor.needsProcessing(aggregationMetricName)) { indexFieldName = attribute.getQualifiedName();
}
indexFieldNameCache.put(attribute.getQualifiedName(), indexFieldName);
}
AggregationContext aggregatorContext = new AggregationContext(queryString,
searchParameters.getEntityFilters(),
searchForEntityType,
aggregationFields,
aggregationAttributes,
indexFieldNameCache,
searchParameters.getExcludeDeletedEntities(),
searchParameters.getIncludeSubTypes());
Map<String, List<AtlasAggregationEntry>> aggregatedMetrics = graphIndexClient.getAggregatedMetrics(aggregatorContext);
for (String aggregationMetricName: aggregatedMetrics.keySet()) {
for (PostProcessor postProcessor: postProcessors) {
if (postProcessor.needsProcessing(aggregationMetricName)) {
postProcessor.prepareForMetric(aggregationMetricName); postProcessor.prepareForMetric(aggregationMetricName);
for(AtlasAggregationEntry aggregationEntry: aggregatedMetrics.get(aggregationMetricName)) { for (AtlasAggregationEntry aggregationEntry: aggregatedMetrics.get(aggregationMetricName)) {
postProcessor.process(aggregationEntry); postProcessor.process(aggregationEntry);
} }
...@@ -67,21 +107,10 @@ public class SearchAggregatorImpl implements SearchAggregator { ...@@ -67,21 +107,10 @@ public class SearchAggregatorImpl implements SearchAggregator {
} }
} }
for(PostProcessor postProcessor: postProcessors) { for (PostProcessor postProcessor: postProcessors) {
postProcessor.handleCompletion(aggregatedMetrics); postProcessor.handleCompletion(aggregatedMetrics);
} }
// remove entries with 0 counts
for (List<AtlasAggregationEntry> entries : aggregatedMetrics.values()) {
for (ListIterator<AtlasAggregationEntry> iter = entries.listIterator(); iter.hasNext(); ) {
AtlasAggregationEntry entry = iter.next();
if (entry.getCount() <= 0) {
iter.remove();
}
}
}
return aggregatedMetrics; return aggregatedMetrics;
} catch (AtlasException e) { } catch (AtlasException e) {
LOG.error("Error encountered in post processing stage of aggrgation metrics collection. Empty metrics will be returned.", e); LOG.error("Error encountered in post processing stage of aggrgation metrics collection. Empty metrics will be returned.", e);
...@@ -90,6 +119,20 @@ public class SearchAggregatorImpl implements SearchAggregator { ...@@ -90,6 +119,20 @@ public class SearchAggregatorImpl implements SearchAggregator {
} }
} }
private String getIndexFieldNameForCommonFieldName(AtlasTypeRegistry typeRegistry, String fieldName) {
String indexFieldName = typeRegistry.getIndexFieldName(fieldName);
if(indexFieldName != null) {
return indexFieldName;
}
if(LOG.isDebugEnabled()) {
LOG.debug("Could not find index field name from type registry for attribute {}. Will use use the field name as is.", fieldName);
}
return fieldName;
}
static interface PostProcessor { static interface PostProcessor {
boolean needsProcessing(String metricName); boolean needsProcessing(String metricName);
void prepareForMetric(String metricName); void prepareForMetric(String metricName);
...@@ -102,8 +145,8 @@ public class SearchAggregatorImpl implements SearchAggregator { ...@@ -102,8 +145,8 @@ public class SearchAggregatorImpl implements SearchAggregator {
private static final String SERVICE_TYPE = "ServiceType"; private static final String SERVICE_TYPE = "ServiceType";
private final AtlasTypeRegistry typeRegistry; private final AtlasTypeRegistry typeRegistry;
private List<AtlasAggregationEntry> entries; private final List<AtlasAggregationEntry> entries = new ArrayList<>();;
private Map<String, AtlasAggregationEntry> entityType2MetricsMap; private final Map<String, AtlasAggregationEntry> entityType2MetricsMap = new HashMap<>();
public ServiceTypeAggregator(AtlasTypeRegistry typeRegistry) { public ServiceTypeAggregator(AtlasTypeRegistry typeRegistry) {
this.typeRegistry = typeRegistry; this.typeRegistry = typeRegistry;
...@@ -118,8 +161,6 @@ public class SearchAggregatorImpl implements SearchAggregator { ...@@ -118,8 +161,6 @@ public class SearchAggregatorImpl implements SearchAggregator {
public void prepareForMetric(String metricName) { public void prepareForMetric(String metricName) {
Map<String, AtlasAggregationEntry> serviceName2MetricsMap = new HashMap<>(); Map<String, AtlasAggregationEntry> serviceName2MetricsMap = new HashMap<>();
entries = new ArrayList<>();
//prepare the service map to aggregations //prepare the service map to aggregations
for(String serviceName: typeRegistry.getAllServiceTypes()) { for(String serviceName: typeRegistry.getAllServiceTypes()) {
AtlasAggregationEntry serviceMetrics = new AtlasAggregationEntry(serviceName, 0); AtlasAggregationEntry serviceMetrics = new AtlasAggregationEntry(serviceName, 0);
...@@ -130,8 +171,6 @@ public class SearchAggregatorImpl implements SearchAggregator { ...@@ -130,8 +171,6 @@ public class SearchAggregatorImpl implements SearchAggregator {
} }
//prepare the map from entity type to aggregations //prepare the map from entity type to aggregations
entityType2MetricsMap = new HashMap<>();
for(AtlasEntityType entityType: typeRegistry.getAllEntityTypes()) { for(AtlasEntityType entityType: typeRegistry.getAllEntityTypes()) {
String serviceName = entityType.getServiceType(); String serviceName = entityType.getServiceType();
...@@ -157,7 +196,16 @@ public class SearchAggregatorImpl implements SearchAggregator { ...@@ -157,7 +196,16 @@ public class SearchAggregatorImpl implements SearchAggregator {
@Override @Override
public void handleCompletion(Map<String, List<AtlasAggregationEntry>> aggregatedMetrics) { public void handleCompletion(Map<String, List<AtlasAggregationEntry>> aggregatedMetrics) {
aggregatedMetrics.put(SERVICE_TYPE, entries); //remove all zero count entries.
for (int i = entries.size() - 1; i >= 0; i--) {
if (entries.get(i).getCount() == 0) {
entries.remove(i);
}
}
if (CollectionUtils.isNotEmpty(entries)) {
aggregatedMetrics.put(SERVICE_TYPE, entries);
}
} }
} }
} }
...@@ -19,14 +19,15 @@ package org.apache.atlas.repository.graph; ...@@ -19,14 +19,15 @@ package org.apache.atlas.repository.graph;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.listener.ChangedTypeDefs; import org.apache.atlas.listener.ChangedTypeDefs;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.AtlasGraph; import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasGraphIndexClient; import org.apache.atlas.repository.graphdb.AtlasGraphIndexClient;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.util.AtlasRepositoryConfiguration; import org.apache.atlas.util.AtlasRepositoryConfiguration;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -65,13 +66,12 @@ public class SolrIndexHelper implements IndexChangeListener { ...@@ -65,13 +66,12 @@ public class SolrIndexHelper implements IndexChangeListener {
} }
try { try {
AtlasGraph atlasGraph = AtlasGraphProvider.getGraphInstance(); AtlasGraph graph = AtlasGraphProvider.getGraphInstance();
AtlasGraphIndexClient atlasGraphIndexClient = atlasGraph.getGraphIndexClient(); AtlasGraphIndexClient graphIndexClient = graph.getGraphIndexClient();
Map<String, Integer> propertyName2SearchWeightMap = gePropertiesWithSearchWeights(); Map<String, Integer> propertyName2SearchWeightMap = gePropertiesWithSearchWeights();
atlasGraphIndexClient.applySearchWeight(Constants.VERTEX_INDEX, propertyName2SearchWeightMap); graphIndexClient.applySearchWeight(Constants.VERTEX_INDEX, propertyName2SearchWeightMap);
atlasGraphIndexClient.applySuggestionFields(Constants.VERTEX_INDEX, getPropertiesForSuggestions(propertyName2SearchWeightMap)); graphIndexClient.applySuggestionFields(Constants.VERTEX_INDEX, getPropertiesForSuggestions(propertyName2SearchWeightMap));
} catch (AtlasException e) { } catch (AtlasException e) {
LOG.error("Error encountered in handling type system change notification.", e); LOG.error("Error encountered in handling type system change notification.", e);
throw new RuntimeException("Error encountered in handling type system change notification.", e); throw new RuntimeException("Error encountered in handling type system change notification.", e);
...@@ -79,7 +79,7 @@ public class SolrIndexHelper implements IndexChangeListener { ...@@ -79,7 +79,7 @@ public class SolrIndexHelper implements IndexChangeListener {
} }
private List<String> getPropertiesForSuggestions(Map<String, Integer> propertyName2SearchWeightMap) { private List<String> getPropertiesForSuggestions(Map<String, Integer> propertyName2SearchWeightMap) {
List<String> propertiesForSuggestions = new ArrayList<>(); List<String> ret = new ArrayList<>();
for(Map.Entry<String, Integer> entry: propertyName2SearchWeightMap.entrySet()) { for(Map.Entry<String, Integer> entry: propertyName2SearchWeightMap.entrySet()) {
if(entry.getValue().intValue() >= MIN_SEARCH_WEIGHT_FOR_SUGGESTIONS) { if(entry.getValue().intValue() >= MIN_SEARCH_WEIGHT_FOR_SUGGESTIONS) {
...@@ -89,55 +89,64 @@ public class SolrIndexHelper implements IndexChangeListener { ...@@ -89,55 +89,64 @@ public class SolrIndexHelper implements IndexChangeListener {
LOG.debug("Adding the property {} for suggestions.", propertyName); LOG.debug("Adding the property {} for suggestions.", propertyName);
} }
propertiesForSuggestions.add(propertyName); ret.add(propertyName);
} }
} }
return propertiesForSuggestions; return ret;
} }
private Map<String, Integer> gePropertiesWithSearchWeights() { private Map<String, Integer> gePropertiesWithSearchWeights() {
Map<String, Integer> propertiesWithSearchWeights = new HashMap<>(); Map<String, Integer> ret = new HashMap<>();
Collection<AtlasEntityDef> allEntityDefs = typeRegistry.getAllEntityDefs(); Collection<AtlasEntityType> entityTypes = typeRegistry.getAllEntityTypes();
//the following two properties are specially added manually.
//as, they don't come in the entity definitions as attributes.
propertiesWithSearchWeights.put(CLASSIFICATION_TEXT_KEY, SEARCHWEIGHT_FOR_CLASSIFICATIONS); ret.put(typeRegistry.getIndexFieldName(CLASSIFICATION_TEXT_KEY), SEARCHWEIGHT_FOR_CLASSIFICATIONS);
propertiesWithSearchWeights.put(TYPE_NAME_PROPERTY_KEY, SEARCHWEIGHT_FOR_TYPENAME); ret.put(typeRegistry.getIndexFieldName(TYPE_NAME_PROPERTY_KEY), SEARCHWEIGHT_FOR_TYPENAME);
if (CollectionUtils.isNotEmpty(allEntityDefs)) { if (CollectionUtils.isNotEmpty(entityTypes)) {
for (AtlasEntityDef entityDef : allEntityDefs) { for (AtlasEntityType entityType : entityTypes) {
processEntity(propertiesWithSearchWeights, entityDef); processEntityType(ret, entityType);
} }
} }
return propertiesWithSearchWeights; return ret;
} }
private void processEntity(Map<String, Integer> propertiesWithSearchWeights, AtlasEntityDef entityDef) { private void processEntityType(Map<String, Integer> indexFieldNameWithSearchWeights, AtlasEntityType entityType) {
for (AtlasAttributeDef attributeDef : entityDef.getAttributeDefs()) { Map<String, AtlasAttribute> attributes = entityType.getAllAttributes();
processAttributeDefinition(propertiesWithSearchWeights, entityDef, attributeDef);
if(MapUtils.isNotEmpty(attributes)) {
for (AtlasAttribute attribute : attributes.values()) {
processAttribute(indexFieldNameWithSearchWeights, attribute);
}
} else {
LOG.debug("No attributes are defined for entity {}", entityType.getTypeName());
} }
} }
private void processAttributeDefinition(Map<String, Integer> propertiesWithSearchWeights, AtlasEntityDef entityDef, AtlasAttributeDef attributeDef) { private void processAttribute(Map<String, Integer> indexFieldNameWithSearchWeights, AtlasAttribute attribute) {
if (GraphBackedSearchIndexer.isStringAttribute(attributeDef)) { if (GraphBackedSearchIndexer.isStringAttribute(attribute)) {
final String propertyName = GraphBackedSearchIndexer.getEncodedPropertyName(entityDef.getName(), attributeDef); int searchWeight = attribute.getSearchWeight();
int searchWeight = attributeDef.getSearchWeight();
if (searchWeight == DEFAULT_SEARCHWEIGHT) { if (searchWeight == DEFAULT_SEARCHWEIGHT) {
//We will use default search weight of 3 for string attributes. //We will use default search weight of 3 for string attributes.
//this will make the string data searchable like in FullTextIndex Searcher using Free Text searcher. //this will make the string data searchable like in FullTextIndex Searcher using Free Text searcher.
searchWeight = DEFAULT_SEARCHWEIGHT_FOR_STRINGS; searchWeight = DEFAULT_SEARCHWEIGHT_FOR_STRINGS;
} else if (!GraphBackedSearchIndexer.isValidSearchWeight(searchWeight)) { //validate the value provided in the model. } else if (!GraphBackedSearchIndexer.isValidSearchWeight(searchWeight)) { //validate the value provided in the model.
LOG.warn("Invalid search weight {} for attribute {}.{}. Will use default {}", searchWeight, entityDef.getName(), propertyName, DEFAULT_SEARCHWEIGHT_FOR_STRINGS); LOG.warn("Invalid search weight {} for attribute {}. Will use default {}",
searchWeight, attribute.getQualifiedName(), DEFAULT_SEARCHWEIGHT_FOR_STRINGS);
searchWeight = DEFAULT_SEARCHWEIGHT_FOR_STRINGS; searchWeight = DEFAULT_SEARCHWEIGHT_FOR_STRINGS;
} }
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Applying search weight {} for attribute {}.{}", searchWeight, entityDef.getName(), propertyName); LOG.debug("Applying search weight {} for attribute {}", searchWeight, attribute.getQualifiedName());
} }
propertiesWithSearchWeights.put(propertyName, searchWeight); indexFieldNameWithSearchWeights.put(attribute.getIndexFieldName(), searchWeight);
} }
} }
} }
\ No newline at end of file
...@@ -352,7 +352,7 @@ public class AtlasTypeDefStoreInitializer implements ActiveStateChangeHandler { ...@@ -352,7 +352,7 @@ public class AtlasTypeDefStoreInitializer implements ActiveStateChangeHandler {
try { try {
typeDefStore.init(); typeDefStore.init();
loadBootstrapTypeDefs(); loadBootstrapTypeDefs();
typeDefStore.notifyLoadCompletion();
try { try {
AtlasAuthorizerFactory.getAtlasAuthorizer(); AtlasAuthorizerFactory.getAtlasAuthorizer();
} catch (Throwable t) { } catch (Throwable t) {
......
...@@ -1006,6 +1006,17 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore { ...@@ -1006,6 +1006,17 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
} }
@Override
public void notifyLoadCompletion(){
for (TypeDefChangeListener changeListener : typeDefChangeListeners) {
try {
changeListener.onLoadCompletion();
} catch (Throwable t) {
LOG.error("OnLoadCompletion failed for listener {}", changeListener.getClass().getName(), t);
}
}
}
private void tryUpdateByName(String name, AtlasBaseTypeDef typeDef, AtlasTransientTypeRegistry ttr) throws AtlasBaseException { private void tryUpdateByName(String name, AtlasBaseTypeDef typeDef, AtlasTransientTypeRegistry ttr) throws AtlasBaseException {
try { try {
ttr.updateTypeByName(name, typeDef); ttr.updateTypeByName(name, typeDef);
......
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