Search in sources :

Example 66 with QueryException

use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.

the class ExpandMultiNormalizedTerms method expandNodeForNormalizers.

/**
 * @param node
 * @param data
 * @return
 */
protected JexlNode expandNodeForNormalizers(JexlNode node, Object data) {
    JexlNode nodeToReturn = node;
    IdentifierOpLiteral op = JexlASTHelper.getIdentifierOpLiteral(node);
    if (op != null) {
        final String fieldName = op.deconstructIdentifier();
        final Object literal = op.getLiteralValue();
        // Get all of the indexed or normalized dataTypes for the field name
        Set<Type<?>> dataTypes = Sets.newHashSet(config.getQueryFieldsDatatypes().get(fieldName));
        dataTypes.addAll(config.getNormalizedFieldsDatatypes().get(fieldName));
        // Catch the case of the user entering FIELD == null
        if (!dataTypes.isEmpty() && null != literal) {
            try {
                String term = literal.toString();
                Set<String> normalizedTerms = Sets.newHashSet();
                // Build up a set of normalized terms using each normalizer
                for (Type<?> normalizer : dataTypes) {
                    try {
                        if (node instanceof ASTNRNode || node instanceof ASTERNode) {
                            normalizedTerms.add(normalizer.normalizeRegex(term));
                        } else {
                            normalizedTerms.add(normalizer.normalize(term));
                        }
                        log.debug("normalizedTerms=" + normalizedTerms);
                    } catch (IpAddressNormalizer.Exception ipex) {
                        try {
                            String[] lowHi = ((IpAddressType) normalizer).normalizeCidrToRange(term);
                            // node was FIELD == 'cidr'
                            // change to FIELD >= low and FIELD <= hi
                            JexlNode geNode = JexlNodeFactory.buildNode(new ASTGENode(ParserTreeConstants.JJTGENODE), fieldName, lowHi[0]);
                            JexlNode leNode = JexlNodeFactory.buildNode(new ASTLENode(ParserTreeConstants.JJTLENODE), fieldName, lowHi[1]);
                            // now link em up
                            return BoundedRange.create(JexlNodeFactory.createAndNode(Arrays.asList(geNode, leNode)));
                        } catch (Exception ex) {
                            if (log.isTraceEnabled()) {
                                log.trace("Could not normalize " + term + " as cidr notation with: " + normalizer.getClass());
                            }
                        }
                    // this could be CIDR notation, attempt to expand the node to the cidr range
                    } catch (Exception ne) {
                        if (log.isTraceEnabled()) {
                            log.trace("Could not normalize " + term + " using " + normalizer.getClass());
                        }
                    }
                }
                if (normalizedTerms.size() > 1) {
                    nodeToReturn = JexlNodeFactory.createNodeTreeFromFieldValues(ContainerType.OR_NODE, node, node, fieldName, normalizedTerms);
                } else if (1 == normalizedTerms.size()) {
                    // If there is only one term, we don't need to make an OR
                    nodeToReturn = JexlNodeFactory.buildUntypedNewLiteralNode(node, fieldName, normalizedTerms.iterator().next());
                } else {
                    // If we couldn't map anything, return a copy
                    nodeToReturn = JexlNodeFactory.buildUntypedNewLiteralNode(node, fieldName, literal);
                }
            } catch (Exception e) {
                QueryException qe = new QueryException(DatawaveErrorCode.NODE_EXPANSION_ERROR, e, MessageFormat.format("Node: {0}, Datatypes: {1}", PrintingVisitor.formattedQueryString(node), dataTypes));
                log.error(qe);
                throw new DatawaveFatalQueryException(qe);
            }
        }
    }
    return nodeToReturn;
}
Also used : ASTGENode(org.apache.commons.jexl2.parser.ASTGENode) ASTERNode(org.apache.commons.jexl2.parser.ASTERNode) IdentifierOpLiteral(datawave.query.jexl.JexlASTHelper.IdentifierOpLiteral) ASTNRNode(org.apache.commons.jexl2.parser.ASTNRNode) IpAddressNormalizer(datawave.data.normalizer.IpAddressNormalizer) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) QueryException(datawave.webservice.query.exception.QueryException) ContainerType(datawave.query.jexl.JexlNodeFactory.ContainerType) IpAddressType(datawave.data.type.IpAddressType) Type(datawave.data.type.Type) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) QueryException(datawave.webservice.query.exception.QueryException) ASTLENode(org.apache.commons.jexl2.parser.ASTLENode) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) JexlNode(org.apache.commons.jexl2.parser.JexlNode)

Example 67 with QueryException

use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.

the class PushdownLargeFieldedListsVisitor method visit.

@Override
public Object visit(ASTOrNode node, Object data) {
    ASTOrNode newNode = newInstanceOfType(node);
    newNode.image = node.image;
    Multimap<String, JexlNode> eqNodesByField = LinkedListMultimap.create();
    Multimap<String, JexlNode> rangeNodesByField = LinkedListMultimap.create();
    List<JexlNode> otherNodes = new ArrayList<>();
    // first pull out sets of nodes by field
    for (JexlNode childNode : children(node)) assignNodeByField(childNode, eqNodesByField, rangeNodesByField, otherNodes);
    ArrayList<JexlNode> children = newArrayList();
    // if "OTHER_NODES", then simply add the subset back into the children list
    copyChildren(otherNodes, children, data);
    SortedSet<String> fields = new TreeSet<>(eqNodesByField.keySet());
    fields.addAll(rangeNodesByField.keySet());
    for (String field : fields) {
        // if fields is not specified or the current field is in fields it can be reduced
        boolean canReduce = (this.fields == null || this.fields.contains(field));
        Collection<JexlNode> eqNodes = eqNodesByField.get(field);
        Collection<JexlNode> rangeNodes = rangeNodesByField.get(field);
        // @formatter:off
        if (canReduce && !Constants.ANY_FIELD.equals(field) && !Constants.NO_FIELD.equals(field) && (eqNodes.size() >= config.getMaxOrExpansionFstThreshold() || eqNodes.size() >= config.getMaxOrExpansionThreshold() || rangeNodes.size() >= config.getMaxOrRangeThreshold()) && isIndexed(field)) {
            // @formatter:on
            log.info("Pushing down large (" + eqNodes.size() + "|" + rangeNodes.size() + ") fielded list for " + field);
            // turn the subset of children into a list of values
            SortedSet<String> values = new TreeSet<>();
            for (JexlNode child : eqNodes) {
                values.add(String.valueOf(JexlASTHelper.getLiteralValue(child)));
            }
            List<JexlNode> markers = new ArrayList<>();
            try {
                // if we have an hdfs cache directory and if past the fst/list threshold, then create the fst/list and replace the list with an assignment
                if (fstHdfsUri != null && (eqNodes.size() >= config.getMaxOrExpansionFstThreshold())) {
                    URI fstPath = createFst(values);
                    markers.add(ExceededOrThresholdMarkerJexlNode.createFromFstURI(field, fstPath));
                    eqNodes = null;
                } else if (eqNodes.size() >= config.getMaxOrExpansionThreshold()) {
                    markers.add(ExceededOrThresholdMarkerJexlNode.createFromValues(field, values));
                    eqNodes = null;
                }
                // handle range nodes separately
                if (rangeNodes.size() >= config.getMaxOrRangeThreshold()) {
                    TreeMap<Range, JexlNode> ranges = new TreeMap<>();
                    rangeNodes.forEach(rangeNode -> ranges.put(rangeNodeToRange(rangeNode), rangeNode));
                    int numBatches = getBatchCount(rangeNodes.size());
                    List<List<Map.Entry<Range, JexlNode>>> batchedRanges = batchRanges(ranges, numBatches);
                    rangeNodes = new ArrayList<>();
                    for (List<Map.Entry<Range, JexlNode>> rangeList : batchedRanges) {
                        if (rangeList.size() > 1) {
                            markers.add(ExceededOrThresholdMarkerJexlNode.createFromRanges(field, rangeList.stream().map(Map.Entry::getKey).collect(Collectors.toList())));
                        } else {
                            rangeNodes.add(rangeList.get(0).getValue());
                        }
                    }
                }
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IOException e) {
                QueryException qe = new QueryException(DatawaveErrorCode.LARGE_FIELDED_LIST_ERROR, e);
                throw new DatawaveFatalQueryException(qe);
            }
            // add in any unused eq nodes
            if (eqNodes != null) {
                copyChildren(eqNodes, children, data);
            }
            // add in any unused range nodes
            copyChildren(rangeNodes, children, data);
            children.addAll(markers);
        } else // else simply add the subset back into the children list
        {
            // recurse on the eq children in this subset
            copyChildren(eqNodes, children, data);
            track(data, field, eqNodes.size() - 1);
            // recurse on the range children in this subset
            copyChildren(rangeNodes, children, data);
            int numBatches = getBatchCount(rangeNodes.size());
            track(data, field, rangeNodes.size() - numBatches);
        }
    }
    return children.size() == 1 ? Iterables.getOnlyElement(children) : children(newNode, children.toArray(new JexlNode[0]));
}
Also used : ArrayList(java.util.ArrayList) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) URI(java.net.URI) TreeSet(java.util.TreeSet) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) ArrayList(java.util.ArrayList) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ASTOrNode(org.apache.commons.jexl2.parser.ASTOrNode) IOException(java.io.IOException) LiteralRange(datawave.query.jexl.LiteralRange) BoundedRange(datawave.query.jexl.nodes.BoundedRange) Range(org.apache.accumulo.core.data.Range) TreeMap(java.util.TreeMap) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) QueryException(datawave.webservice.query.exception.QueryException) JexlNode(org.apache.commons.jexl2.parser.JexlNode) ExceededValueThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode) ExceededOrThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededOrThresholdMarkerJexlNode) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 68 with QueryException

use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.

the class IteratorBuildingVisitor method ivarateList.

/**
 * Build the iterator stack using the regex ivarator (field index caching regex iterator)
 *
 * @param rootNode
 *            the node that was processed to generated this builder
 * @param sourceNode
 *            the source node derived from the root
 * @param data
 */
public void ivarateList(JexlNode rootNode, JexlNode sourceNode, Object data) throws IOException {
    IvaratorBuilder builder = null;
    try {
        String id = ExceededOrThresholdMarkerJexlNode.getId(sourceNode);
        String field = JexlASTHelper.deconstructIdentifier(ExceededOrThresholdMarkerJexlNode.getField(sourceNode));
        ExceededOrThresholdMarkerJexlNode.ExceededOrParams params = ExceededOrThresholdMarkerJexlNode.getParameters(sourceNode);
        if (params.getRanges() != null && !params.getRanges().isEmpty()) {
            IndexRangeIteratorBuilder rangeIterBuilder = new IndexRangeIteratorBuilder();
            builder = rangeIterBuilder;
            SortedSet<Range> ranges = params.getSortedAccumuloRanges();
            rangeIterBuilder.setSubRanges(params.getSortedAccumuloRanges());
            // cache these ranges for use during Jexl Evaluation
            if (exceededOrEvaluationCache != null)
                exceededOrEvaluationCache.put(id, ranges);
            LiteralRange<?> fullRange = new LiteralRange<>(String.valueOf(ranges.first().getStartKey().getRow()), ranges.first().isStartKeyInclusive(), String.valueOf(ranges.last().getEndKey().getRow()), ranges.last().isEndKeyInclusive(), field, NodeOperand.AND);
            rangeIterBuilder.setRange(fullRange);
        } else {
            IndexListIteratorBuilder listIterBuilder = new IndexListIteratorBuilder();
            builder = listIterBuilder;
            if (params.getValues() != null && !params.getValues().isEmpty()) {
                Set<String> values = new TreeSet<>(params.getValues());
                listIterBuilder.setValues(values);
                // cache these values for use during Jexl Evaluation
                if (exceededOrEvaluationCache != null)
                    exceededOrEvaluationCache.put(id, values);
            } else if (params.getFstURI() != null) {
                URI fstUri = new URI(params.getFstURI());
                FST fst;
                // only recompute this if not already set since this is potentially expensive
                if (exceededOrEvaluationCache.containsKey(id)) {
                    fst = (FST) exceededOrEvaluationCache.get(id);
                } else {
                    fst = DatawaveFieldIndexListIteratorJexl.FSTManager.get(new Path(fstUri), hdfsFileCompressionCodec, hdfsFileSystem.getFileSystem(fstUri));
                }
                listIterBuilder.setFst(fst);
                // cache this fst for use during JexlEvaluation.
                if (exceededOrEvaluationCache != null)
                    exceededOrEvaluationCache.put(id, fst);
            }
            // If this is actually negated, then this will be added to excludes. Do not negate in the ivarator
            listIterBuilder.setNegated(false);
        }
        builder.setField(field);
    } catch (IOException | URISyntaxException | NullPointerException e) {
        QueryException qe = new QueryException(DatawaveErrorCode.UNPARSEABLE_EXCEEDED_OR_PARAMS, e, MessageFormat.format("Class: {0}", ExceededOrThresholdMarkerJexlNode.class.getSimpleName()));
        throw new DatawaveFatalQueryException(qe);
    }
    builder.negateAsNeeded(data);
    builder.forceDocumentBuild(!limitLookup && this.isQueryFullySatisfied);
    ivarate(builder, rootNode, sourceNode, data);
}
Also used : Path(org.apache.hadoop.fs.Path) FST(org.apache.lucene.util.fst.FST) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) LiteralRange(datawave.query.jexl.LiteralRange) Range(org.apache.accumulo.core.data.Range) IvaratorBuilder(datawave.query.iterator.builder.IvaratorBuilder) URI(java.net.URI) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) QueryException(datawave.webservice.query.exception.QueryException) TreeSet(java.util.TreeSet) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) ExceededOrThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededOrThresholdMarkerJexlNode) IndexListIteratorBuilder(datawave.query.iterator.builder.IndexListIteratorBuilder) IndexRangeIteratorBuilder(datawave.query.iterator.builder.IndexRangeIteratorBuilder) LiteralRange(datawave.query.jexl.LiteralRange)

Example 69 with QueryException

use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.

the class IteratorBuildingVisitor method visit.

@Override
public Object visit(ASTEQNode node, Object data) {
    IndexIteratorBuilder builder = null;
    try {
        builder = iteratorBuilderClass.asSubclass(IndexIteratorBuilder.class).newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
        throw new RuntimeException(e);
    }
    /**
     * If we have an unindexed type enforced, we've been configured to assert whether the field is indexed.
     */
    if (isUnindexed(node)) {
        if (isQueryFullySatisfied == true) {
            log.warn("Determined that isQueryFullySatisfied should be false, but it was not preset to false in the SatisfactionVisitor");
        }
        return null;
    }
    // boolean to tell us if we've overridden our subtree due to
    // a negation or
    boolean isNegation = false;
    if (data instanceof AbstractIteratorBuilder) {
        AbstractIteratorBuilder oib = (AbstractIteratorBuilder) data;
        isNegation = oib.isInANot();
    }
    builder.setQueryId(queryId);
    builder.setSource(getSourceIterator(node, isNegation));
    builder.setTimeFilter(getTimeFilter(node));
    builder.setTypeMetadata(typeMetadata);
    builder.setFieldsToAggregate(fieldsToAggregate);
    builder.setDatatypeFilter(datatypeFilter);
    builder.setKeyTransform(fiAggregator);
    builder.setEnv(env);
    builder.forceDocumentBuild(!limitLookup && this.isQueryFullySatisfied);
    builder.setNode(node);
    node.childrenAccept(this, builder);
    // handle this, so we should just not build an IndexIterator for it.
    if (null == builder.getValue()) {
        if (this.indexOnlyFields.contains(builder.getField())) {
            QueryException qe = new QueryException(DatawaveErrorCode.INDEX_ONLY_FIELDS_RETRIEVAL_ERROR, MessageFormat.format("{0} {1} {2}", "Unable to compare index only field", builder.getField(), "against null"));
            throw new DatawaveFatalQueryException(qe);
        }
        return null;
    }
    // We have no parent already defined
    if (data == null) {
        // Make this EQNode the root
        if (!includeReferences.contains(builder.getField()) && excludeReferences.contains(builder.getField())) {
            throw new IllegalStateException(builder.getField() + " is a blacklisted reference.");
        } else if (builder.getField() != null) {
            root = builder.build();
            if (log.isTraceEnabled()) {
                log.trace("Build IndexIterator: " + root);
            }
        }
    } else {
        AbstractIteratorBuilder iterators = (AbstractIteratorBuilder) data;
        // Add this IndexIterator to the parent
        final boolean isNew = !iterators.hasSeen(builder.getField(), builder.getValue());
        final boolean inclusionReference = includeReferences.contains(builder.getField());
        final boolean notExcluded = !excludeReferences.contains(builder.getField());
        if (isNew && inclusionReference && notExcluded) {
            iterators.addInclude(builder.build());
        } else {
            if (isQueryFullySatisfied == true) {
                log.warn("Determined that isQueryFullySatisfied should be false, but it was not preset to false in the SatisfactionVisitor");
            }
        }
    }
    return null;
}
Also used : DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) QueryException(datawave.webservice.query.exception.QueryException) IndexIteratorBuilder(datawave.query.iterator.builder.IndexIteratorBuilder) AbstractIteratorBuilder(datawave.query.iterator.builder.AbstractIteratorBuilder) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException)

Example 70 with QueryException

use of datawave.webservice.query.exception.QueryException in project datawave by NationalSecurityAgency.

the class IteratorBuildingVisitor method ivarateFilter.

/**
 * Build the iterator stack using the filter ivarator (field index caching filter iterator)
 *
 * @param rootNode
 *            the node that was processed to generated this builder
 * @param sourceNode
 *            the source node derived from the root
 * @param data
 */
public void ivarateFilter(JexlNode rootNode, JexlNode sourceNode, Object data, List<ASTFunctionNode> functionNodes) throws IOException {
    IndexFilterIteratorBuilder builder = new IndexFilterIteratorBuilder();
    builder.negateAsNeeded(data);
    // hence the "IndexAgnostic" method can be used here
    if (sourceNode instanceof ASTAndNode) {
        LiteralRange range = JexlASTHelper.findRange().recursively().getRange(sourceNode);
        if (range == null) {
            QueryException qe = new QueryException(DatawaveErrorCode.MULTIPLE_RANGES_IN_EXPRESSION);
            throw new DatawaveFatalQueryException(qe);
        }
        builder.setRangeAndFunction(range, new FunctionFilter(functionNodes));
    } else {
        QueryException qe = new QueryException(DatawaveErrorCode.UNEXPECTED_SOURCE_NODE, MessageFormat.format("{0}", "ASTFunctionNode"));
        throw new DatawaveFatalQueryException(qe);
    }
    ivarate(builder, rootNode, sourceNode, data);
}
Also used : DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) QueryException(datawave.webservice.query.exception.QueryException) IndexFilterIteratorBuilder(datawave.query.iterator.builder.IndexFilterIteratorBuilder) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) LiteralRange(datawave.query.jexl.LiteralRange) ASTAndNode(org.apache.commons.jexl2.parser.ASTAndNode)

Aggregations

QueryException (datawave.webservice.query.exception.QueryException)131 DatawaveWebApplicationException (datawave.webservice.common.exception.DatawaveWebApplicationException)63 IOException (java.io.IOException)62 NotFoundQueryException (datawave.webservice.query.exception.NotFoundQueryException)57 BadRequestQueryException (datawave.webservice.query.exception.BadRequestQueryException)51 NoResultsQueryException (datawave.webservice.query.exception.NoResultsQueryException)47 PreConditionFailedQueryException (datawave.webservice.query.exception.PreConditionFailedQueryException)45 Produces (javax.ws.rs.Produces)44 NoResultsException (datawave.webservice.common.exception.NoResultsException)40 UnauthorizedQueryException (datawave.webservice.query.exception.UnauthorizedQueryException)39 DatawaveFatalQueryException (datawave.query.exceptions.DatawaveFatalQueryException)36 DatawavePrincipal (datawave.security.authorization.DatawavePrincipal)36 Interceptors (javax.interceptor.Interceptors)36 UnauthorizedException (datawave.webservice.common.exception.UnauthorizedException)34 GZIP (org.jboss.resteasy.annotations.GZIP)34 Principal (java.security.Principal)32 WebApplicationException (javax.ws.rs.WebApplicationException)31 BadRequestException (datawave.webservice.common.exception.BadRequestException)29 Path (javax.ws.rs.Path)28 Timed (com.codahale.metrics.annotation.Timed)26