Search in sources :

Example 11 with Parameter

use of datawave.webservice.query.QueryImpl.Parameter in project datawave by NationalSecurityAgency.

the class QueryUtilTest method testSerializationDeserialization.

@Test
public void testSerializationDeserialization() throws InvalidProtocolBufferException, ClassNotFoundException {
    QueryImpl q = new QueryImpl();
    q.setQueryLogicName("EventQuery");
    q.setExpirationDate(new Date());
    q.setId(UUID.randomUUID());
    q.setPagesize(10);
    q.setPageTimeout(-1);
    q.setQuery("FOO == BAR");
    q.setQueryName("test query");
    q.setQueryAuthorizations("ALL");
    q.setUserDN("some user");
    q.setOwner("some owner");
    q.setColumnVisibility("A&B");
    Set<Parameter> parameters = new HashSet<>();
    parameters.add(new Parameter("some param", "some value"));
    q.setParameters(parameters);
    Mutation m = QueryUtil.toMutation(q, new ColumnVisibility(q.getColumnVisibility()));
    Assert.assertEquals(1, m.getUpdates().size());
    byte[] value = m.getUpdates().get(0).getValue();
    Query q2 = QueryUtil.deserialize(QueryImpl.class.getName(), new Text("A&B"), new Value(value));
    Assert.assertEquals(q, q2);
}
Also used : QueryImpl(datawave.webservice.query.QueryImpl) Query(datawave.webservice.query.Query) Value(org.apache.accumulo.core.data.Value) Parameter(datawave.webservice.query.QueryImpl.Parameter) Text(org.apache.hadoop.io.Text) Mutation(org.apache.accumulo.core.data.Mutation) ColumnVisibility(org.apache.accumulo.core.security.ColumnVisibility) Date(java.util.Date) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 12 with Parameter

use of datawave.webservice.query.QueryImpl.Parameter in project datawave by NationalSecurityAgency.

the class QueryUtil method toParametersString.

public static String toParametersString(final Set<Parameter> parameters) {
    final StringBuilder params = new StringBuilder();
    if (null != parameters) {
        for (final Parameter param : parameters) {
            if (params.length() > 0) {
                params.append(PARAMETER_SEPARATOR);
            }
            params.append(param.getParameterName());
            params.append(PARAMETER_NAME_VALUE_SEPARATOR);
            params.append(param.getParameterValue());
        }
    }
    return params.toString();
}
Also used : Parameter(datawave.webservice.query.QueryImpl.Parameter)

Example 13 with Parameter

use of datawave.webservice.query.QueryImpl.Parameter in project datawave by NationalSecurityAgency.

the class DefaultQueryPlanner method addDateFilters.

/**
 * Adding date filters if the query parameters specify that the dates are to be other than the default
 *
 * @param queryTree
 * @param scannerFactory
 * @param metadataHelper
 * @param config
 * @return the updated query tree
 * @throws TableNotFoundException
 */
public ASTJexlScript addDateFilters(final ASTJexlScript queryTree, ScannerFactory scannerFactory, MetadataHelper metadataHelper, DateIndexHelper dateIndexHelper, ShardQueryConfiguration config, Query settings) throws TableNotFoundException, DatawaveQueryException {
    String defaultDateType = config.getDefaultDateTypeName();
    String dateType = defaultDateType;
    Parameter dateTypeParameter = settings.findParameter(QueryParameters.DATE_RANGE_TYPE);
    if (dateTypeParameter != null && dateTypeParameter.getParameterValue() != null) {
        String parm = dateTypeParameter.getParameterValue().trim();
        if (!parm.isEmpty()) {
            dateType = parm.toUpperCase();
        }
    }
    // time, then we need to modify the query
    if (!dateType.equals(defaultDateType)) {
        log.info("Using the date index for " + dateType);
        // if no date index helper configured, then we are in error
        if (dateIndexHelper == null) {
            throw new DatawaveQueryException("Requested date range of type " + dateType + " but no date index is configured");
        }
        // get all of the fields used for this date type
        DateIndexHelper.DateTypeDescription dateIndexData = dateIndexHelper.getTypeDescription(dateType, config.getBeginDate(), config.getEndDate(), config.getDatatypeFilter());
        if (dateIndexData.getFields().isEmpty()) {
            log.warn("The specified date type: " + dateType + " is unknown for the specified data types");
            // If this is the case, then essentially we have no dates to search. Adding the filter function with _NO_FIELD_ will have the desired effect.
            // Also it will be understandable from the plan as to why no results were returned.
            dateIndexData.getFields().add(Constants.NO_FIELD);
        }
        log.info("Adding date filters for the following fields: " + dateIndexData.getFields());
        // now for each field, add an expression to filter that date
        List<JexlNode> andChildren = new ArrayList<>();
        for (int i = 0; i < queryTree.jjtGetNumChildren(); i++) {
            andChildren.add(JexlNodeFactory.createExpression(queryTree.jjtGetChild(i)));
        }
        List<JexlNode> orChildren = new ArrayList<>();
        for (String field : dateIndexData.getFields()) {
            orChildren.add(createDateFilter(dateType, field, config.getBeginDate(), config.getEndDate()));
        }
        if (orChildren.size() > 1) {
            andChildren.add(JexlNodeFactory.createOrNode(orChildren));
        } else {
            andChildren.addAll(orChildren);
        }
        JexlNode andNode = JexlNodeFactory.createAndNode(andChildren);
        JexlNodeFactory.setChildren(queryTree, Collections.singleton(andNode));
        // now lets update the query parameters with the correct start and
        // end dates
        log.info("Remapped " + dateType + " dates [" + config.getBeginDate() + "," + config.getEndDate() + "] to EVENT dates " + dateIndexData.getBeginDate() + "," + dateIndexData.getEndDate());
        // reset the dates in the configuration, no need to reset then in
        // the Query settings object
        config.setBeginDate(dateIndexData.getBeginDate());
        config.setEndDate(dateIndexData.getEndDate());
    } else {
        log.info("Date index not needed for this query");
    }
    return queryTree;
}
Also used : DatawaveQueryException(datawave.query.exceptions.DatawaveQueryException) ArrayList(java.util.ArrayList) Parameter(datawave.webservice.query.QueryImpl.Parameter) ExceededValueThresholdMarkerJexlNode(datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode) JexlNode(org.apache.commons.jexl2.parser.JexlNode) DateIndexHelper(datawave.query.util.DateIndexHelper)

Example 14 with Parameter

use of datawave.webservice.query.QueryImpl.Parameter in project datawave by NationalSecurityAgency.

the class DefaultQueryPlanner method updateQueryTree.

protected ASTJexlScript updateQueryTree(ScannerFactory scannerFactory, MetadataHelper metadataHelper, DateIndexHelper dateIndexHelper, ShardQueryConfiguration config, String query, QueryData queryData, Query settings) throws DatawaveQueryException {
    final QueryStopwatch timers = config.getTimers();
    TraceStopwatch stopwatch = timers.newStartedStopwatch("DefaultQueryPlanner - Parse query");
    config.setQueryTree(parseQueryAndValidatePattern(query, stopwatch));
    if (log.isDebugEnabled()) {
        logQuery(config.getQueryTree(), "Query after initial parse:");
    }
    stopwatch.stop();
    Map<String, String> optionsMap = new HashMap<>();
    if (query.contains(QueryFunctions.QUERY_FUNCTION_NAMESPACE + ':')) {
        // only do the extra tree visit if the function is present
        stopwatch = timers.newStartedStopwatch("DefaultQueryPlanner - parse out queryOptions from options function");
        config.setQueryTree(QueryOptionsFromQueryVisitor.collect(config.getQueryTree(), optionsMap));
        if (!optionsMap.isEmpty()) {
            QueryOptionsSwitch.apply(optionsMap, config);
        }
        stopwatch.stop();
    }
    // groom the query so that any nodes with the literal on the left and the identifier on
    // the right will be re-ordered to simplify subsequent processing
    config.setQueryTree(timedInvertSwappedNodes(timers, config.getQueryTree()));
    config.setQueryTree(timedFixNotNullIntent(timers, config.getQueryTree()));
    config.setQueryTree(timedIncludeDateFilters(timers, config.getQueryTree(), config, metadataHelper, scannerFactory, dateIndexHelper, settings));
    // note this must be called after we do the date adjustments per the query date type in addDateFilters
    timedCapDateRange(timers, config);
    // Find unmarked bounded ranges
    if (UnmarkedBoundedRangeDetectionVisitor.findUnmarkedBoundedRanges(config.getQueryTree())) {
        throw new DatawaveFatalQueryException("Found incorrectly marked bounded ranges");
    }
    if (optionsMap.containsKey(QueryParameters.SHARDS_AND_DAYS)) {
        config.setQueryTree(timedAddShardsAndDaysFromOptions(timers, config.getQueryTree(), optionsMap));
    } else {
        // look for the shards and days hint in the query settings
        // the shards and days hint cannot always be specified in the query string when using certain query parsers
        Parameter parameter = settings.findParameter(QueryParameters.SHARDS_AND_DAYS);
        if (StringUtils.isNotBlank(parameter.getParameterValue())) {
            optionsMap.put(QueryParameters.SHARDS_AND_DAYS, parameter.getParameterValue());
            config.setQueryTree(timedAddShardsAndDaysFromOptions(timers, config.getQueryTree(), optionsMap));
        }
    }
    // extract #NO_EXPANSION function, if it exists
    config.setQueryTree(parseNoExpansionFields(timers, config.getQueryTree(), config));
    // flatten the tree
    config.setQueryTree(timedFlatten(timers, config.getQueryTree()));
    validateQuerySize("initial parse", config.getQueryTree(), config);
    config.setQueryTree(timedApplyRules(timers, config.getQueryTree(), config, metadataHelper, scannerFactory));
    config.setQueryTree(timedFixNegativeNumbers(timers, config.getQueryTree()));
    // Fix any query property markers that have multiple unwrapped sources.
    config.setQueryTree(timedFixQueryPropertyMarkers(timers, config.getQueryTree()));
    // Ensure that all ASTIdentifier nodes (field names) are upper-case to be consistent with what is enforced at ingest time
    config.setQueryTree(timedUpperCaseIdentifiers(timers, config.getQueryTree(), config, metadataHelper));
    config.setQueryTree(timedRewriteNegations(timers, config.getQueryTree()));
    QueryModel queryModel = loadQueryModel(config);
    config.setQueryTree(timedApplyQueryModel(timers, config.getQueryTree(), config, metadataHelper, queryModel));
    // Enforce unique terms within an AND or OR expression.
    if (config.getEnforceUniqueTermsWithinExpressions()) {
        config.setQueryTree(timedEnforceUniqueTermsWithinExpressions(timers, config.getQueryTree()));
    }
    // Enforce unique AND'd terms within OR expressions.
    if (config.getEnforceUniqueConjunctionsWithinExpression()) {
        config.setQueryTree(timedEnforceUniqueConjunctionsWithinExpressions(timers, config.getQueryTree()));
    }
    // Enforce unique OR'd terms within AND expressions.
    if (config.getEnforceUniqueDisjunctionsWithinExpression()) {
        config.setQueryTree(timedEnforceUniqueDisjunctionsWithinExpressions(timers, config.getQueryTree()));
    }
    Set<String> indexOnlyFields = loadIndexedFields(config);
    if (disableBoundedLookup) {
        // LT,GT or ER node, we should expand it
        if (BoundedRangeDetectionVisitor.mustExpandBoundedRange(config, metadataHelper, config.getQueryTree()))
            disableBoundedLookup = false;
    }
    if (!indexOnlyFields.isEmpty()) {
        config.setQueryTree(expandRegexFunctionNodes(config.getQueryTree(), config, metadataHelper, indexOnlyFields));
    }
    config.setQueryTree(processTree(config.getQueryTree(), config, settings, metadataHelper, scannerFactory, queryData, timers, queryModel));
    // ExpandCompositeTerms was here
    boolean containsIndexOnlyFields = false;
    if (!indexOnlyFields.isEmpty() && !disableBoundedLookup) {
        // Figure out if the query contained any index only terms so we know
        // if we have to force it down the field-index path with event-specific
        // ranges
        containsIndexOnlyFields = timedCheckForIndexOnlyFieldsInQuery(timers, "Check for Index-Only Fields", config.getQueryTree(), config, metadataHelper, dateIndexHelper, indexOnlyFields);
    }
    boolean containsComposites = timedCheckForCompositeFields(timers, "Check for Composite Fields", config.getQueryTree(), config, metadataHelper, dateIndexHelper);
    boolean sortedUIDS = timedCheckForSortedUids(timers, "Check for Sorted UIDs", config.getQueryTree(), config);
    // check the query for any fields that are term frequencies
    // if any exist, populate the shard query config with these fields
    timedCheckForTokenizedFields(timers, "Check for term frequency (tokenized) fields", config.getQueryTree(), config, metadataHelper, dateIndexHelper);
    if (reduceQuery) {
        config.setQueryTree(timedReduce(timers, "Reduce Query Final", config.getQueryTree()));
    }
    return config.getQueryTree();
}
Also used : HashMap(java.util.HashMap) TraceStopwatch(datawave.util.time.TraceStopwatch) DatawaveFatalQueryException(datawave.query.exceptions.DatawaveFatalQueryException) Parameter(datawave.webservice.query.QueryImpl.Parameter) QueryStopwatch(datawave.query.util.QueryStopwatch) QueryModel(datawave.query.model.QueryModel)

Example 15 with Parameter

use of datawave.webservice.query.QueryImpl.Parameter in project datawave by NationalSecurityAgency.

the class QueryExecutorBean method validateQuery.

/**
 * This method will provide some initial query validation for the define and create query calls.
 */
private QueryData validateQuery(String queryLogicName, MultivaluedMap<String, String> queryParameters, HttpHeaders httpHeaders) {
    // Parameter 'logicName' is required and passed in prior to this call. Add to the queryParameters now.
    if (!queryParameters.containsKey(QueryParameters.QUERY_LOGIC_NAME)) {
        queryParameters.putSingle(QueryParameters.QUERY_LOGIC_NAME, queryLogicName);
    }
    QueryData qd = new QueryData();
    log.debug(queryParameters);
    qp.clear();
    qp.setRequestHeaders(httpHeaders != null ? httpHeaders.getRequestHeaders() : null);
    // Pull "params" values into individual query parameters for validation on the query logic.
    // This supports the deprecated "params" value (both on the old and new API). Once we remove the deprecated
    // parameter, this code block can go away.
    String params = queryParameters.getFirst(QueryParameters.QUERY_PARAMS);
    if (params != null) {
        for (Parameter pm : QueryUtil.parseParameters(params)) {
            if (!queryParameters.containsKey(pm.getParameterName())) {
                queryParameters.putSingle(pm.getParameterName(), pm.getParameterValue());
            }
        }
    }
    queryParameters.remove(AuditParameters.QUERY_SECURITY_MARKING_COLVIZ);
    queryParameters.remove(AuditParameters.USER_DN);
    queryParameters.remove(AuditParameters.QUERY_AUDIT_TYPE);
    // Ensure that all required parameters exist prior to validating the values.
    qp.validate(queryParameters);
    // Leaving for now until we can test to ensure that is always the case.
    if (qp.getPagesize() <= 0) {
        log.error("Invalid page size: " + qp.getPagesize());
        GenericResponse<String> response = new GenericResponse<>();
        throwBadRequest(DatawaveErrorCode.INVALID_PAGE_SIZE, response);
    }
    if (qp.getPageTimeout() != -1 && (qp.getPageTimeout() < PAGE_TIMEOUT_MIN || qp.getPageTimeout() > PAGE_TIMEOUT_MAX)) {
        log.error("Invalid page timeout: " + qp.getPageTimeout());
        GenericResponse<String> response = new GenericResponse<>();
        throwBadRequest(DatawaveErrorCode.INVALID_PAGE_TIMEOUT, response);
    }
    if (System.currentTimeMillis() >= qp.getExpirationDate().getTime()) {
        log.error("Invalid expiration date: " + qp.getExpirationDate());
        GenericResponse<String> response = new GenericResponse<>();
        throwBadRequest(DatawaveErrorCode.INVALID_EXPIRATION_DATE, response);
    }
    // Ensure begin date does not occur after the end date (if dates are not null)
    if ((qp.getBeginDate() != null && qp.getEndDate() != null) && qp.getBeginDate().after(qp.getEndDate())) {
        log.error("Invalid begin and/or end date: " + qp.getBeginDate() + " - " + qp.getEndDate());
        GenericResponse<String> response = new GenericResponse<>();
        throwBadRequest(DatawaveErrorCode.BEGIN_DATE_AFTER_END_DATE, response);
    }
    // will throw IllegalArgumentException if not defined
    try {
        qd.logic = queryLogicFactory.getQueryLogic(queryLogicName, ctx.getCallerPrincipal());
    } catch (Exception e) {
        log.error("Failed to get query logic for " + queryLogicName, e);
        BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.QUERY_LOGIC_ERROR, e);
        GenericResponse<String> response = new GenericResponse<>();
        response.addException(qe.getBottomQueryException());
        throw new BadRequestException(qe, response);
    }
    qd.logic.validate(queryParameters);
    try {
        marking.clear();
        marking.validate(queryParameters);
    } catch (IllegalArgumentException e) {
        log.error("Failed security markings validation", e);
        BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.SECURITY_MARKING_CHECK_ERROR, e);
        GenericResponse<String> response = new GenericResponse<>();
        response.addException(qe);
        throw new BadRequestException(qe, response);
    }
    // Find out who/what called this method
    qd.proxyServers = null;
    qd.p = ctx.getCallerPrincipal();
    qd.userDn = qd.p.getName();
    qd.userid = qd.userDn;
    qd.dnList = Collections.singletonList(qd.userid);
    if (qd.p instanceof DatawavePrincipal) {
        DatawavePrincipal dp = (DatawavePrincipal) qd.p;
        qd.userid = dp.getShortName();
        qd.userDn = dp.getUserDN().subjectDN();
        String[] dns = dp.getDNs();
        Arrays.sort(dns);
        qd.dnList = Arrays.asList(dns);
        qd.proxyServers = dp.getProxyServers();
        // Verify that the calling principal has access to the query logic.
        if (!qd.logic.containsDNWithAccess(qd.dnList)) {
            UnauthorizedQueryException qe = new UnauthorizedQueryException("None of the DNs used have access to this query logic: " + qd.dnList, 401);
            GenericResponse<String> response = new GenericResponse<>();
            response.addException(qe);
            throw new UnauthorizedException(qe, response);
        }
    }
    log.trace(qd.userid + " has authorizations " + ((qd.p instanceof DatawavePrincipal) ? ((DatawavePrincipal) qd.p).getAuthorizations() : ""));
    // always check against the max
    if (qd.logic.getMaxPageSize() > 0 && qp.getPagesize() > qd.logic.getMaxPageSize()) {
        log.error("Invalid page size: " + qp.getPagesize() + " vs " + qd.logic.getMaxPageSize());
        BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.PAGE_SIZE_TOO_LARGE, MessageFormat.format("Max = {0}.", qd.logic.getMaxPageSize()));
        GenericResponse<String> response = new GenericResponse<>();
        response.addException(qe);
        throw new BadRequestException(qe, response);
    }
    // privileged users however can set whatever they want
    if (qp.isMaxResultsOverridden() && qd.logic.getMaxResults() >= 0) {
        if (!ctx.isCallerInRole(PRIVILEGED_USER)) {
            if (qp.getMaxResultsOverride() < 0 || (qd.logic.getMaxResults() < qp.getMaxResultsOverride())) {
                log.error("Invalid max results override: " + qp.getMaxResultsOverride() + " vs " + qd.logic.getMaxResults());
                GenericResponse<String> response = new GenericResponse<>();
                throwBadRequest(DatawaveErrorCode.INVALID_MAX_RESULTS_OVERRIDE, response);
            }
        }
    }
    // Set private audit-related parameters, stripping off any that the user might have passed in first.
    // These are parameters that aren't passed in by the user, but rather are computed from other sources.
    PrivateAuditConstants.stripPrivateParameters(queryParameters);
    queryParameters.add(PrivateAuditConstants.LOGIC_CLASS, queryLogicName);
    queryParameters.putSingle(PrivateAuditConstants.COLUMN_VISIBILITY, marking.toColumnVisibilityString());
    queryParameters.add(PrivateAuditConstants.USER_DN, qd.userDn);
    return qd;
}
Also used : GenericResponse(datawave.webservice.result.GenericResponse) BadRequestQueryException(datawave.webservice.query.exception.BadRequestQueryException) DatawaveWebApplicationException(datawave.webservice.common.exception.DatawaveWebApplicationException) CancellationException(java.util.concurrent.CancellationException) PreConditionFailedQueryException(datawave.webservice.query.exception.PreConditionFailedQueryException) WebApplicationException(javax.ws.rs.WebApplicationException) HeuristicMixedException(javax.transaction.HeuristicMixedException) NotFoundQueryException(datawave.webservice.query.exception.NotFoundQueryException) NoResultsQueryException(datawave.webservice.query.exception.NoResultsQueryException) IOException(java.io.IOException) QueryException(datawave.webservice.query.exception.QueryException) BadRequestException(datawave.webservice.common.exception.BadRequestException) HeuristicRollbackException(javax.transaction.HeuristicRollbackException) UnauthorizedQueryException(datawave.webservice.query.exception.UnauthorizedQueryException) JAXBException(javax.xml.bind.JAXBException) UnauthorizedException(datawave.webservice.common.exception.UnauthorizedException) NoResultsException(datawave.webservice.common.exception.NoResultsException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RollbackException(javax.transaction.RollbackException) BadRequestQueryException(datawave.webservice.query.exception.BadRequestQueryException) DatawavePrincipal(datawave.security.authorization.DatawavePrincipal) UnauthorizedQueryException(datawave.webservice.query.exception.UnauthorizedQueryException) UnauthorizedException(datawave.webservice.common.exception.UnauthorizedException) Parameter(datawave.webservice.query.QueryImpl.Parameter) BadRequestException(datawave.webservice.common.exception.BadRequestException)

Aggregations

Parameter (datawave.webservice.query.QueryImpl.Parameter)17 HashSet (java.util.HashSet)5 ArrayList (java.util.ArrayList)4 DatawavePrincipal (datawave.security.authorization.DatawavePrincipal)3 BadRequestException (datawave.webservice.common.exception.BadRequestException)3 DatawaveWebApplicationException (datawave.webservice.common.exception.DatawaveWebApplicationException)3 NoResultsException (datawave.webservice.common.exception.NoResultsException)3 UnauthorizedException (datawave.webservice.common.exception.UnauthorizedException)3 Query (datawave.webservice.query.Query)3 BadRequestQueryException (datawave.webservice.query.exception.BadRequestQueryException)3 NoResultsQueryException (datawave.webservice.query.exception.NoResultsQueryException)3 NotFoundQueryException (datawave.webservice.query.exception.NotFoundQueryException)3 PreConditionFailedQueryException (datawave.webservice.query.exception.PreConditionFailedQueryException)3 QueryException (datawave.webservice.query.exception.QueryException)3 UnauthorizedQueryException (datawave.webservice.query.exception.UnauthorizedQueryException)3 IOException (java.io.IOException)3 CancellationException (java.util.concurrent.CancellationException)3 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)3 HeuristicMixedException (javax.transaction.HeuristicMixedException)3 HeuristicRollbackException (javax.transaction.HeuristicRollbackException)3