use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.
the class CachedResultsBean method getRows.
/**
* Returns a set of rows based on the given starting and end positions. The response object type is dynamic, see the listQueryLogic operation to determine
* what the response type object will be.
*
* @param queryId
* CachedResults queryId
* @param rowBegin
* first row to be returned
* @param rowEnd
* last row to be returned
* @return datawave.webservice.result.BaseQueryResponse
* @RequestHeader X-ProxiedEntitiesChain use when proxying request for user by specifying a chain of DNs of the identities to proxy
* @RequestHeader X-ProxiedIssuersChain required when using X-ProxiedEntitiesChain, specify one issuer DN per subject DN listed in X-ProxiedEntitiesChain
* @RequestHeader query-session-id session id value used for load balancing purposes. query-session-id can be placed in the request in a Cookie header or as
* a query parameter
* @ResponseHeader X-OperationTimeInMS time spent on the server performing the operation, does not account for network or result serialization
* @ResponseHeader X-Partial-Results true if the page contains less than the requested number of results
*
* @HTTP 200 success
* @HTTP 401 caller is not authorized to run the query
* @HTTP 412 if the query is not active
* @HTTP 500 internal server error
*/
@GET
@javax.ws.rs.Path("/{queryId}/getRows")
@Produces({ "application/xml", "text/xml", "application/json", "text/yaml", "text/x-yaml", "application/x-yaml", "application/x-protobuf" })
@GZIP
@Interceptors({ RequiredInterceptor.class, ResponseInterceptor.class })
@Timed(name = "dw.cachedr.getRows", absolute = true)
public BaseQueryResponse getRows(@PathParam("queryId") @Required("queryId") String queryId, @QueryParam("rowBegin") @DefaultValue("1") Integer rowBegin, @QueryParam("rowEnd") Integer rowEnd) {
BaseQueryResponse response = responseObjectFactory.getEventQueryResponse();
// Find out who/what called this method
Principal p = ctx.getCallerPrincipal();
String owner = getOwnerFromPrincipal(p);
try {
if (rowBegin < 1) {
throw new BadRequestQueryException(DatawaveErrorCode.ROW_BEGIN_LESS_THAN_1);
}
if (rowEnd != null && rowEnd < rowBegin) {
throw new BadRequestQueryException(DatawaveErrorCode.ROW_END_LESS_THAN_ROW_BEGIN);
}
// If there is a this.maxPageSize set, then we should honor it here. Otherwise, we use Integer.MAX_VALUE
int maxPageSize = cachedResultsConfiguration.getMaxPageSize();
if (rowEnd == null) {
if (maxPageSize > 0) {
rowEnd = (rowBegin + maxPageSize) - 1;
} else {
rowEnd = Integer.MAX_VALUE;
}
}
int pagesize = (rowEnd - rowBegin) + 1;
if (maxPageSize > 0 && pagesize > maxPageSize) {
throw new QueryException(DatawaveErrorCode.TOO_MANY_ROWS_REQUESTED, MessageFormat.format("Size must be less than or equal to: {0}", maxPageSize));
}
CachedRunningQuery crq = null;
try {
// Get the CachedRunningQuery object from the cache
try {
crq = retrieve(queryId, owner);
} catch (IOException e) {
throw new PreConditionFailedQueryException(DatawaveErrorCode.CACHED_RESULTS_IMPORT_ERROR, e);
}
if (null == crq)
throw new PreConditionFailedQueryException(DatawaveErrorCode.QUERY_NOT_CACHED);
response = crq.getQueryLogic().getResponseObjectFactory().getEventQueryResponse();
if (!crq.getUser().equals(owner)) {
throw new UnauthorizedQueryException(DatawaveErrorCode.QUERY_OWNER_MISMATCH, MessageFormat.format("{0} != {1}", crq.getUser(), owner));
}
synchronized (crq) {
if (crq.isActivated() == false) {
Connection connection = ds.getConnection();
String logicName = crq.getQueryLogicName();
QueryLogic<?> queryLogic = queryFactory.getQueryLogic(logicName, p);
crq.activate(connection, queryLogic);
}
try {
ResultsPage resultList = crq.getRows(rowBegin, rowEnd, cachedResultsConfiguration.getPageByteTrigger());
response = crq.getTransformer().createResponse(resultList);
Status status;
if (!resultList.getResults().isEmpty()) {
response.setHasResults(true);
status = Status.OK;
} else {
response.setHasResults(false);
status = Status.NO_CONTENT;
}
response.setLogicName(crq.getQueryLogic().getLogicName());
response.setQueryId(crq.getQueryId());
if (response instanceof TotalResultsAware) {
((TotalResultsAware) response).setTotalResults(crq.getTotalRows());
}
if (status == Status.NO_CONTENT) {
throw new NoResultsQueryException(DatawaveErrorCode.NO_CONTENT_STATUS);
}
crq.getMetric().setLifecycle(QueryMetric.Lifecycle.RESULTS);
return response;
} catch (SQLException e) {
throw new QueryException();
} catch (NoResultsQueryException e) {
throw e;
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
throw e;
} finally {
crq.closeConnection(log);
}
}
} finally {
// Push metrics
try {
if (null != crq && crq.getQueryLogic().getCollectQueryMetrics() == true) {
metrics.updateMetric(crq.getMetric());
}
} catch (Exception e1) {
log.error("Error updating metrics", e1);
}
}
} catch (Exception e) {
DatawaveErrorCode dec;
if (e instanceof NoResultsQueryException) {
dec = DatawaveErrorCode.NO_CONTENT_STATUS;
} else {
dec = DatawaveErrorCode.CACHED_QUERY_TRANSACTION_ERROR;
}
QueryException qe = new QueryException(dec, e);
log.error(qe);
response.addException(qe.getBottomQueryException());
int statusCode = qe.getBottomQueryException().getStatusCode();
throw new DatawaveWebApplicationException(qe, response, statusCode);
}
}
use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.
the class CachedResultsBean method previous.
/**
* Returns the previous page of results to the caller. The response object type is dynamic, see the listQueryLogic operation to determine what the response
* type object will be.
*
* @param queryId
* user defined id for this query
* @return previous page of results
*
* @return datawave.webservice.result.BaseQueryResponse
* @RequestHeader X-ProxiedEntitiesChain use when proxying request for user by specifying a chain of DNs of the identities to proxy
* @RequestHeader X-ProxiedIssuersChain required when using X-ProxiedEntitiesChain, specify one issuer DN per subject DN listed in X-ProxiedEntitiesChain
* @RequestHeader query-session-id session id value used for load balancing purposes. query-session-id can be placed in the request in a Cookie header or as
* a query parameter
* @ResponseHeader X-OperationTimeInMS time spent on the server performing the operation, does not account for network or result serialization
* @ResponseHeader X-query-page-number page number returned by this call
* @ResponseHeader X-query-last-page if true then there are no more pages for this query, caller should call close()
* @ResponseHeader X-Partial-Results true if the page contains less than the requested number of results
*
* @HTTP 200 success
* @HTTP 401 caller is not authorized to run the query
* @HTTP 412 if the query is not active
* @HTTP 500 internal server error
*/
@GET
@javax.ws.rs.Path("/{queryId}/previous")
@Produces({ "application/xml", "text/xml", "application/json", "text/yaml", "text/x-yaml", "application/x-yaml", "application/x-protobuf" })
@GZIP
@Interceptors({ RequiredInterceptor.class, ResponseInterceptor.class })
@Timed(name = "dw.cachedr.previous", absolute = true)
public BaseQueryResponse previous(@PathParam("queryId") @Required("queryId") String queryId) {
BaseQueryResponse response = responseObjectFactory.getEventQueryResponse();
// Find out who/what called this method
Principal p = ctx.getCallerPrincipal();
String owner = getOwnerFromPrincipal(p);
try {
CachedRunningQuery crq = null;
try {
// Get the CachedRunningQuery object from the cache
try {
crq = retrieve(queryId, owner);
} catch (IOException e) {
throw new PreConditionFailedQueryException(DatawaveErrorCode.CACHED_RESULTS_IMPORT_ERROR, e);
}
if (null == crq)
throw new PreConditionFailedQueryException(DatawaveErrorCode.QUERY_NOT_CACHED);
if (!crq.getUser().equals(owner)) {
throw new UnauthorizedQueryException(DatawaveErrorCode.QUERY_OWNER_MISMATCH, MessageFormat.format("{0} != {1}", crq.getUser(), owner));
}
synchronized (crq) {
if (crq.isActivated() == false) {
if (crq.getShouldAutoActivate()) {
Connection connection = ds.getConnection();
String logicName = crq.getQueryLogicName();
QueryLogic<?> queryLogic = queryFactory.getQueryLogic(logicName, p);
crq.activate(connection, queryLogic);
} else {
throw new PreConditionFailedQueryException(DatawaveErrorCode.QUERY_TIMEOUT_FOR_RESOURCES);
}
}
try {
ResultsPage resultList = crq.previous(cachedResultsConfiguration.getPageByteTrigger());
long pageNum = crq.getLastPageNumber();
response = crq.getTransformer().createResponse(resultList);
Status status = null;
if (!resultList.getResults().isEmpty()) {
response.setHasResults(true);
status = Status.OK;
} else {
response.setHasResults(false);
status = Status.NO_CONTENT;
}
response.setPageNumber(pageNum);
response.setLogicName(crq.getQueryLogic().getLogicName());
response.setQueryId(crq.getQueryId());
if (response instanceof TotalResultsAware) {
((TotalResultsAware) response).setTotalResults(crq.getTotalRows());
}
if (status == Status.NO_CONTENT) {
throw new NoResultsException(null);
}
crq.getMetric().setLifecycle(QueryMetric.Lifecycle.RESULTS);
return response;
} catch (SQLException e) {
throw new QueryException(DatawaveErrorCode.CACHED_QUERY_SQL_ERROR, e);
}
}
} finally {
// Push metrics
if (null != crq && crq.getQueryLogic().getCollectQueryMetrics() == true) {
try {
metrics.updateMetric(crq.getMetric());
} catch (Exception e1) {
log.error("Error updating metrics", e1);
}
}
}
} catch (Exception e) {
QueryException qe = null;
if (e instanceof NoResultsException) {
qe = new QueryException(DatawaveErrorCode.NO_CONTENT_STATUS, e);
} else {
qe = new QueryException("Error calling previous.", e, "500-42");
log.error(qe);
}
response.addException(qe.getBottomQueryException());
int statusCode = qe.getBottomQueryException().getStatusCode();
throw new DatawaveWebApplicationException(qe, response, statusCode);
}
}
use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.
the class CachedResultsBean method cancelLoad.
/**
* Cancel the load process.
*
* @param originalQueryId
*
* @return datawave.webservice.result.VoidResponse
* @RequestHeader X-ProxiedEntitiesChain use when proxying request for user by specifying a chain of DNs of the identities to proxy
* @RequestHeader X-ProxiedIssuersChain required when using X-ProxiedEntitiesChain, specify one issuer DN per subject DN listed in X-ProxiedEntitiesChain
* @RequestHeader query-session-id session id value used for load balancing purposes. query-session-id can be placed in the request in a Cookie header or as
* a query parameter
* @ResponseHeader X-OperationTimeInMS time spent on the server performing the operation, does not account for network or result serialization
*
* @HTTP 200 success
* @HTTP 401 caller is not authorized to cancel the query
*/
@PUT
@Produces({ "application/xml", "text/xml", "application/json", "text/yaml", "text/x-yaml", "application/x-yaml", "application/x-protobuf", "application/x-protostuff" })
@javax.ws.rs.Path("/{queryId}/cancel")
@GZIP
@ClearQuerySessionId
@Interceptors({ RequiredInterceptor.class, ResponseInterceptor.class })
@Timed(name = "dw.cachedr.cancel", absolute = true)
public VoidResponse cancelLoad(@PathParam("queryId") @Required("queryId") String originalQueryId) {
// Find out who/what called this method
Principal p = ctx.getCallerPrincipal();
String owner = getOwnerFromPrincipal(p);
VoidResponse response = new VoidResponse();
try {
// check if query is even loading
RunningQuery query = CachedResultsBean.loadingQueryMap.get(originalQueryId);
if (query == null) {
NotFoundQueryException e = new NotFoundQueryException(DatawaveErrorCode.NO_QUERY_OBJECT_MATCH);
throw new NotFoundException(e, response);
} else {
if (query.getSettings().getOwner().equals(owner)) {
accumuloConnectionRequestBean.cancelConnectionRequest(originalQueryId);
query.cancel();
response.addMessage("CachedResults load canceled.");
} else {
UnauthorizedQueryException e = new UnauthorizedQueryException(DatawaveErrorCode.QUERY_OWNER_MISMATCH, MessageFormat.format("{0} != {1}", query.getSettings().getOwner(), owner));
throw new UnauthorizedException(e, response);
}
}
return response;
} catch (DatawaveWebApplicationException e) {
throw e;
} catch (Exception e) {
QueryException qe = new QueryException(DatawaveErrorCode.CANCELLATION_ERROR, e, MessageFormat.format("query_id: {0}", originalQueryId));
log.error(qe);
response.addException(qe.getBottomQueryException());
int statusCode = qe.getBottomQueryException().getStatusCode();
throw new DatawaveWebApplicationException(qe, response, statusCode);
}
}
use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.
the class AtomServiceBean method getCategories.
/**
* @return Atom Categories document that lists category names
*/
@GET
@GZIP
@Produces("application/atomcat+xml")
@Path("/categories")
public Categories getCategories() {
Principal p = ctx.getCallerPrincipal();
Set<Authorizations> auths = new HashSet<>();
if (p instanceof DatawavePrincipal) {
DatawavePrincipal dp = (DatawavePrincipal) p;
for (Collection<String> cbAuths : dp.getAuthorizations()) auths.add(new Authorizations(cbAuths.toArray(new String[cbAuths.size()])));
}
Categories result;
Connector connection = null;
try {
result = abdera.newCategories();
Map<String, String> trackingMap = connectionFactory.getTrackingMap(Thread.currentThread().getStackTrace());
connection = connectionFactory.getConnection(poolName, Priority.NORMAL, trackingMap);
try (Scanner scanner = ScannerHelper.createScanner(connection, tableName + "Categories", auths)) {
Map<String, String> props = new HashMap<>();
props.put(MatchingKeySkippingIterator.ROW_DELIMITER_OPTION, "\0");
props.put(MatchingKeySkippingIterator.NUM_SCANS_STRING_NAME, "5");
IteratorSetting setting = new IteratorSetting(30, MatchingKeySkippingIterator.class, props);
scanner.addScanIterator(setting);
for (Map.Entry<Key, Value> entry : scanner) {
String collectionName = entry.getKey().getRow().toString();
result.addCategory(collectionName);
}
}
if (result.getCategories().isEmpty())
throw new NoResultsException(null);
else
return result;
} catch (WebApplicationException web) {
throw web;
} catch (Exception e) {
VoidResponse response = new VoidResponse();
QueryException qe = new QueryException(DatawaveErrorCode.COLLECTION_ERROR, e);
log.error(qe);
response.addException(qe.getBottomQueryException());
throw new DatawaveWebApplicationException(qe, response);
} finally {
if (null != connection) {
try {
connectionFactory.returnConnection(connection);
} catch (Exception e) {
log.error("Error returning connection to factory", e);
}
}
}
}
use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.
the class IteratorBuildingVisitor method visit.
@Override
public Object visit(ASTAndNode and, Object data) {
QueryPropertyMarker.Instance instance = QueryPropertyMarker.findInstance(and);
if (instance.isType(ExceededOrThresholdMarkerJexlNode.class)) {
JexlNode source = instance.getSource();
// Ivarator to get the job done
if (source instanceof ASTAndNode) {
try {
ivarateList(and, source, data);
} catch (IOException ioe) {
throw new DatawaveFatalQueryException(ioe);
}
} else {
QueryException qe = new QueryException(DatawaveErrorCode.UNEXPECTED_SOURCE_NODE, MessageFormat.format("{0}", "Limited ExceededOrThresholdMarkerJexlNode"));
throw new DatawaveFatalQueryException(qe);
}
} else if (data instanceof IndexRangeIteratorBuilder) {
// index checking has already been done, otherwise we would not have
// an "ExceededValueThresholdMarker"
// hence the "IndexAgnostic" method can be used here
LiteralRange range = JexlASTHelper.findRange().recursively().getRange(and);
if (range == null) {
QueryException qe = new QueryException(DatawaveErrorCode.MULTIPLE_RANGES_IN_EXPRESSION);
throw new DatawaveFatalQueryException(qe);
}
((IndexRangeIteratorBuilder) data).setRange(range);
} else if (instance.isType(ExceededValueThresholdMarkerJexlNode.class)) {
// if the parent is our ExceededValueThreshold marker, then use an
// Ivarator to get the job done unless we don't have to
JexlNode source = instance.getSource();
String identifier = null;
LiteralRange<?> range = null;
boolean negatedLocal = false;
if (source instanceof ASTAndNode) {
range = buildLiteralRange(source, null);
identifier = range.getFieldName();
} else {
if (source instanceof ASTNRNode || source instanceof ASTNotNode)
negatedLocal = true;
range = buildLiteralRange(source);
identifier = JexlASTHelper.getIdentifier(source);
}
boolean negatedOverall = negatedLocal;
if (data instanceof AbstractIteratorBuilder) {
AbstractIteratorBuilder oib = (AbstractIteratorBuilder) data;
if (oib.isInANot()) {
negatedOverall = !negatedOverall;
}
}
// or the field is index only but not in the term frequencies, then we must ivarate
if (!limitLookup || !allowTermFrequencyLookup || (indexOnlyFields.contains(identifier) && !termFrequencyFields.contains(identifier))) {
if (source instanceof ASTAndNode) {
try {
List<ASTFunctionNode> functionNodes = JexlASTHelper.getFunctionNodes(source).stream().filter(node -> JexlFunctionArgumentDescriptorFactory.F.getArgumentDescriptor(node).allowIvaratorFiltering()).collect(Collectors.toList());
if (functionNodes.isEmpty()) {
ivarateRange(and, source, data);
} else {
ivarateFilter(and, source, data, functionNodes);
}
} catch (IOException ioe) {
throw new DatawaveFatalQueryException("Unable to ivarate", ioe);
}
} else if (source instanceof ASTERNode || source instanceof ASTNRNode) {
try {
ivarateRegex(and, source, data);
} catch (IOException ioe) {
throw new DatawaveFatalQueryException("Unable to ivarate", ioe);
}
} else {
QueryException qe = new QueryException(DatawaveErrorCode.UNEXPECTED_SOURCE_NODE, MessageFormat.format("{0}", "ExceededValueThresholdMarkerJexlNode"));
throw new DatawaveFatalQueryException(qe);
}
} else {
NestedIterator<Key> nested = null;
if (termFrequencyFields.contains(identifier)) {
nested = buildExceededFromTermFrequency(identifier, and, source, range, data);
} else {
/**
* This is okay since 1) We are doc specific 2) We are not index only or tf 3) Therefore, we must evaluate against the document for this
* expression 4) Return a stubbed range in case we have a disjunction that breaks the current doc.
*/
if (!limitOverride && !negatedOverall)
nested = createExceededCheck(identifier, range, and);
}
if (null != nested && null != data && data instanceof AbstractIteratorBuilder) {
AbstractIteratorBuilder iterators = (AbstractIteratorBuilder) data;
if (negatedLocal) {
iterators.addExclude(nested);
} else {
iterators.addInclude(nested);
}
} else {
if (isQueryFullySatisfied == true) {
log.warn("Determined that isQueryFullySatisfied should be false, but it was not preset to false in the SatisfactionVisitor");
}
return nested;
}
}
} else if (null != data && data instanceof AndIteratorBuilder) {
and.childrenAccept(this, data);
} else {
// Create an AndIterator and recursively add the children
AbstractIteratorBuilder andItr = new AndIteratorBuilder();
andItr.negateAsNeeded(data);
and.childrenAccept(this, andItr);
// If there is no parent
if (data == null) {
// Make this AndIterator the root node
if (!andItr.includes().isEmpty()) {
root = andItr.build();
}
} else {
// Otherwise, add this AndIterator to its parent
AbstractIteratorBuilder parent = (AbstractIteratorBuilder) data;
if (!andItr.includes().isEmpty()) {
parent.addInclude(andItr.build());
}
}
if (log.isTraceEnabled()) {
log.trace("ASTAndNode visit: pretty formatting of:\nparent.includes:" + formatIncludesOrExcludes(andItr.includes()) + "\nparent.excludes:" + formatIncludesOrExcludes(andItr.excludes()));
}
}
return null;
}
Aggregations