You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2017/03/23 20:28:13 UTC
[1/4] usergrid git commit: [USERGRID-1336] Initial commit of a simple
query analyzer feature.
Repository: usergrid
Updated Branches:
refs/heads/master 3b1b0ca1c -> d92110853
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerEnforcementExceptionMapper.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerEnforcementExceptionMapper.java b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerEnforcementExceptionMapper.java
new file mode 100644
index 0000000..fed97d1
--- /dev/null
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerEnforcementExceptionMapper.java
@@ -0,0 +1,51 @@
+/*
+ * 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.usergrid.rest.exceptions;
+
+
+import org.apache.usergrid.persistence.index.exceptions.QueryAnalyzerEnforcementException;
+import org.apache.usergrid.rest.ApiResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+
+import static javax.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE;
+import static org.apache.usergrid.utils.JsonUtils.mapToJsonString;
+
+
+@Provider
+public class QueryAnalyzerEnforcementExceptionMapper extends AbstractExceptionMapper<QueryAnalyzerEnforcementException> {
+
+ private static final Logger logger = LoggerFactory.getLogger( QueryAnalyzerEnforcementExceptionMapper.class );
+
+ @Override
+ public Response toResponse( QueryAnalyzerEnforcementException e ) {
+
+ // build a proper ApiResponse object
+ ApiResponse apiResponse = new ApiResponse();
+ apiResponse.setError("query_analyzer_violations_enforced");
+ apiResponse.setErrorDescription(e.getErrorMessage());
+
+ logger.warn(e.getErrorMessage());
+
+ // give toResponse() the json string value of the ApiResponse
+ // skip logging because we use a 5XX but it's not technically an error for the logs
+ return toResponse( SERVICE_UNAVAILABLE, mapToJsonString(apiResponse), true );
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerExceptionMapper.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerExceptionMapper.java b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerExceptionMapper.java
new file mode 100644
index 0000000..bd5db14
--- /dev/null
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/QueryAnalyzerExceptionMapper.java
@@ -0,0 +1,69 @@
+/*
+ * 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.usergrid.rest.exceptions;
+
+
+import org.apache.usergrid.persistence.index.QueryAnalyzer;
+import org.apache.usergrid.persistence.index.exceptions.QueryAnalyzerException;
+import org.apache.usergrid.rest.ApiResponse;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+
+import java.util.Collections;
+import java.util.HashMap;
+
+import static javax.ws.rs.core.Response.Status.OK;
+import static org.apache.usergrid.utils.JsonUtils.mapToFormattedJsonString;
+
+
+@Provider
+public class QueryAnalyzerExceptionMapper extends AbstractExceptionMapper<QueryAnalyzerException> {
+
+ // This mapper is used to short-circuit the query process on any collection query. Therefore, it does its best
+ // job to build a normal ApiResponse format with 200 OK status.
+
+ @Override
+ public Response toResponse( QueryAnalyzerException e ) {
+
+
+ MultivaluedMap<String, String> params = new MultivaluedHashMap<>();
+ params.add("ql", e.getOriginalQuery());
+ params.add("analyzeOnly", "true");
+
+ // build a proper ApiResponse object
+ ApiResponse apiResponse = new ApiResponse();
+ apiResponse.setParams(params);
+ apiResponse.setSuccess();
+
+ // remove large_index warnings because indexes are shared buckets and not specific for an app
+ for( int i=0; i < e.getViolations().size(); i++) {
+ if (e.getViolations().get(i).get(QueryAnalyzer.k_violation) == QueryAnalyzer.v_large_index) {
+ e.getViolations().remove(i);
+ }
+ }
+
+ apiResponse.setMetadata(new HashMap<String,Object>(){{put("queryWarnings", e.getViolations());}});
+ apiResponse.setEntities(Collections.emptyList());
+ apiResponse.setAction("query analysis only");
+
+ // give toResponse() the json string value of the ApiResponse
+ return toResponse( OK, mapToFormattedJsonString(apiResponse) );
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/services/src/main/java/org/apache/usergrid/services/AbstractService.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/AbstractService.java b/stack/services/src/main/java/org/apache/usergrid/services/AbstractService.java
index 6736894..f60bfdd 100644
--- a/stack/services/src/main/java/org/apache/usergrid/services/AbstractService.java
+++ b/stack/services/src/main/java/org/apache/usergrid/services/AbstractService.java
@@ -29,6 +29,7 @@ import org.apache.usergrid.persistence.cache.CacheFactory;
import org.apache.usergrid.persistence.core.metrics.MetricsFactory;
import org.apache.usergrid.persistence.core.metrics.ObservableTimer;
import org.apache.usergrid.persistence.core.rx.RxTaskScheduler;
+import org.apache.usergrid.persistence.index.exceptions.QueryAnalyzerException;
import org.apache.usergrid.security.shiro.utils.LocalShiroCache;
import org.apache.usergrid.security.shiro.utils.SubjectUtils;
import org.apache.usergrid.services.ServiceParameter.IdParameter;
@@ -686,6 +687,7 @@ public abstract class AbstractService implements Service {
Query.fromIdentifier( name ), parameters, payload );
}
else if ( query != null ) {
+ query.setAnalyzeOnly(request.isAnalyzeQueryOnly());
return new ServiceContext( this, action, request, previousResults, owner, collectionName, query, parameters,
payload );
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/services/src/main/java/org/apache/usergrid/services/ServiceManager.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/ServiceManager.java b/stack/services/src/main/java/org/apache/usergrid/services/ServiceManager.java
index 04e00e0..075278f 100644
--- a/stack/services/src/main/java/org/apache/usergrid/services/ServiceManager.java
+++ b/stack/services/src/main/java/org/apache/usergrid/services/ServiceManager.java
@@ -31,7 +31,6 @@ import org.apache.usergrid.mq.QueueManager;
import org.apache.usergrid.persistence.Entity;
import org.apache.usergrid.persistence.EntityManager;
import org.apache.usergrid.persistence.EntityRef;
-import org.apache.usergrid.persistence.cassandra.CassandraService;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.services.ServiceParameter.IdParameter;
import org.apache.usergrid.services.applications.ApplicationsService;
@@ -358,13 +357,13 @@ public class ServiceManager {
public ServiceRequest newRequest( ServiceAction action, List<ServiceParameter> parameters ) throws Exception {
- return newRequest( action, false, parameters, null, true, true );
+ return newRequest( action, false, parameters, null, true, true, false);
}
public ServiceRequest newRequest( ServiceAction action, List<ServiceParameter> parameters, ServicePayload payload )
throws Exception {
- return newRequest( action, false, parameters, payload, true, true );
+ return newRequest( action, false, parameters, payload, true, true, false);
}
@@ -381,9 +380,9 @@ public class ServiceManager {
static ApplicationsService appService = new ApplicationsService();
- public ServiceRequest newRequest( ServiceAction action, boolean returnsTree, List<ServiceParameter> parameters,
- ServicePayload payload, boolean returnsInboundConnections,
- boolean returnsOutboundConnections ) throws Exception {
+ public ServiceRequest newRequest(ServiceAction action, boolean returnsTree, List<ServiceParameter> parameters,
+ ServicePayload payload, boolean returnsInboundConnections,
+ boolean returnsOutboundConnections, boolean analyzeQueryOnly) throws Exception {
if ( em != null ) {
if ( action != null ) {
@@ -414,12 +413,12 @@ public class ServiceManager {
String serviceName = pluralize( ServiceParameter.dequeueParameter( parameters ).getName() );
return new ServiceRequest( this, action, serviceName, parameters, payload, returnsTree,
- returnsInboundConnections, returnsOutboundConnections );
+ returnsInboundConnections, returnsOutboundConnections, analyzeQueryOnly);
}
public ServiceRequest newRequest( ServiceAction action, boolean returnsTree, List<ServiceParameter> parameters,
ServicePayload payload ) throws Exception {
- return newRequest( action, returnsTree, parameters, payload, true, true );
+ return newRequest( action, returnsTree, parameters, payload, true, true, false);
}
public void notifyExecutionEventListeners( ServiceAction action, ServiceRequest request, ServiceResults results,
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/services/src/main/java/org/apache/usergrid/services/ServiceRequest.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/ServiceRequest.java b/stack/services/src/main/java/org/apache/usergrid/services/ServiceRequest.java
index f8a5abb..89f4976 100644
--- a/stack/services/src/main/java/org/apache/usergrid/services/ServiceRequest.java
+++ b/stack/services/src/main/java/org/apache/usergrid/services/ServiceRequest.java
@@ -59,13 +59,14 @@ public class ServiceRequest {
private final boolean returnsOutboundConnections;
private final ServicePayload payload;
private final List<ServiceParameter> originalParameters;
+ private final boolean analyzeQueryOnly;
// return results_set, result_entity, new_service, param_list, properties
- public ServiceRequest( ServiceManager services, ServiceAction action, String serviceName,
- List<ServiceParameter> parameters, ServicePayload payload, boolean returnsTree,
- boolean returnsInboundConnections, boolean returnsOutboundConnections ) {
+ public ServiceRequest(ServiceManager services, ServiceAction action, String serviceName,
+ List<ServiceParameter> parameters, ServicePayload payload, boolean returnsTree,
+ boolean returnsInboundConnections, boolean returnsOutboundConnections, boolean analyzeQueryOnly) {
this.services = services;
this.action = action;
parent = null;
@@ -78,6 +79,7 @@ public class ServiceRequest {
this.returnsTree = returnsTree;
this.returnsInboundConnections = returnsInboundConnections;
this.returnsOutboundConnections = returnsOutboundConnections;
+ this.analyzeQueryOnly = analyzeQueryOnly;
if ( payload == null ) {
payload = new ServicePayload();
}
@@ -87,13 +89,13 @@ public class ServiceRequest {
public ServiceRequest( ServiceManager services, ServiceAction action, String serviceName,
List<ServiceParameter> parameters, ServicePayload payload, boolean returnsTree) {
- this( services, action, serviceName, parameters, payload, returnsTree, true, true);
+ this( services, action, serviceName, parameters, payload, returnsTree, true, true, false);
}
public ServiceRequest( ServiceManager services, ServiceAction action, String serviceName,
List<ServiceParameter> parameters, ServicePayload payload ) {
- this( services, action, serviceName, parameters, payload, false, true, true );
+ this( services, action, serviceName, parameters, payload, false, true, true, false);
}
@@ -103,6 +105,7 @@ public class ServiceRequest {
this.returnsTree = parent.returnsTree;
this.returnsInboundConnections = parent.returnsInboundConnections;
this.returnsOutboundConnections = parent.returnsOutboundConnections;
+ this.analyzeQueryOnly = parent.analyzeQueryOnly;
this.action = parent.action;
this.payload = parent.payload;
this.parent = parent;
@@ -121,7 +124,7 @@ public class ServiceRequest {
public ServiceRequest( ServiceManager services, ServiceAction action, ServiceRequest parent, EntityRef owner,
String path, String childPath, String serviceName, List<ServiceParameter> parameters,
ServicePayload payload, boolean returnsTree, boolean returnsInboundConnections,
- boolean returnsOutboundConnections ) {
+ boolean returnsOutboundConnections, boolean analyzeQueryOnly ) {
this.services = services;
this.action = action;
this.parent = parent;
@@ -134,25 +137,26 @@ public class ServiceRequest {
this.returnsTree = returnsTree;
this.returnsInboundConnections = returnsInboundConnections;
this.returnsOutboundConnections = returnsOutboundConnections;
+ this.analyzeQueryOnly = analyzeQueryOnly;
this.payload = payload;
}
public ServiceRequest( ServiceManager services, ServiceAction action, ServiceRequest parent, EntityRef owner,
String path, String childPath, String serviceName, List<ServiceParameter> parameters,
ServicePayload payload, boolean returnsTree ) {
- this(services, action, parent, owner, path, childPath, serviceName, parameters, payload, returnsTree, true, true);
+ this(services, action, parent, owner, path, childPath, serviceName, parameters, payload, returnsTree, true, true, false);
}
public static ServiceRequest withPath( ServiceRequest r, String path ) {
return new ServiceRequest( r.services, r.action, r.parent, r.owner, path, r.childPath, r.serviceName,
- r.parameters, r.payload, r.returnsTree, r.returnsInboundConnections, r.returnsOutboundConnections );
+ r.parameters, r.payload, r.returnsTree, r.returnsInboundConnections, r.returnsOutboundConnections, r.analyzeQueryOnly );
}
public static ServiceRequest withChildPath( ServiceRequest r, String childPath ) {
return new ServiceRequest( r.services, r.action, r.parent, r.owner, r.path, childPath, r.serviceName,
- r.parameters, r.payload, r.returnsTree, r.returnsInboundConnections, r.returnsOutboundConnections );
+ r.parameters, r.payload, r.returnsTree, r.returnsInboundConnections, r.returnsOutboundConnections, r.analyzeQueryOnly );
}
@@ -390,4 +394,8 @@ public class ServiceRequest {
public List<ServiceParameter> getOriginalParameters() {
return originalParameters;
}
+
+ public boolean isAnalyzeQueryOnly(){
+ return analyzeQueryOnly;
+ }
}
[2/4] usergrid git commit: [USERGRID-1336] Initial commit of a simple
query analyzer feature.
Posted by mr...@apache.org.
[USERGRID-1336] Initial commit of a simple query analyzer feature.
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/a4941462
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/a4941462
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/a4941462
Branch: refs/heads/master
Commit: a494146250ea92c6d0ebbb9c579ff194525f5eed
Parents: f8e644d
Author: Michael Russo <ru...@google.com>
Authored: Fri Feb 24 14:49:09 2017 -0800
Committer: Michael Russo <ru...@google.com>
Committed: Fri Feb 24 14:49:09 2017 -0800
----------------------------------------------------------------------
.../corepersistence/CpRelationManager.java | 9 ++
.../pipeline/builder/IdBuilder.java | 10 +-
.../pipeline/read/FilterFactory.java | 7 +-
.../search/AbstractElasticSearchFilter.java | 21 ++-
.../read/search/SearchCollectionFilter.java | 5 +-
.../read/search/SearchConnectionFilter.java | 5 +-
.../service/AggregationServiceImpl.java | 6 +-
.../service/CollectionSearch.java | 10 ++
.../service/CollectionServiceImpl.java | 2 +-
.../service/ConnectionSearch.java | 12 ++
.../service/ConnectionServiceImpl.java | 4 +-
.../org/apache/usergrid/persistence/Query.java | 9 ++
.../org/apache/usergrid/utils/JsonUtils.java | 2 +-
.../corepersistence/StaleIndexCleanupTest.java | 2 +-
.../index/AsyncIndexServiceTest.java | 2 +-
.../corepersistence/index/IndexServiceTest.java | 8 +-
.../usergrid/persistence/index/EntityIndex.java | 11 +-
.../usergrid/persistence/index/IndexFig.java | 39 ++++++
.../persistence/index/QueryAnalyzer.java | 129 +++++++++++++++++++
.../QueryAnalyzerEnforcementException.java | 45 +++++++
.../exceptions/QueryAnalyzerException.java | 57 ++++++++
.../index/impl/EsEntityIndexImpl.java | 61 ++++++++-
.../persistence/index/impl/EntityIndexTest.java | 86 ++++++-------
.../persistence/index/impl/GeoPagingTest.java | 2 +-
.../index/impl/IndexLoadTestsIT.java | 2 +-
.../rest/applications/CollectionResource.java | 17 ---
.../rest/applications/ServiceResource.java | 9 +-
.../exceptions/AbstractExceptionMapper.java | 17 ++-
...QueryAnalyzerEnforcementExceptionMapper.java | 51 ++++++++
.../QueryAnalyzerExceptionMapper.java | 69 ++++++++++
.../usergrid/services/AbstractService.java | 2 +
.../usergrid/services/ServiceManager.java | 15 +--
.../usergrid/services/ServiceRequest.java | 26 ++--
33 files changed, 626 insertions(+), 126 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
index 4a759ac..c02ca7d 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
@@ -629,6 +629,7 @@ public class CpRelationManager implements RelationManager {
final Query toExecute = adjustQuery( query );
final Optional<String> queryString = query.isGraphSearch()? Optional.<String>absent(): query.getQl();
final Id ownerId = headEntity.asId();
+ final boolean analyzeOnly = query.getAnalyzeOnly();
if(query.getLevel() == Level.IDS ){
@@ -642,6 +643,8 @@ public class CpRelationManager implements RelationManager {
new CollectionSearch( applicationScope, ownerId, collectionName, collection.getType(), toExecute.getLimit(),
queryString, cursor );
+ search.setAnalyzeOnly(analyzeOnly);
+
return collectionService.searchCollectionIds( search );
}
}.next();
@@ -658,6 +661,8 @@ public class CpRelationManager implements RelationManager {
new CollectionSearch( applicationScope, ownerId, collectionName, collection.getType(), toExecute.getLimit(),
queryString, cursor );
+ search.setAnalyzeOnly(analyzeOnly);
+
return collectionService.searchCollection( search );
}
}.next();
@@ -919,6 +924,8 @@ public class CpRelationManager implements RelationManager {
headEntity = em.validate( headEntity );
+ final boolean analyzeOnly = query.getAnalyzeOnly();
+
final Query toExecute = adjustQuery( query );
@@ -951,6 +958,7 @@ public class CpRelationManager implements RelationManager {
final ConnectionSearch search =
new ConnectionSearch( applicationScope, sourceId, entityType, connection, toExecute.getLimit(),
queryString, cursor, isConnecting );
+ search.setAnalyzeOnly(analyzeOnly);
return connectionService.searchConnectionAsRefs( search );
}
}.next();
@@ -966,6 +974,7 @@ public class CpRelationManager implements RelationManager {
final ConnectionSearch search =
new ConnectionSearch( applicationScope, sourceId, entityType, connection, toExecute.getLimit(),
queryString, cursor, isConnecting );
+ search.setAnalyzeOnly(analyzeOnly);
return connectionService.searchConnection( search );
}
}.next();
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/builder/IdBuilder.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/builder/IdBuilder.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/builder/IdBuilder.java
index 85e9069..a7f9ad9 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/builder/IdBuilder.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/builder/IdBuilder.java
@@ -117,12 +117,13 @@ public class IdBuilder {
* @param collectionName The name of the collection
* @param ql The user's query to execute
* @param entityType The type of the entity
+ * @param analyzeOnly
* @return Candidate results
*/
- public CandidateBuilder searchCollection( final String collectionName, final String ql, final String entityType ) {
+ public CandidateBuilder searchCollection(final String collectionName, final String ql, final String entityType, boolean analyzeOnly) {
final Pipeline<FilterResult<Candidate>> newFilter = pipeline.withFilter( filterFactory.searchCollectionFilter(
- ql, collectionName, entityType ) );
+ ql, collectionName, entityType, analyzeOnly ) );
return new CandidateBuilder( newFilter, filterFactory );
}
@@ -133,13 +134,14 @@ public class IdBuilder {
* @param connectionName The connection name to search
* @param ql The query to execute
* @param entityType The optional type of entity. If this is absent, all entity types in the connection will be searched
+ * @param analyzeOnly
* @return Candidate results
*/
- public CandidateBuilder searchConnection( final String connectionName, final String ql , final Optional<String> entityType) {
+ public CandidateBuilder searchConnection(final String connectionName, final String ql, final Optional<String> entityType, boolean analyzeOnly) {
final Pipeline<FilterResult<Candidate>> newFilter = pipeline.withFilter( filterFactory.searchConnectionFilter(
- ql, connectionName, entityType ) );
+ ql, connectionName, entityType,analyzeOnly ) );
return new CandidateBuilder( newFilter, filterFactory );
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/FilterFactory.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/FilterFactory.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/FilterFactory.java
index 4b615d8..7b61b3d 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/FilterFactory.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/FilterFactory.java
@@ -96,7 +96,8 @@ public interface FilterFactory {
*/
SearchCollectionFilter searchCollectionFilter( @Assisted( "query" ) final String query,
@Assisted( "collectionName" ) final String collectionName,
- @Assisted( "entityType" ) final String entityType );
+ @Assisted( "entityType" ) final String entityType,
+ @Assisted( "analyzeOnly") final boolean analyzeOnly);
/**
@@ -108,8 +109,8 @@ public interface FilterFactory {
*/
SearchConnectionFilter searchConnectionFilter( @Assisted( "query" ) final String query,
@Assisted( "connectionName" ) final String connectionName,
- @Assisted( "connectedEntityType" )
- final Optional<String> connectedEntityType );
+ @Assisted( "connectedEntityType" ) final Optional<String> connectedEntityType,
+ @Assisted( "analyzeOnly") final boolean analyzeOnly);
/**
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/AbstractElasticSearchFilter.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/AbstractElasticSearchFilter.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/AbstractElasticSearchFilter.java
index 4bf723e..9f6be2a 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/AbstractElasticSearchFilter.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/AbstractElasticSearchFilter.java
@@ -23,6 +23,8 @@ package org.apache.usergrid.corepersistence.pipeline.read.search;
import org.apache.usergrid.corepersistence.index.IndexLocationStrategyFactory;
import org.apache.usergrid.persistence.Schema;
import org.apache.usergrid.persistence.index.*;
+import org.apache.usergrid.persistence.index.exceptions.QueryAnalyzerEnforcementException;
+import org.apache.usergrid.persistence.index.exceptions.QueryAnalyzerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,19 +56,21 @@ public abstract class AbstractElasticSearchFilter extends AbstractPathFilter<Id,
private final IndexLocationStrategyFactory indexLocationStrategyFactory;
private final String query;
private final Timer searchTimer;
+ private final boolean analyzeOnly;
/**
* Create a new instance of our command
*/
- public AbstractElasticSearchFilter( final EntityIndexFactory entityIndexFactory,
- final MetricsFactory metricsFactory,
- final IndexLocationStrategyFactory indexLocationStrategyFactory,
- final String query ) {
+ public AbstractElasticSearchFilter(final EntityIndexFactory entityIndexFactory,
+ final MetricsFactory metricsFactory,
+ final IndexLocationStrategyFactory indexLocationStrategyFactory,
+ final String query, boolean analyzeOnly) {
this.entityIndexFactory = entityIndexFactory;
this.indexLocationStrategyFactory = indexLocationStrategyFactory;
this.query = query;
this.searchTimer = metricsFactory.getTimer( AbstractElasticSearchFilter.class, "query.search" );
+ this.analyzeOnly = analyzeOnly;
}
@@ -123,7 +127,7 @@ public abstract class AbstractElasticSearchFilter extends AbstractPathFilter<Id,
try {
final CandidateResults candidateResults =
- applicationEntityIndex.search( searchEdge, searchTypes, query, limit, currentOffSet, propertiesWithType );
+ applicationEntityIndex.search( searchEdge, searchTypes, query, limit, currentOffSet, propertiesWithType, analyzeOnly );
Collection<SelectFieldMapping> fieldMappingCollection = candidateResults.getGetFieldMappings();
@@ -156,8 +160,11 @@ public abstract class AbstractElasticSearchFilter extends AbstractPathFilter<Id,
}
catch ( Throwable t ) {
-
- logger.error( "Unable to search candidates", t );
+ // query analyzer exceptions are short circuits initiated by an exception, but is not really an error
+ // still rethrow because it's mapped later
+ if (!(t instanceof QueryAnalyzerException || t instanceof QueryAnalyzerEnforcementException) ){
+ logger.error( "Unable to search candidates", t );
+ }
subscriber.onError( t );
}
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchCollectionFilter.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchCollectionFilter.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchCollectionFilter.java
index 4fc6179..214bcbb 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchCollectionFilter.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchCollectionFilter.java
@@ -52,8 +52,9 @@ public class SearchCollectionFilter extends AbstractElasticSearchFilter {
final MetricsFactory metricsFactory,
@Assisted( "query" ) final String query,
@Assisted( "collectionName" ) final String collectionName,
- @Assisted( "entityType" ) final String entityType ) {
- super( entityIndexFactory, metricsFactory, indexLocationStrategyFactory, query );
+ @Assisted( "entityType" ) final String entityType,
+ @Assisted( "analyzeOnly") final boolean analyzeOnly) {
+ super( entityIndexFactory, metricsFactory, indexLocationStrategyFactory, query, analyzeOnly );
this.collectionName = collectionName;
this.entityType = entityType;
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchConnectionFilter.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchConnectionFilter.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchConnectionFilter.java
index d484ade..4a61120 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchConnectionFilter.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/SearchConnectionFilter.java
@@ -50,8 +50,9 @@ public class SearchConnectionFilter extends AbstractElasticSearchFilter {
final IndexLocationStrategyFactory indexLocationStrategyFactory,
@Assisted( "query" ) final String query,
@Assisted( "connectionName" ) final String connectionName,
- @Assisted( "connectedEntityType" ) final Optional<String> connectedEntityType ) {
- super( entityIndexFactory, metricsFactory, indexLocationStrategyFactory, query );
+ @Assisted( "connectedEntityType" ) final Optional<String> connectedEntityType,
+ @Assisted( "analyzeOnly") final boolean analyzeOnly) {
+ super( entityIndexFactory, metricsFactory, indexLocationStrategyFactory, query, analyzeOnly);
this.connectionName = connectionName;
this.connectedEntityType = connectedEntityType;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/AggregationServiceImpl.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/AggregationServiceImpl.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/AggregationServiceImpl.java
index 44010db..6588486 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/AggregationServiceImpl.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/AggregationServiceImpl.java
@@ -73,7 +73,7 @@ public class AggregationServiceImpl implements AggregationService {
MathObservable.sumLong(
graphManager.getEdgeTypesFromSource(new SimpleSearchEdgeType(applicationScope.getApplication(), CpNamingUtils.EDGE_COLL_PREFIX, Optional.<String>absent()))
.map(type -> CpNamingUtils.createCollectionSearchEdge(applicationScope.getApplication(), type))
- .map(edge -> entityIndex.getEntitySize(edge))
+ .map(edge -> entityIndex.getTotalEntitySizeInBytes(edge))
), sumTimer).toBlocking().last();
return sum.longValue();
@@ -90,7 +90,7 @@ public class AggregationServiceImpl implements AggregationService {
{
SearchEdge edge = CpNamingUtils.createCollectionSearchEdge(applicationScope.getApplication(), type);
final String collectionName = CpNamingUtils.getCollectionNameFromEdgeName(type);
- long sumType = entityIndex.getEntitySize(edge);
+ long sumType = entityIndex.getTotalEntitySizeInBytes(edge);
map.put(collectionName,sumType);
})
)
@@ -103,7 +103,7 @@ public class AggregationServiceImpl implements AggregationService {
public long getSize(ApplicationScope applicationScope, SearchEdge edge) {
final IndexLocationStrategy indexLocationStrategy = indexLocationStrategyFactory.getIndexLocationStrategy(applicationScope);
EntityIndex entityIndex = entityIndexFactory.createEntityIndex(indexLocationStrategy);
- return entityIndex.getEntitySize(edge);
+ return entityIndex.getTotalEntitySizeInBytes(edge);
}
@Override
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionSearch.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionSearch.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionSearch.java
index 602a5b6..6240028 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionSearch.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionSearch.java
@@ -41,6 +41,7 @@ public class CollectionSearch {
private final Optional<String> query;
private final Optional<String> cursor;
private Level level = Level.ALL;
+ private boolean analyzeOnly;
public CollectionSearch( final ApplicationScope applicationScope, final Id collectionOwnerId, final String
@@ -53,6 +54,7 @@ public class CollectionSearch {
this.limit = limit;
this.query = query;
this.cursor = cursor;
+ this.analyzeOnly = false;
}
@@ -93,4 +95,12 @@ public class CollectionSearch {
public void setResultsLevel(Level level){ this.level = level; }
public Level getResultsLevel(){ return level; }
+
+ public boolean getAnalyzeOnly() {
+ return analyzeOnly;
+ }
+
+ public void setAnalyzeOnly(final boolean analyzeOnly){
+ this.analyzeOnly = analyzeOnly;
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionServiceImpl.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionServiceImpl.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionServiceImpl.java
index 9244315..7684050 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionServiceImpl.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/CollectionServiceImpl.java
@@ -68,7 +68,7 @@ public class CollectionServiceImpl implements CollectionService {
results = pipelineBuilder.traverseCollection( collectionName ).loadEntities();
}
else {
- results = pipelineBuilder.searchCollection( collectionName, query.get(),search.getEntityType()).loadEntities();
+ results = pipelineBuilder.searchCollection( collectionName, query.get(),search.getEntityType(), search.getAnalyzeOnly()).loadEntities();
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionSearch.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionSearch.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionSearch.java
index 8ad57fb..98f36be 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionSearch.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionSearch.java
@@ -37,6 +37,8 @@ public class ConnectionSearch {
private final Optional<String> query;
private final Optional<String> cursor;
private final boolean isConnecting;
+ private boolean analyzeOnly;
+
public ConnectionSearch( final ApplicationScope applicationScope, final Id sourceNodeId, final Optional<String> entityType,
@@ -50,6 +52,8 @@ public class ConnectionSearch {
this.query = query;
this.cursor = cursor;
this.isConnecting = isConnecting;
+ this.analyzeOnly = false;
+
}
@@ -90,4 +94,12 @@ public class ConnectionSearch {
public boolean getIsConnecting(){
return isConnecting;
}
+
+ public boolean getAnalyzeOnly() {
+ return analyzeOnly;
+ }
+
+ public void setAnalyzeOnly(final boolean analyzeOnly){
+ this.analyzeOnly = analyzeOnly;
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionServiceImpl.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionServiceImpl.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionServiceImpl.java
index 926c676..7c70a3d 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionServiceImpl.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/service/ConnectionServiceImpl.java
@@ -106,7 +106,7 @@ public class ConnectionServiceImpl implements ConnectionService {
else {
results =
- pipelineBuilder.searchConnection( search.getConnectionName(), query.get(), search.getEntityType() )
+ pipelineBuilder.searchConnection( search.getConnectionName(), query.get(), search.getEntityType(), search.getAnalyzeOnly() )
.loadEntities();
}
@@ -135,7 +135,7 @@ public class ConnectionServiceImpl implements ConnectionService {
}
else {
traversedIds =
- pipelineBuilder.searchConnection( connectionName, query.get(), search.getEntityType() ).loadIds();
+ pipelineBuilder.searchConnection( connectionName, query.get(), search.getEntityType(), search.getAnalyzeOnly() ).loadIds();
}
//create connection refs
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/persistence/Query.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/Query.java b/stack/core/src/main/java/org/apache/usergrid/persistence/Query.java
index d68c085..1015f76 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/Query.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/Query.java
@@ -78,6 +78,7 @@ public class Query {
private String collection;
private String ql;
private Collection<SelectFieldMapping> selectFields;
+ private boolean analyzeOnly = false;
private static ObjectMapper mapper = new ObjectMapper();
@@ -120,6 +121,7 @@ public class Query {
? new ArrayList<>( q.counterFilters ) : null;
collection = q.collection;
level = q.level;
+ analyzeOnly = q.analyzeOnly;
}
@@ -481,6 +483,13 @@ public class Query {
this.permissions = permissions;
}
+ public void setAnalyzeOnly(final boolean analyzeOnly){
+ this.analyzeOnly = analyzeOnly;
+ }
+
+ public boolean getAnalyzeOnly(){
+ return analyzeOnly;
+ }
public boolean isMergeSelectResults() {
return mergeSelectResults;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/main/java/org/apache/usergrid/utils/JsonUtils.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/utils/JsonUtils.java b/stack/core/src/main/java/org/apache/usergrid/utils/JsonUtils.java
index 3bb96f9..6c1875b 100644
--- a/stack/core/src/main/java/org/apache/usergrid/utils/JsonUtils.java
+++ b/stack/core/src/main/java/org/apache/usergrid/utils/JsonUtils.java
@@ -83,7 +83,7 @@ public class JsonUtils {
/** Converts object to JSON string, throws runtime exception JsonWriteException on failure. */
public static String mapToFormattedJsonString( Object obj ) {
try {
- return indentObjectMapper.writeValueAsString( obj );
+ return indentObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString( obj );
}
catch ( Throwable t ) {
if (logger.isDebugEnabled()) {
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/test/java/org/apache/usergrid/corepersistence/StaleIndexCleanupTest.java
----------------------------------------------------------------------
diff --git a/stack/core/src/test/java/org/apache/usergrid/corepersistence/StaleIndexCleanupTest.java b/stack/core/src/test/java/org/apache/usergrid/corepersistence/StaleIndexCleanupTest.java
index 65c373f..abe2615 100644
--- a/stack/core/src/test/java/org/apache/usergrid/corepersistence/StaleIndexCleanupTest.java
+++ b/stack/core/src/test/java/org/apache/usergrid/corepersistence/StaleIndexCleanupTest.java
@@ -344,7 +344,7 @@ public class StaleIndexCleanupTest extends AbstractCoreIT {
SearchEdge is = CpNamingUtils.createCollectionSearchEdge( rootId, collName );
- return ei.search( is, SearchTypes.fromTypes( type ), query, 1000, 0 );
+ return ei.search( is, SearchTypes.fromTypes( type ), query, 1000, 0, false );
}
/**
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/AsyncIndexServiceTest.java
----------------------------------------------------------------------
diff --git a/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/AsyncIndexServiceTest.java b/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/AsyncIndexServiceTest.java
index 366ab34..cecc3b2 100644
--- a/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/AsyncIndexServiceTest.java
+++ b/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/AsyncIndexServiceTest.java
@@ -182,7 +182,7 @@ public abstract class AsyncIndexServiceTest {
for ( int i = 0; i < attempts; i++ ) {
final CandidateResults candidateResults =
- entityIndex.search( searchEdge, searchTypes, "select *", 100, 0 );
+ entityIndex.search( searchEdge, searchTypes, "select *", 100, 0, false );
if ( candidateResults.size() == expectedSize ) {
return candidateResults;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/IndexServiceTest.java
----------------------------------------------------------------------
diff --git a/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/IndexServiceTest.java b/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/IndexServiceTest.java
index ecc2b46..f47afe6 100644
--- a/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/IndexServiceTest.java
+++ b/stack/core/src/test/java/org/apache/usergrid/corepersistence/index/IndexServiceTest.java
@@ -353,7 +353,7 @@ public class IndexServiceTest {
//ensure that no edges remain
CandidateResults connectionResultsEmpty = EntityIndex.search( connectionSearchEdge,
- SearchTypes.fromTypes( "thing" ),"select *",10,0 );
+ SearchTypes.fromTypes( "thing" ),"select *",10,0, false );
assertEquals(1,connectionResultsEmpty.size());
@@ -375,7 +375,7 @@ public class IndexServiceTest {
//ensure that no edges remain
connectionResultsEmpty = EntityIndex.search( connectionSearchEdge,
- SearchTypes.fromTypes( "thing" ),"select *",10,0 );
+ SearchTypes.fromTypes( "thing" ),"select *",10,0, false );
assertEquals(0,connectionResultsEmpty.size());
@@ -434,7 +434,7 @@ public class IndexServiceTest {
//ensure that no edges remain
final CandidateResults connectionResultsEmpty = EntityIndex.search( connectionSearchEdge,
- SearchTypes.fromTypes( "things" ),"select *",10,0 );
+ SearchTypes.fromTypes( "things" ),"select *",10,0, false );
assertEquals(0,connectionResultsEmpty.size());
}
@@ -535,7 +535,7 @@ public class IndexServiceTest {
String ql = "select *";
for ( int i = 0; i < attempts; i++ ) {
final CandidateResults candidateResults =
- EntityIndex.search( searchEdge, searchTypes, ql , 100, 0 );
+ EntityIndex.search( searchEdge, searchTypes, ql , 100, 0, false );
if ( candidateResults.size() == expectedSize ) {
return candidateResults;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
index ee12ec8..14020a9 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
@@ -76,7 +76,7 @@ public interface EntityIndex extends CPManager {
* @param edge
* @return
*/
- long getEntitySize(final SearchEdge edge);
+ long getTotalEntitySizeInBytes(final SearchEdge edge);
/**
* Initialize the index if necessary. This is an idempotent operation and should not create an index
@@ -98,10 +98,12 @@ public interface EntityIndex extends CPManager {
* @param query The query to execute
* @param limit The limit of values to return
* @param offset The offset to query on
+ * @param analyzeOnly This optional param will instruct the query processing to only analyze the query and
+ * provide info but not actually execute the query.
* @return
*/
CandidateResults search(final SearchEdge searchEdge, final SearchTypes searchTypes, final String query,
- final int limit, final int offset);
+ final int limit, final int offset, final boolean analyzeOnly);
/**
* Search on every document in the specified search edge. Also search by the types if specified
@@ -113,10 +115,13 @@ public interface EntityIndex extends CPManager {
* @param offset The offset to query on
* @param fieldsWithType An optional param that allows the caller to provide schema related info which might
* relate to data in the query, such as sort predicate types
+ * @param analyzeOnly This optional param will instruct the query processing to only analyze the query and
+ * provide info but not actually execute the query.
* @return
*/
CandidateResults search(final SearchEdge searchEdge, final SearchTypes searchTypes, final String query,
- final int limit, final int offset, final Map<String, Class> fieldsWithType);
+ final int limit, final int offset, final Map<String, Class> fieldsWithType,
+ final boolean analyzeOnly);
/**
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
index c4596a2..e23961c 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
@@ -62,6 +62,19 @@ public interface IndexFig extends GuicyFig {
String ELASTICSEARCH_VERSION_QUERY_LIMIT = "elasticsearch.version_query_limit";
+ String USERGRID_QUERYANALYZER_OPERAND_COUNT = "usergrid.queryanalyzer.operand_count";
+
+ String USERGRID_QUERYANALYZER_SORTPREDICATE_COUNT = "usergrid.queryanalyzer.sortpredicate_count";
+
+ String USERGRID_QUERYANALYZER_COLLECTIONSIZE = "usergrid.queryanalyzer.collectionsize_bytes";
+
+ String USERGRID_QUERYANALYZER_INDEXSIZE = "usergrid.queryanalyzer.indexsize_bytes";
+
+ String USERGRID_QUERYANALYZER_ENFORCE = "usergrid.queryanalyzer.enforce";
+
+
+
+
/**
* Comma-separated list of Elasticsearch hosts.
@@ -196,7 +209,33 @@ public interface IndexFig extends GuicyFig {
@Key( "elasticsearch_queue_error_sleep_ms" )
long getSleepTimeForQueueError();
+
@Default("100")
@Key( ELASTICSEARCH_VERSION_QUERY_LIMIT )
int getVersionQueryLimit();
+
+
+ @Default("8")
+ @Key( USERGRID_QUERYANALYZER_OPERAND_COUNT )
+ int getQueryBreakerErrorOperandCount();
+
+
+ @Default("8")
+ @Key( USERGRID_QUERYANALYZER_SORTPREDICATE_COUNT )
+ int getQueryBreakerErrorSortPredicateCount();
+
+
+ @Default("500000000L") // 500 MB
+ @Key(USERGRID_QUERYANALYZER_COLLECTIONSIZE)
+ long getQueryBreakerErrorCollectionSizeBytes();
+
+
+ @Default("10000000000") // 10 GB
+ @Key( USERGRID_QUERYANALYZER_INDEXSIZE )
+ long getQueryBreakerErrorIndexSizeBytes();
+
+
+ @Default("true")
+ @Key( USERGRID_QUERYANALYZER_ENFORCE )
+ boolean enforceQueryBreaker();
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java
new file mode 100644
index 0000000..86f1e5d
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.usergrid.persistence.index;
+
+import org.apache.usergrid.persistence.index.query.ParsedQuery;
+import org.apache.usergrid.persistence.index.query.tree.Operand;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class QueryAnalyzer {
+
+ public static final String v_predicate_count = "sort_predicate_count_exceeded";
+ public static final String v_operand_count = "operand_count_exceeded";
+ public static final String v_large_collection = "large_collection_size_bytes";
+ public static final String v_large_index = "large_index_size_bytes";
+
+ public static final String k_violation = "violation";
+ public static final String k_limit = "limit";
+ public static final String k_actual = "actual";
+
+
+ public static List<Map<String, Object>> analyze(final ParsedQuery parsedQuery, final long collectionSizeInBytes,
+ final long indexSizeInBytes, final IndexFig indexFig ) {
+
+ List<Map<String, Object>> violations = new ArrayList<>();
+
+ // get configured breaker values
+ final int errorPredicateCount = indexFig.getQueryBreakerErrorSortPredicateCount();
+ final int errorOperandCount = indexFig.getQueryBreakerErrorOperandCount();
+ final long errorCollectionSizeBytes = indexFig.getQueryBreakerErrorCollectionSizeBytes();
+ final long errorIndexSizeBytes = indexFig.getQueryBreakerErrorIndexSizeBytes();
+
+
+ // get the actual values to compare against the configured enforcement values
+ int queryPredicatesSize = parsedQuery.getSortPredicates().size();
+ int queryOperandCount = getTotalChildCount(parsedQuery.getRootOperand());
+
+ // large indexes can cause issues, this is never returned from the API and only logged
+ if( indexSizeInBytes > errorIndexSizeBytes ){
+ violations.add(new HashMap<String, Object>(3){{
+ put(k_violation, v_large_index);
+ put(k_limit, errorIndexSizeBytes);
+ put(k_actual, indexSizeInBytes);
+ }});
+ }
+
+ // large collections mean that sorts and other complex queries can impact the query service (Elasticsearch)
+ if (collectionSizeInBytes > errorCollectionSizeBytes ){
+ violations.add(new HashMap<String, Object>(3){{
+ put(k_violation, v_large_collection);
+ put(k_limit, errorCollectionSizeBytes);
+ put(k_actual, collectionSizeInBytes);
+ }});
+ }
+
+ // complex queries can be determined from the # of operands and sort predicates
+ if ( queryPredicatesSize > errorPredicateCount){
+ violations.add(new HashMap<String, Object>(3){{
+ put(k_violation, v_predicate_count);
+ put(k_limit, errorPredicateCount);
+ put(k_actual, queryPredicatesSize);
+ }});
+ }
+ if (queryOperandCount > errorOperandCount){
+ violations.add(new HashMap<String, Object>(3){{
+ put(k_violation, v_operand_count);
+ put(k_limit, errorOperandCount);
+ put(k_actual, queryOperandCount);
+ }});
+ }
+
+ return violations;
+
+ }
+
+ public static String violationsAsString(List<Map<String, Object>> violations, String originalQuery){
+
+ final StringBuilder logMessage = new StringBuilder();
+ logMessage.append( "QueryAnalyzer Violations Detected [").append(violations.size()).append("]: [" );
+ violations.forEach(violation -> {
+
+ final StringBuilder violationMessage = new StringBuilder();
+ violation.forEach((k,v) -> {
+ violationMessage.append(k).append(":").append(v).append(",");
+
+ });
+ violationMessage.deleteCharAt(violationMessage.length()-1);
+ logMessage.append(" (").append(violationMessage).append(") ");
+ });
+ logMessage.append("]");
+ logMessage.append(" [Original Query: ").append(originalQuery).append("]");
+ return logMessage.toString();
+
+ }
+
+ private static int getTotalChildCount(Operand rootOperand){
+ int count = 0;
+ if( rootOperand != null) {
+ count ++;
+ if (rootOperand.getChildren() != null) {
+ for (Object child : rootOperand.getChildren()) {
+ if (child instanceof Operand) {
+ count += getTotalChildCount((Operand) child);
+ }
+ }
+ }
+ }
+ return count;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerEnforcementException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerEnforcementException.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerEnforcementException.java
new file mode 100644
index 0000000..454fbe1
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerEnforcementException.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.usergrid.persistence.index.exceptions;
+
+
+import org.apache.usergrid.persistence.index.QueryAnalyzer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class QueryAnalyzerEnforcementException extends RuntimeException {
+
+ private List<Map<String, Object>> violations = new ArrayList<>();
+ private String originalQuery;
+
+ public QueryAnalyzerEnforcementException(final List<Map<String, Object>> violations, final String originalQuery) {
+ super("Query Analyzer Enforced");
+ this.violations = violations;
+ this.originalQuery = originalQuery;
+ }
+
+ public List<Map<String, Object>> getViolations(){
+ return violations;
+ }
+
+ public String getErrorMessage() {
+ return QueryAnalyzer.violationsAsString(violations, originalQuery);
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerException.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerException.java
new file mode 100644
index 0000000..c392822
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/exceptions/QueryAnalyzerException.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.usergrid.persistence.index.exceptions;
+
+
+import org.apache.usergrid.persistence.index.QueryAnalyzer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class QueryAnalyzerException extends RuntimeException {
+
+ private List<Map<String, Object>> violations = new ArrayList<>();
+ private String originalQuery;
+ private UUID applicationUUID;
+
+ public QueryAnalyzerException(final List<Map<String, Object>> violations, final String originalQuery,
+ final UUID applicationUUID) {
+ super("Query Analyzer");
+ this.violations = violations;
+ this.originalQuery = originalQuery;
+ this.applicationUUID = applicationUUID;
+ }
+
+ public List<Map<String, Object>> getViolations(){
+ return violations;
+ }
+
+ public String getErrorMessage() {
+ return QueryAnalyzer.violationsAsString(violations, originalQuery);
+ }
+
+ public String getOriginalQuery(){
+ return originalQuery;
+ }
+
+ public UUID getApplicationUUID(){
+ return applicationUUID;
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
index 3615d86..26e8f68 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
@@ -21,6 +21,8 @@ package org.apache.usergrid.persistence.index.impl;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Timer;
import com.google.common.base.*;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources;
import com.google.inject.Inject;
@@ -36,6 +38,8 @@ import org.apache.usergrid.persistence.core.util.ValidationUtils;
import org.apache.usergrid.persistence.index.*;
import org.apache.usergrid.persistence.index.ElasticSearchQueryBuilder.SearchRequestBuilderStrategyV2;
import org.apache.usergrid.persistence.index.exceptions.IndexException;
+import org.apache.usergrid.persistence.index.exceptions.QueryAnalyzerException;
+import org.apache.usergrid.persistence.index.exceptions.QueryAnalyzerEnforcementException;
import org.apache.usergrid.persistence.index.migration.IndexDataVersions;
import org.apache.usergrid.persistence.index.query.ParsedQuery;
import org.apache.usergrid.persistence.index.query.ParsedQueryBuilder;
@@ -54,6 +58,8 @@ import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
+import org.elasticsearch.action.admin.indices.stats.CommonStats;
+import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.deletebyquery.IndexDeleteByQueryResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
@@ -78,6 +84,7 @@ import rx.Observable;
import java.io.IOException;
import java.net.URL;
import java.util.*;
+import java.util.concurrent.TimeUnit;
import static org.apache.usergrid.persistence.index.impl.IndexingUtils.APPLICATION_ID_FIELDNAME;
import static org.apache.usergrid.persistence.index.impl.IndexingUtils.applicationId;
@@ -129,6 +136,10 @@ public class EsEntityIndexImpl implements EntityIndex,VersionedData {
private Meter refreshIndexMeter;
+ private Cache<String, Long> sizeCache =
+ CacheBuilder.newBuilder().maximumSize( 1000 ).expireAfterWrite(5, TimeUnit.MINUTES).build();
+
+
@Inject
public EsEntityIndexImpl( final EsProvider provider,
final IndexCache indexCache,
@@ -412,12 +423,13 @@ public class EsEntityIndexImpl implements EntityIndex,VersionedData {
}
public CandidateResults search( final SearchEdge searchEdge, final SearchTypes searchTypes, final String query,
- final int limit, final int offset ) {
- return search(searchEdge, searchTypes, query, limit, offset, new HashMap<>(0));
+ final int limit, final int offset, final boolean analyzeOnly ) {
+ return search(searchEdge, searchTypes, query, limit, offset, new HashMap<>(0), analyzeOnly);
}
public CandidateResults search( final SearchEdge searchEdge, final SearchTypes searchTypes, final String query,
- final int limit, final int offset, final Map<String, Class> fieldsWithType ) {
+ final int limit, final int offset, final Map<String, Class> fieldsWithType,
+ final boolean analyzeOnly ) {
IndexValidationUtils.validateSearchEdge(searchEdge);
Preconditions.checkNotNull(searchTypes, "searchTypes cannot be null");
@@ -442,6 +454,36 @@ public class EsEntityIndexImpl implements EntityIndex,VersionedData {
}
+ final String cacheKey = applicationScope.getApplication().getUuid().toString()+"_"+searchEdge.getEdgeName();
+ final Object totalEdgeSizeFromCache = sizeCache.getIfPresent(cacheKey);
+ long totalEdgeSizeInBytes;
+ if (totalEdgeSizeFromCache == null){
+ totalEdgeSizeInBytes = getTotalEntitySizeInBytes(searchEdge);
+ sizeCache.put(cacheKey, totalEdgeSizeInBytes);
+ }else{
+ totalEdgeSizeInBytes = (long) totalEdgeSizeFromCache;
+ }
+
+ final Object totalIndexSizeFromCache = sizeCache.getIfPresent(indexLocationStrategy.getIndexRootName());
+ long totalIndexSizeInBytes;
+ if (totalIndexSizeFromCache == null){
+ totalIndexSizeInBytes = getIndexSize();
+ sizeCache.put(indexLocationStrategy.getIndexRootName(), totalIndexSizeInBytes);
+ }else{
+ totalIndexSizeInBytes = (long) totalIndexSizeFromCache;
+ }
+
+ List<Map<String, Object>> violations = QueryAnalyzer.analyze(parsedQuery, totalEdgeSizeInBytes, totalIndexSizeInBytes, indexFig);
+ if(indexFig.enforceQueryBreaker() && violations.size() > 0){
+ throw new QueryAnalyzerEnforcementException(violations, parsedQuery.getOriginalQuery());
+ }else{
+ logger.warn( QueryAnalyzer.violationsAsString(violations, parsedQuery.getOriginalQuery()) );
+ }
+
+ if(analyzeOnly){
+ throw new QueryAnalyzerException(violations, parsedQuery.getOriginalQuery(), applicationScope.getApplication().getUuid());
+ }
+
final SearchRequestBuilder srb = searchRequest
.getBuilder( searchEdge, searchTypes, visitor, limit, offset, parsedQuery.getSortPredicates(), fieldsWithType )
.setTimeout(TimeValue.timeValueMillis(queryTimeout));
@@ -824,9 +866,20 @@ public class EsEntityIndexImpl implements EntityIndex,VersionedData {
return Health.RED;
}
+ private long getIndexSize(){
+ final IndicesStatsResponse statsResponse = esProvider.getClient()
+ .admin()
+ .indices()
+ .prepareStats(indexLocationStrategy.getIndexInitialName())
+ .all()
+ .execute()
+ .actionGet();
+ final CommonStats indexStats = statsResponse.getIndex(indexLocationStrategy.getIndexInitialName()).getTotal();
+ return indexStats.getStore().getSizeInBytes();
+ }
@Override
- public long getEntitySize(final SearchEdge edge){
+ public long getTotalEntitySizeInBytes(final SearchEdge edge){
//"term":{"edgeName":"zzzcollzzz|roles"}
SearchRequestBuilder builder = searchRequestBuilderStrategyV2.getBuilder();
builder.setQuery(new TermQueryBuilder("edgeSearch",IndexingUtils.createContextName(applicationScope,edge)));
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java
index e64db83..ac7d10d 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java
@@ -160,7 +160,7 @@ public class EntityIndexTest extends BaseIT {
StopWatch timer = new StopWatch();
timer.start();
CandidateResults candidateResults =
- entityIndex.search( indexEdge, searchTypes, "select * where testfield = 'test' order by ordinal", 100, 0 );
+ entityIndex.search( indexEdge, searchTypes, "select * where testfield = 'test' order by ordinal", 100, 0, false );
timer.stop();
@@ -182,11 +182,11 @@ public class EntityIndexTest extends BaseIT {
//make sure we can query uuids out as strings and not wrapped
candidateResults =
- entityIndex.search( indexEdge, searchTypes, "select * where testuuid = '"+uuid+"'", 100, 0 );
+ entityIndex.search( indexEdge, searchTypes, "select * where testuuid = '"+uuid+"'", 100, 0, false );
assertEquals(entity1.getId(),candidateResults.get(0).getId());
candidateResults =
- entityIndex.search( indexEdge, searchTypes, "select * where testuuid = "+uuid, 100, 0 );
+ entityIndex.search( indexEdge, searchTypes, "select * where testuuid = "+uuid, 100, 0, false);
assertEquals(entity1.getId(),candidateResults.get(0).getId());
}
@@ -369,7 +369,7 @@ public class EntityIndexTest extends BaseIT {
entityIndex.refreshAsync().toBlocking().first();
CandidateResults candidateResults = entityIndex
- .search( searchEdge, SearchTypes.fromTypes( entity.getId().getType() ), "name contains 'Ferrari*'", 10, 0 );
+ .search( searchEdge, SearchTypes.fromTypes( entity.getId().getType() ), "name contains 'Ferrari*'", 10, 0, false );
assertEquals( 1, candidateResults.size() );
EntityIndexBatch batch = entityIndex.createBatch();
@@ -378,7 +378,7 @@ public class EntityIndexTest extends BaseIT {
entityIndex.refreshAsync().toBlocking().first();
candidateResults = entityIndex
- .search(searchEdge, SearchTypes.fromTypes( entity.getId().getType() ), "name contains 'Ferrari*'", 10, 0 );
+ .search(searchEdge, SearchTypes.fromTypes( entity.getId().getType() ), "name contains 'Ferrari*'", 10, 0, false );
assertEquals(0, candidateResults.size());
}
@@ -390,7 +390,7 @@ public class EntityIndexTest extends BaseIT {
StopWatch timer = new StopWatch();
timer.start();
- CandidateResults candidateResults = entityIndex.search( scope, searchTypes, queryString, 1000, 0 );
+ CandidateResults candidateResults = entityIndex.search( scope, searchTypes, queryString, 1000, 0, false );
timer.stop();
@@ -518,7 +518,7 @@ public class EntityIndexTest extends BaseIT {
final String query = "where username = 'edanuff'";
- CandidateResults r = entityIndex.search( indexSCope, SearchTypes.fromTypes( "edanuff" ), query, 10, 0);
+ CandidateResults r = entityIndex.search( indexSCope, SearchTypes.fromTypes( "edanuff" ), query, 10, 0, false);
assertEquals( user.getId(), r.get( 0 ).getId());
batch.deindex( indexSCope, user.getId(), user.getVersion() );
@@ -528,7 +528,7 @@ public class EntityIndexTest extends BaseIT {
// EntityRef
- r = entityIndex.search( indexSCope, SearchTypes.fromTypes( "edanuff" ), query, 10, 0 );
+ r = entityIndex.search( indexSCope, SearchTypes.fromTypes( "edanuff" ), query, 10, 0, false );
assertFalse( r.iterator().hasNext() );
}
@@ -589,16 +589,16 @@ public class EntityIndexTest extends BaseIT {
final SearchTypes searchTypes = SearchTypes.fromTypes( "user" );
- CandidateResults r = entityIndex.search( indexScope, searchTypes, "where username = 'bill'", 10, 0);
+ CandidateResults r = entityIndex.search( indexScope, searchTypes, "where username = 'bill'", 10, 0, false);
assertEquals( bill.getId(), r.get( 0 ).getId() );
- r = entityIndex.search( indexScope, searchTypes, "where username = 'fred'", 10, 0);
+ r = entityIndex.search( indexScope, searchTypes, "where username = 'fred'", 10, 0, false);
assertEquals(fred.getId(), r.get(0).getId());
- r = entityIndex.search( indexScope, searchTypes, "where age = 41", 10, 0);
+ r = entityIndex.search( indexScope, searchTypes, "where age = 41", 10, 0, false);
assertEquals(fred.getId(), r.get(0).getId());
- r = entityIndex.search( indexScope, searchTypes, "where age = 'thirtysomething'", 10, 0);
+ r = entityIndex.search( indexScope, searchTypes, "where age = 'thirtysomething'", 10, 0, false);
assertEquals(bill.getId(), r.get(0).getId());
}
@@ -677,8 +677,8 @@ public class EntityIndexTest extends BaseIT {
int i ;
for ( i=0; i < expectedPages; i++ ) {
final CandidateResults results = !offset.isPresent()
- ? entityIndex.search( indexEdge, SearchTypes.allTypes(), query, limit, 0 )
- : entityIndex.search(indexEdge, SearchTypes.allTypes(), query, limit, i * limit);
+ ? entityIndex.search( indexEdge, SearchTypes.allTypes(), query, limit, 0, false )
+ : entityIndex.search(indexEdge, SearchTypes.allTypes(), query, limit, i * limit, false);
assertEquals(limit, results.size());
@@ -690,7 +690,7 @@ public class EntityIndexTest extends BaseIT {
}
//get our next page, we shouldn't get a cursor
- final CandidateResults results = entityIndex.search(indexEdge, SearchTypes.allTypes(), query, limit, i * limit);
+ final CandidateResults results = entityIndex.search(indexEdge, SearchTypes.allTypes(), query, limit, i * limit, false);
assertEquals( 0, results.size() );
assertFalse(results.hasOffset());
@@ -733,7 +733,7 @@ public class EntityIndexTest extends BaseIT {
final String query = "where searchUUID = " + searchUUID;
final CandidateResults r =
- entityIndex.search( indexSCope, SearchTypes.fromTypes(entityId.getType()), query, 10, 0);
+ entityIndex.search( indexSCope, SearchTypes.fromTypes(entityId.getType()), query, 10, 0, false);
assertEquals(user.getId(), r.get(0).getId());
}
@@ -772,7 +772,7 @@ public class EntityIndexTest extends BaseIT {
final String query = "where string = 'I am*'";
final CandidateResults r =
- entityIndex.search( indexSCope, SearchTypes.fromTypes( entityId.getType() ), query, 10, 0);
+ entityIndex.search( indexSCope, SearchTypes.fromTypes( entityId.getType() ), query, 10, 0, false);
assertEquals(user.getId(), r.get(0).getId());
@@ -780,7 +780,7 @@ public class EntityIndexTest extends BaseIT {
final String queryNoWildCard = "where string = 'I am'";
final CandidateResults noWildCardResults =
- entityIndex.search( indexSCope, SearchTypes.fromTypes( entityId.getType() ), queryNoWildCard, 10, 0 );
+ entityIndex.search( indexSCope, SearchTypes.fromTypes( entityId.getType() ), queryNoWildCard, 10, 0, false );
assertEquals( 0, noWildCardResults.size() );
}
@@ -830,7 +830,7 @@ public class EntityIndexTest extends BaseIT {
final String ascQuery = "order by string";
final CandidateResults ascResults =
- entityIndex.search(indexSCope, SearchTypes.fromTypes( first.getId().getType() ), ascQuery, 10 , 0);
+ entityIndex.search(indexSCope, SearchTypes.fromTypes( first.getId().getType() ), ascQuery, 10 , 0, false);
assertEquals( first.getId(), ascResults.get( 0).getId() );
@@ -841,7 +841,7 @@ public class EntityIndexTest extends BaseIT {
final String descQuery = "order by string desc";
final CandidateResults descResults =
- entityIndex.search(indexSCope, SearchTypes.fromTypes( first.getId().getType() ), descQuery, 10 , 0);
+ entityIndex.search(indexSCope, SearchTypes.fromTypes( first.getId().getType() ), descQuery, 10 , 0, false);
assertEquals( second.getId(), descResults.get( 0).getId() );
@@ -895,7 +895,7 @@ public class EntityIndexTest extends BaseIT {
final String singleMatchQuery = "string contains 'alpha' OR string contains 'foo'";
final CandidateResults singleResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), singleMatchQuery, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), singleMatchQuery, 10, 0, false );
assertEquals(1, singleResults.size());
@@ -906,7 +906,7 @@ public class EntityIndexTest extends BaseIT {
final String bothKeywordsMatch = "string contains 'alpha' OR string contains 'bravo'";
final CandidateResults singleKeywordUnion =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), bothKeywordsMatch, 10 , 0);
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), bothKeywordsMatch, 10 , 0, false);
assertEquals( 2, singleKeywordUnion.size() );
@@ -917,7 +917,7 @@ public class EntityIndexTest extends BaseIT {
final String twoKeywordMatches = "string contains 'alpha' OR string contains 'long'";
final CandidateResults towMatchResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), twoKeywordMatches, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), twoKeywordMatches, 10, 0, false );
assertEquals( 2, towMatchResults.size() );
@@ -976,7 +976,7 @@ public class EntityIndexTest extends BaseIT {
final String notFirst = "NOT int = 1";
final CandidateResults notFirstResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirst, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirst, 10, 0, false );
assertEquals( 1, notFirstResults.size() );
@@ -987,7 +987,7 @@ public class EntityIndexTest extends BaseIT {
final String notSecond = "NOT int = 2";
final CandidateResults notSecondUnion =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecond, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecond, 10, 0, false );
assertEquals( 1, notSecondUnion.size() );
@@ -997,7 +997,7 @@ public class EntityIndexTest extends BaseIT {
final String notBothReturn = "NOT int = 3";
final CandidateResults notBothReturnResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notBothReturn, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notBothReturn, 10, 0, false );
assertEquals( 2, notBothReturnResults.size() );
@@ -1008,7 +1008,7 @@ public class EntityIndexTest extends BaseIT {
final String notFilterBoth = "(NOT int = 1) AND (NOT int = 2) ";
final CandidateResults filterBoth =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFilterBoth, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFilterBoth, 10, 0, false );
assertEquals( 0, filterBoth.size() );
@@ -1016,7 +1016,7 @@ public class EntityIndexTest extends BaseIT {
final String noMatchesAnd = "(NOT int = 3) AND (NOT int = 4)";
final CandidateResults noMatchesAndResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesAnd, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesAnd, 10, 0, false );
assertEquals( 2, noMatchesAndResults.size() );
@@ -1027,7 +1027,7 @@ public class EntityIndexTest extends BaseIT {
final String noMatchesOr = "(NOT int = 3) AND (NOT int = 4)";
final CandidateResults noMatchesOrResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesOr, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesOr, 10, 0, false );
assertEquals( 2, noMatchesOrResults.size() );
@@ -1086,7 +1086,7 @@ public class EntityIndexTest extends BaseIT {
final String notFirst = "NOT string = 'I ate a sammich'";
final CandidateResults notFirstResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirst, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirst, 10, 0, false );
assertEquals( 1, notFirstResults.size() );
@@ -1096,7 +1096,7 @@ public class EntityIndexTest extends BaseIT {
final String notFirstWildCard = "NOT string = 'I ate*'";
final CandidateResults notFirstWildCardResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirstWildCard, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirstWildCard, 10, 0, false );
assertEquals( 1, notFirstWildCardResults.size() );
@@ -1106,7 +1106,7 @@ public class EntityIndexTest extends BaseIT {
final String notFirstContains = "NOT string contains 'sammich'";
final CandidateResults notFirstContainsResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirstContains, 10 , 0);
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFirstContains, 10 , 0, false);
assertEquals( 1, notFirstContainsResults.size() );
@@ -1117,7 +1117,7 @@ public class EntityIndexTest extends BaseIT {
final String notSecond = "NOT string = 'I drank a beer'";
final CandidateResults notSecondUnion =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecond, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecond, 10, 0, false );
assertEquals( 1, notSecondUnion.size() );
@@ -1127,7 +1127,7 @@ public class EntityIndexTest extends BaseIT {
final String notSecondWildcard = "NOT string = 'I drank*'";
final CandidateResults notSecondWildcardUnion =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecondWildcard, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecondWildcard, 10, 0, false );
assertEquals( 1, notSecondWildcardUnion.size() );
@@ -1137,7 +1137,7 @@ public class EntityIndexTest extends BaseIT {
final String notSecondContains = "NOT string contains 'beer'";
final CandidateResults notSecondContainsUnion =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecondContains, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notSecondContains, 10, 0, false );
assertEquals( 1, notSecondContainsUnion.size() );
@@ -1147,7 +1147,7 @@ public class EntityIndexTest extends BaseIT {
final String notBothReturn = "NOT string = 'I'm a foodie'";
final CandidateResults notBothReturnResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notBothReturn, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notBothReturn, 10, 0, false );
assertEquals( 2, notBothReturnResults.size() );
@@ -1158,7 +1158,7 @@ public class EntityIndexTest extends BaseIT {
final String notFilterBoth = "(NOT string = 'I ate a sammich') AND (NOT string = 'I drank a beer') ";
final CandidateResults filterBoth =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFilterBoth, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), notFilterBoth, 10, 0, false );
assertEquals( 0, filterBoth.size() );
@@ -1166,7 +1166,7 @@ public class EntityIndexTest extends BaseIT {
final String noMatchesAnd = "(NOT string = 'I ate*') AND (NOT string = 'I drank*')";
final CandidateResults noMatchesAndResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesAnd, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesAnd, 10, 0, false );
assertEquals( 0, noMatchesAndResults.size() );
@@ -1174,7 +1174,7 @@ public class EntityIndexTest extends BaseIT {
final String noMatchesContainsAnd = "(NOT string contains 'ate') AND (NOT string contains 'drank')";
final CandidateResults noMatchesContainsAndResults = entityIndex
- .search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesContainsAnd, 10, 0 );
+ .search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesContainsAnd, 10, 0, false );
assertEquals( 0, noMatchesContainsAndResults.size() );
@@ -1183,7 +1183,7 @@ public class EntityIndexTest extends BaseIT {
final String noMatchesOr = "(NOT string = 'I ate*') AND (NOT string = 'I drank*')";
final CandidateResults noMatchesOrResults =
- entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesOr, 10, 0 );
+ entityIndex.search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesOr, 10, 0, false );
assertEquals( 0, noMatchesOrResults.size() );
@@ -1191,7 +1191,7 @@ public class EntityIndexTest extends BaseIT {
final String noMatchesContainsOr = "(NOT string contains 'ate') AND (NOT string contains 'drank')";
final CandidateResults noMatchesContainsOrResults = entityIndex
- .search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesContainsOr, 10, 0 );
+ .search(indexScope1, SearchTypes.fromTypes( first.getId().getType() ), noMatchesContainsOr, 10, 0, false );
assertEquals( 0, noMatchesContainsOrResults.size() );
@@ -1236,7 +1236,7 @@ public class EntityIndexTest extends BaseIT {
indexProducer.put(batch.build()).subscribe();;
entityIndex.refreshAsync().toBlocking().first();
- long size = entityIndex.getEntitySize(new SearchEdgeImpl(ownerId,type, SearchEdge.NodeType.SOURCE));
+ long size = entityIndex.getTotalEntitySizeInBytes(new SearchEdgeImpl(ownerId,type, SearchEdge.NodeType.SOURCE));
assertTrue( size == 100 );
}
@@ -1289,7 +1289,7 @@ public class EntityIndexTest extends BaseIT {
StopWatch timer = new StopWatch();
timer.start();
CandidateResults candidateResults =
- entityIndex.search( indexEdge, searchTypes, "select * where uuid = '"+uuid+"'", 100, 0 );
+ entityIndex.search( indexEdge, searchTypes, "select * where uuid = '"+uuid+"'", 100, 0, false );
timer.stop();
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoPagingTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoPagingTest.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoPagingTest.java
index 3d68fe1..ba33030 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoPagingTest.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoPagingTest.java
@@ -138,7 +138,7 @@ public class GeoPagingTest extends BaseIT {
final String query = "select * where location within 1500000 of 37, -75" ;
final CandidateResults
- candidates = entityIndex.search( edge, SearchTypes.fromTypes( "cat" ), query, 100, 0 );
+ candidates = entityIndex.search( edge, SearchTypes.fromTypes( "cat" ), query, 100, 0, false );
assertNotNull( candidates );
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/IndexLoadTestsIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/IndexLoadTestsIT.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/IndexLoadTestsIT.java
index afaebb7..a5c3b53 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/IndexLoadTestsIT.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/IndexLoadTestsIT.java
@@ -223,7 +223,7 @@ public class IndexLoadTestsIT extends BaseIT {
.search( searchEdge, SearchTypes.fromTypes( searchEdge.getEdgeName() ),
"select * where " + FIELD_WORKER_INDEX + " = " + workerIndex + " AND " + FIELD_ORDINAL
+ " = " + ordinal + " AND " + FIELD_UNIQUE_IDENTIFIER + " = '" + uniqueIdentifier
- + "'" , 100 , 0);
+ + "'" , 100 , 0, false);
queryTps.mark();
queryTimerContext.stop();
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/rest/src/main/java/org/apache/usergrid/rest/applications/CollectionResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/CollectionResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/CollectionResource.java
index 898eb3b..b8c1caa 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/CollectionResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/CollectionResource.java
@@ -18,16 +18,10 @@
package org.apache.usergrid.rest.applications;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -35,7 +29,6 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.PathSegment;
-import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.springframework.context.annotation.Scope;
@@ -44,25 +37,15 @@ import org.springframework.stereotype.Component;
import org.apache.commons.lang.NullArgumentException;
import org.apache.commons.lang.StringUtils;
-import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilder;
-import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilderImpl;
-import org.apache.usergrid.corepersistence.index.ReIndexService;
import org.apache.usergrid.persistence.Query;
-import org.apache.usergrid.persistence.exceptions.RequiredPropertyNotFoundException;
-import org.apache.usergrid.persistence.index.utils.UUIDUtils;
-import org.apache.usergrid.rest.AbstractContextResource;
import org.apache.usergrid.rest.ApiResponse;
-import org.apache.usergrid.rest.RootResource;
-import org.apache.usergrid.rest.exceptions.RequiredPropertyNotFoundExceptionMapper;
import org.apache.usergrid.rest.security.annotations.RequireApplicationAccess;
import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
import org.apache.usergrid.rest.system.IndexResource;
-import org.apache.usergrid.services.AbstractCollectionService;
import org.apache.usergrid.services.ServiceAction;
import org.apache.usergrid.services.ServiceParameter;
import org.apache.usergrid.services.ServicePayload;
-import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
index 91c7db9..3835b75 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
@@ -32,7 +32,6 @@ import org.apache.usergrid.rest.ApiResponse;
import org.apache.usergrid.rest.RootResource;
import org.apache.usergrid.rest.applications.assets.AssetsResource;
import org.apache.usergrid.rest.security.annotations.CheckPermissionsForPath;
-import org.apache.usergrid.rest.security.annotations.RequireApplicationAccess;
import org.apache.usergrid.security.oauth.AccessInfo;
import org.apache.usergrid.services.*;
import org.apache.usergrid.services.assets.data.AssetUtils;
@@ -262,7 +261,7 @@ public class ServiceResource extends AbstractContextResource {
addQueryParams( getServiceParameters(), ui );
ServiceRequest r = services.newRequest( action, tree, getServiceParameters(), payload,
- returnInboundConnections, returnOutboundConnections );
+ returnInboundConnections, returnOutboundConnections, false);
response.setServiceRequest( r );
@@ -316,7 +315,7 @@ public class ServiceResource extends AbstractContextResource {
addQueryParams( getServiceParameters(), ui );
ServiceRequest r = services.newRequest( action, tree, getServiceParameters(), payload,
- returnInboundConnections, returnOutboundConnections );
+ returnInboundConnections, returnOutboundConnections, false);
response.setServiceRequest( r );
@@ -400,13 +399,15 @@ public class ServiceResource extends AbstractContextResource {
}
}
+ boolean analyzeQueryOnly = Boolean.valueOf(ui.getQueryParameters().getFirst("analyzeOnly"));
+
boolean collectionGet = false;
if ( action == ServiceAction.GET ) {
collectionGet = getServiceParameters().size() == 1;
}
addQueryParams( getServiceParameters(), ui );
ServiceRequest r = services.newRequest( action, tree, getServiceParameters(), payload,
- returnInboundConnections, returnOutboundConnections );
+ returnInboundConnections, returnOutboundConnections, analyzeQueryOnly);
response.setServiceRequest( r );
ServiceResults results = r.execute();
if ( results != null ) {
http://git-wip-us.apache.org/repos/asf/usergrid/blob/a4941462/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
index 4a4b8b0..807e0c9 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/AbstractExceptionMapper.java
@@ -71,11 +71,11 @@ public abstract class AbstractExceptionMapper<E extends java.lang.Throwable> imp
if ( status >= 500 ) {
// only log real errors as errors
- logger.error( "{} 5XX Uncaught Exception ({})", e.getClass().getCanonicalName(), status, e );
+ logger.error( "{} 5XX Uncaught Exception ({}), {}", e.getClass().getCanonicalName(), status, e );
} else {
if (logger.isDebugEnabled()) {
- logger.debug( "{} Following Exception Thrown ({})", e.getClass().getCanonicalName(), status, e );
+ logger.debug( "{} Following Exception Thrown ({}), {}", e.getClass().getCanonicalName(), status, e );
}
}
@@ -98,12 +98,19 @@ public abstract class AbstractExceptionMapper<E extends java.lang.Throwable> imp
public Response toResponse( Status status, String jsonResponse ) {
- return toResponse( status.getStatusCode(), jsonResponse );
+ return toResponse( status.getStatusCode(), jsonResponse, false );
}
+ public Response toResponse( Status status, String jsonResponse, boolean skipLogging ) {
+ return toResponse( status.getStatusCode(), jsonResponse, skipLogging );
+ }
- protected Response toResponse( int status, String jsonResponse ) {
- if ( status >= 500 ) {
+ public Response toResponse( int statusCode, String jsonResponse ) {
+ return toResponse( statusCode, jsonResponse, false );
+ }
+
+ protected Response toResponse( int status, String jsonResponse, boolean skipLogging ) {
+ if ( status >= 500 && !skipLogging) {
// only log real errors as errors
logger.error( "Server Error ({}):\n{}", status, jsonResponse );
} else if ( logger.isDebugEnabled() ) {
[3/4] usergrid git commit: Add query analyzer condition for full
collection sorts when the collection size exceeds the limit. Add
QueryAnalyzer tests.
Posted by mr...@apache.org.
Add query analyzer condition for full collection sorts when the collection size exceeds the limit. Add QueryAnalyzer tests.
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/f556e42b
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/f556e42b
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/f556e42b
Branch: refs/heads/master
Commit: f556e42b0fafb41a5674812a1f83235bc1008bde
Parents: a494146
Author: Michael Russo <ru...@google.com>
Authored: Sat Feb 25 15:43:10 2017 -0800
Committer: Michael Russo <ru...@google.com>
Committed: Sat Feb 25 15:43:10 2017 -0800
----------------------------------------------------------------------
.../usergrid/persistence/index/IndexFig.java | 2 +-
.../persistence/index/QueryAnalyzer.java | 14 ++
.../index/impl/QueryAnalyzerTest.java | 169 +++++++++++++++++++
3 files changed, 184 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/f556e42b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
index e23961c..4091e5e 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/IndexFig.java
@@ -225,7 +225,7 @@ public interface IndexFig extends GuicyFig {
int getQueryBreakerErrorSortPredicateCount();
- @Default("500000000L") // 500 MB
+ @Default("500000000") // 500 MB
@Key(USERGRID_QUERYANALYZER_COLLECTIONSIZE)
long getQueryBreakerErrorCollectionSizeBytes();
http://git-wip-us.apache.org/repos/asf/usergrid/blob/f556e42b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java
index 86f1e5d..6d3cd92 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/QueryAnalyzer.java
@@ -31,6 +31,7 @@ public class QueryAnalyzer {
public static final String v_operand_count = "operand_count_exceeded";
public static final String v_large_collection = "large_collection_size_bytes";
public static final String v_large_index = "large_index_size_bytes";
+ public static final String v_full_collection_sort = "full_collection_sort";
public static final String k_violation = "violation";
public static final String k_limit = "limit";
@@ -69,6 +70,19 @@ public class QueryAnalyzer {
put(k_limit, errorCollectionSizeBytes);
put(k_actual, collectionSizeInBytes);
}});
+
+ // query like "select * order by created asc"
+ if(parsedQuery.getSelectFieldMappings().size() < 1 &&
+ !parsedQuery.getOriginalQuery().toLowerCase().contains("where") &&
+ parsedQuery.getSortPredicates().size() > 0 ){
+
+ violations.add(new HashMap<String, Object>(3){{
+ put(k_violation, v_full_collection_sort);
+ put(k_limit, null);
+ put(k_actual, null);
+ }});
+ }
+
}
// complex queries can be determined from the # of operands and sort predicates
http://git-wip-us.apache.org/repos/asf/usergrid/blob/f556e42b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/QueryAnalyzerTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/QueryAnalyzerTest.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/QueryAnalyzerTest.java
new file mode 100644
index 0000000..8c319c0
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/QueryAnalyzerTest.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.usergrid.persistence.index.impl;
+
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.usergrid.persistence.index.IndexFig;
+import org.apache.usergrid.persistence.index.QueryAnalyzer;
+import org.apache.usergrid.persistence.index.query.ParsedQuery;
+import org.apache.usergrid.persistence.index.query.ParsedQueryBuilder;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.*;
+
+public class QueryAnalyzerTest extends BaseIT {
+
+ private static final Logger logger = LoggerFactory.getLogger(QueryAnalyzerTest.class);
+
+ private IndexFig fig;
+
+ @Before
+ public void setup() {
+
+ // the mock will return 0/empty values for all fig items
+ fig = mock ( IndexFig.class );
+
+ }
+
+ @Test
+ public void testNoViolations() throws Throwable {
+
+ when ( fig.getQueryBreakerErrorSortPredicateCount() ).thenReturn( 5 );
+ when ( fig.getQueryBreakerErrorOperandCount() ).thenReturn( 5 );
+ when ( fig.getQueryBreakerErrorIndexSizeBytes() ).thenReturn( 5L );
+ when ( fig.getQueryBreakerErrorCollectionSizeBytes() ).thenReturn( 5L );
+
+ ParsedQuery parsedQuery;
+ List<Map<String,Object>> violations;
+
+
+ parsedQuery = ParsedQueryBuilder.build("select * order by created asc");
+ violations = QueryAnalyzer.analyze(parsedQuery, 1, 1, fig );
+ assertEquals(0, violations.size());
+
+ parsedQuery = ParsedQueryBuilder.build("select name='value' order by created asc");
+ violations = QueryAnalyzer.analyze(parsedQuery, 1, 1, fig );
+ assertEquals(0, violations.size());
+
+ parsedQuery = ParsedQueryBuilder.build("where name='value'");
+ violations = QueryAnalyzer.analyze(parsedQuery, 1, 1, fig );
+ assertEquals(0, violations.size());
+
+
+ }
+
+
+ @Test
+ public void IndexSizeViolation() throws Throwable {
+
+
+ ParsedQuery parsedQuery = ParsedQueryBuilder.build("select created order by created asc");
+ List<Map<String,Object>> violations;
+ violations = QueryAnalyzer.analyze(parsedQuery, 0, 1, fig );
+ boolean violationExists = violationExists(violations, QueryAnalyzer.v_large_index);
+
+ if(!violationExists){
+ fail("Index Size Violation should be present");
+ }
+
+ }
+
+ @Test
+ public void collectionSizeViolation() throws Throwable {
+
+ // the sort violation is only tripped when the collection size warning is tripped
+ when ( fig.getQueryBreakerErrorCollectionSizeBytes() ).thenReturn( 0L );
+
+ ParsedQuery parsedQuery = ParsedQueryBuilder.build("select created order by created asc");
+ List<Map<String,Object>> violations;
+ violations = QueryAnalyzer.analyze(parsedQuery, 1, 1, fig );
+ boolean violationExists = violationExists(violations, QueryAnalyzer.v_large_collection);
+
+ if(!violationExists){
+ fail("Collection Size Violation should be present");
+ }
+
+ }
+
+
+ @Test
+ public void fullSortViolation() throws Throwable {
+
+ ParsedQuery parsedQuery = ParsedQueryBuilder.build("select * order by created asc");
+ List<Map<String,Object>> violations;
+ violations = QueryAnalyzer.analyze(parsedQuery, 1, 1, fig );
+ boolean violationExists = violationExists(violations, QueryAnalyzer.v_full_collection_sort);
+
+ if(!violationExists){
+ fail("Full Collection Sort Violation should be present");
+ }
+
+ }
+
+ @Test
+ public void operandCountViolation() throws Throwable {
+
+ ParsedQuery parsedQuery = ParsedQueryBuilder.build("where name='value'");
+ List<Map<String,Object>> violations;
+ violations = QueryAnalyzer.analyze(parsedQuery, 0, 0, fig );
+ boolean violationExists = violationExists(violations, QueryAnalyzer.v_operand_count);
+
+ if(!violationExists){
+ fail("Operand Count Violation should be present");
+ }
+
+ }
+
+ @Test
+ public void predicateCountViolation() throws Throwable {
+
+ ParsedQuery parsedQuery = ParsedQueryBuilder.build("where name='value'");
+ List<Map<String,Object>> violations;
+ violations = QueryAnalyzer.analyze(parsedQuery, 0, 0, fig );
+ boolean violationExists = violationExists(violations, QueryAnalyzer.v_operand_count);
+
+ if(!violationExists){
+ fail("Operand Count Violation should be present");
+ }
+
+ }
+
+
+
+ private boolean violationExists(final List<Map<String,Object>> violations, final String expectedViolation){
+ for ( Map<String, Object> violation : violations ){
+ if (violation.get(QueryAnalyzer.k_violation) == expectedViolation){
+ return true;
+ }
+
+ }
+ return false;
+ }
+
+}
+
+
+
[4/4] usergrid git commit: Merge commit 'refs/pull/567/head' of
github.com:apache/usergrid
Posted by mr...@apache.org.
Merge commit 'refs/pull/567/head' of github.com:apache/usergrid
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/d9211085
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/d9211085
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/d9211085
Branch: refs/heads/master
Commit: d92110853e17ab4a67b19ab8b0c28a48584883ce
Parents: 3b1b0ca f556e42
Author: Michael Russo <ru...@google.com>
Authored: Thu Mar 23 13:27:42 2017 -0700
Committer: Michael Russo <ru...@google.com>
Committed: Thu Mar 23 13:27:42 2017 -0700
----------------------------------------------------------------------
.../corepersistence/CpRelationManager.java | 9 +
.../pipeline/builder/IdBuilder.java | 10 +-
.../pipeline/read/FilterFactory.java | 7 +-
.../search/AbstractElasticSearchFilter.java | 21 ++-
.../read/search/SearchCollectionFilter.java | 5 +-
.../read/search/SearchConnectionFilter.java | 5 +-
.../service/AggregationServiceImpl.java | 6 +-
.../service/CollectionSearch.java | 10 ++
.../service/CollectionServiceImpl.java | 2 +-
.../service/ConnectionSearch.java | 12 ++
.../service/ConnectionServiceImpl.java | 4 +-
.../org/apache/usergrid/persistence/Query.java | 9 +
.../org/apache/usergrid/utils/JsonUtils.java | 2 +-
.../corepersistence/StaleIndexCleanupTest.java | 2 +-
.../index/AsyncIndexServiceTest.java | 2 +-
.../corepersistence/index/IndexServiceTest.java | 8 +-
.../usergrid/persistence/index/EntityIndex.java | 11 +-
.../usergrid/persistence/index/IndexFig.java | 39 +++++
.../persistence/index/QueryAnalyzer.java | 143 ++++++++++++++++
.../QueryAnalyzerEnforcementException.java | 45 +++++
.../exceptions/QueryAnalyzerException.java | 57 +++++++
.../index/impl/EsEntityIndexImpl.java | 61 ++++++-
.../persistence/index/impl/EntityIndexTest.java | 86 +++++-----
.../persistence/index/impl/GeoPagingTest.java | 2 +-
.../index/impl/IndexLoadTestsIT.java | 2 +-
.../index/impl/QueryAnalyzerTest.java | 169 +++++++++++++++++++
.../rest/applications/CollectionResource.java | 17 --
.../rest/applications/ServiceResource.java | 9 +-
.../exceptions/AbstractExceptionMapper.java | 17 +-
...QueryAnalyzerEnforcementExceptionMapper.java | 51 ++++++
.../QueryAnalyzerExceptionMapper.java | 69 ++++++++
.../usergrid/services/AbstractService.java | 2 +
.../usergrid/services/ServiceManager.java | 15 +-
.../usergrid/services/ServiceRequest.java | 26 ++-
34 files changed, 809 insertions(+), 126 deletions(-)
----------------------------------------------------------------------