/** * Submits a query via the session. * * @param query The query to submit. * @param <T> The query output type. * @return A completable future to be completed with the query output. */ public <T> CompletableFuture<T> submit(Query<T> query) { if (!isOpen()) return Futures.exceptionalFuture(new IllegalStateException("session not open")); CompletableFuture<T> future = new CompletableFuture<>(); context .executor() .execute( () -> { QueryRequest request; if (query.consistency() == Query.ConsistencyLevel.CAUSAL) { request = QueryRequest.builder() .withSession(id) .withSequence(commandResponse) .withVersion(responseVersion) .withQuery(query) .build(); } else { request = QueryRequest.builder() .withSession(id) .withSequence(commandRequest) .withVersion(responseVersion) .withQuery(query) .build(); } submit(request, future); }); return future; }
@Override protected boolean createKeys(List<KeyValueQueryContent> toPopulate) { for (QueryRequest queryRequest : queryRequests) { Map<String, Object> map = queryRequest.getProperties(); initCommonProperties(map); final String query = queryRequest.getQueryString(); setCommonProperty(map, CommonPropertyTypes.KEYWORD, query); setCommonProperty(map, CommonPropertyTypes.REGEX, !queryRequest.getQuery().isLiteral()); createFlatKeys(queryRequest, toPopulate); } return true; }
@Test public void annotationQuery_roundTrip() { String annotationQuery = "http.method=GET and error"; QueryRequest request = QueryRequest.builder() .serviceName("security-service") .parseAnnotationQuery(annotationQuery) .build(); assertThat(request.binaryAnnotations).containsEntry(HTTP_METHOD, "GET").hasSize(1); assertThat(request.annotations).containsExactly(Constants.ERROR); assertThat(request.toAnnotationQuery()).isEqualTo(annotationQuery); }
@Test public void maxDuration_onlyWithMinDuration() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("maxDuration is only valid with minDuration"); QueryRequest.builder().serviceName("foo").maxDuration(0L).build(); }
@Test public void spanNameCantBeEmpty() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("spanName was empty"); QueryRequest.builder().serviceName("foo").spanName("").build(); }
@Test public void annotationCantBeEmpty() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("annotation was empty"); QueryRequest.builder().serviceName("foo").addAnnotation("").build(); }
/** * Particularly in the case of cassandra, indexing boundary annotations isn't fruitful work, and * not helpful to users. Nevertheless we should ensure an unlikely caller gets an exception. */ @Test public void annotationCantBeCore() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("queries cannot be refined by core annotations: sr"); QueryRequest.builder().serviceName("foo").addAnnotation(Constants.SERVER_RECV).build(); }
@Test public void binaryAnnotationValueCantBeEmpty() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("binary annotation value for foo was empty"); QueryRequest.builder().serviceName("foo").addBinaryAnnotation("foo", "").build(); }
@Test public void endTsMustBePositive() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("endTs should be positive, in epoch microseconds: was 0"); QueryRequest.builder().serviceName("foo").endTs(0L).build(); }
public boolean updateQuery(String tql) throws ServiceException { QueryRequest.Builder builder = QueryRequest.newBuilder(); builder.setQuery(tql); ResultCode resultCode = service.updateQuery(null, builder.build()).getResultCode(); return resultCode == ResultCode.OK; }
@Test public void limitMustBePositive() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("limit should be positive: was 0"); QueryRequest.builder().serviceName("foo").limit(0).build(); }
@Test public void maxDuration_greaterThanOrEqualToMinDuration() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("maxDuration should be >= minDuration"); QueryRequest.builder().serviceName("foo").minDuration(1L).maxDuration(0L).build(); }
@Test public void minDuration_mustBePositive() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("minDuration must be a positive number of microseconds"); QueryRequest.builder().serviceName("foo").minDuration(0L).build(); }
public synchronized boolean equals(java.lang.Object obj) { if (!(obj instanceof QueryRequest)) return false; QueryRequest other = (QueryRequest) obj; if (obj == null) return false; if (this == obj) return true; if (__equalsCalc != null) { return (__equalsCalc == obj); } __equalsCalc = obj; boolean _equals; _equals = true && ((this.cqlQuery == null && other.getCqlQuery() == null) || (this.cqlQuery != null && this.cqlQuery.equals(other.getCqlQuery()))); __equalsCalc = null; return _equals; }
@Override public void handleQuery( final ServerContext context, final QueryRequest request, final QueryResultHandler handler) { // TODO: i18n handler.handleError( newBadRequestException( "The singleton resource %s cannot be queried", request.getResourceName())); }
/** * Decorates the given query request with attributes required for geo spatial querying. * * @param queryRequest the request that needs to be decorated with geo attributes * @param latitude the latitude of the item that is being queried * @param longitude the longitude of the item that is being queried * @param config the configuration to be used for decorating the request with geo attributes * @param compositeKeyValue the value of the column that is used in the construction of the * composite hash key(geoHashKey + someOtherColumnValue). This is needed when constructing * queries that need a composite hash key. For eg. Fetch an item where lat/long is 23.78787, * -70.6767 AND category = 'restaurants' * @return the decorated request */ public QueryRequest getItemQuery( QueryRequest queryRequest, double latitude, double longitude, GeoConfig config, Optional<String> compositeKeyValue) { checkConfigParams( config.getGeoIndexName(), config.getGeoHashKeyColumn(), config.getGeoHashColumn(), config.getGeoHashKeyLength()); // Generate the geohash and geoHashKey to query by global secondary index long geohash = s2Manager.generateGeohash(latitude, longitude); long geoHashKey = s2Manager.generateHashKey(geohash, config.getGeoHashKeyLength()); queryRequest.withIndexName(config.getGeoIndexName()); Map<String, Condition> keyConditions = new HashMap<String, Condition>(); // Construct the hashKey condition Condition geoHashKeyCondition; if (config.getHashKeyDecorator().isPresent() && compositeKeyValue.isPresent()) { String hashKey = config.getHashKeyDecorator().get().decorate(compositeKeyValue.get(), geoHashKey); geoHashKeyCondition = new Condition() .withComparisonOperator(ComparisonOperator.EQ) .withAttributeValueList(new AttributeValue().withS(hashKey)); } else { geoHashKeyCondition = new Condition() .withComparisonOperator(ComparisonOperator.EQ) .withAttributeValueList(new AttributeValue().withN(String.valueOf(geoHashKey))); } keyConditions.put(config.getGeoHashKeyColumn(), geoHashKeyCondition); // Construct the geohash condition Condition geoHashCondition = new Condition() .withComparisonOperator(ComparisonOperator.EQ) .withAttributeValueList(new AttributeValue().withN(String.valueOf(geohash))); keyConditions.put(config.getGeoHashColumn(), geoHashCondition); queryRequest.setKeyConditions(keyConditions); return queryRequest; }
/** * It submits a query statement and get a response. The main difference from {@link * #executeQuery(String)} is a blocking method. So, this method is wait for the finish of the * submitted query. * * @return If failed, return null. */ public ResultSet executeQueryAndGetResult(String tql) throws ServiceException, IOException { QueryRequest.Builder builder = QueryRequest.newBuilder(); builder.setQuery(tql); SubmitQueryRespose response = service.submitQuery(null, builder.build()); QueryId queryId = new QueryId(response.getQueryId()); if (queryId.equals(TajoIdUtils.NullQueryId)) { return null; } return getQueryResultAndWait(queryId); }
@Test public void annotationQuery_missingValue() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("binary annotation value for http.method was empty"); String annotationQuery = "http.method="; QueryRequest request = QueryRequest.builder() .serviceName("security-service") .parseAnnotationQuery(annotationQuery) .build(); assertThat(request.annotations).containsExactly(HTTP_METHOD); }
/** Recursively submits a query. */ @SuppressWarnings("unchecked") private <T> CompletableFuture<T> submit(QueryRequest request, CompletableFuture<T> future) { if (!isOpen()) { future.completeExceptionally(new IllegalStateException("session not open")); return future; } long sequence = ++requestSequence; this.<QueryRequest, QueryResponse>request(request) .whenComplete( (response, error) -> { if (error == null) { // If the query consistency level is CAUSAL, we can simply complete queries in // sequential order. if (request.query().consistency() == Query.ConsistencyLevel.CAUSAL) { sequenceResponse( sequence, () -> { responseVersion = Math.max(responseVersion, response.version()); completeResponse(response, future); }); } // If the query consistency level is strong, the query must be executed // sequentially. In order to ensure responses // are received in a sequential manner, we compare the response version number with // the highest version for which // we've received a response and resubmit queries with output resulting from stale // (prior) versions. else { sequenceResponse( sequence, () -> { if (response.version() > 0 && response.version() < responseVersion) { submit(request, future); } else { responseVersion = Math.max(responseVersion, response.version()); completeResponse(response, future); } }); } } else { future.completeExceptionally(error); } }); return future; }
private QueryRequest q(String query) { return QueryRequest.createQuery(query, (byte) 5); }
/** * @param queryRequest * @param toPopulate * @return */ private boolean createFlatKeys(QueryRequest queryRequest, List<KeyValueQueryContent> toPopulate) { /** Check the validity of the requested query. */ final KeywordSearchQuery keywordSearchQuery = queryRequest.getQuery(); if (!keywordSearchQuery.validate()) { // TODO mark the particular query node RED return false; } /** Execute the requested query. */ QueryResults queryResults; try { queryResults = keywordSearchQuery.performQuery(); } catch (NoOpenCoreException ex) { logger.log( Level.SEVERE, "Could not perform the query " + keywordSearchQuery.getQueryString(), ex); // NON-NLS return false; } int id = 0; List<KeyValueQueryContent> tempList = new ArrayList<>(); for (KeywordHit hit : getOneHitPerObject(queryResults)) { /** Get file properties. */ Map<String, Object> properties = new LinkedHashMap<>(); Content content = hit.getContent(); if (content instanceof AbstractFile) { AbstractFsContentNode.fillPropertyMap(properties, (AbstractFile) content); } else { properties.put( AbstractAbstractFileNode.AbstractFilePropertyType.LOCATION.toString(), content.getName()); } /** Add a snippet property, if available. */ if (hit.hasSnippet()) { setCommonProperty(properties, CommonPropertyTypes.CONTEXT, hit.getSnippet()); } // @@@ USE ConentHit in UniqueFileMap instead of the below search // get unique match result files // BC: @@@ THis is really ineffecient. We should keep track of this when // we flattened the list of files to the unique files. final String highlightQueryEscaped = getHighlightQuery( keywordSearchQuery, keywordSearchQuery.isLiteral(), queryResults, content); String name = content.getName(); if (hit.isArtifactHit()) name = hit.getArtifact().getDisplayName() + " Artifact"; // NON-NLS tempList.add( new KeyValueQueryContent( name, properties, ++id, hit.getSolrObjectId(), content, highlightQueryEscaped, keywordSearchQuery, queryResults)); } // Add all the nodes to toPopulate at once. Minimizes node creation // EDT threads, which can slow and/or hang the UI on large queries. toPopulate.addAll(tempList); // write to bb // cannot reuse snippet in BlackboardResultWriter // because for regex searches in UI we compress results by showing a content per regex once // (even if multiple term hits) // whereas in bb we write every hit per content separately new BlackboardResultWriter(queryResults, queryRequest.getQuery().getKeywordList().getName()) .execute(); return true; }
/** * It submits a query statement and get a response immediately. The response only contains a query * id, and submission status. In order to get the result, you should use {@link * #getQueryResult(tajo.QueryId)} or {@link #getQueryResultAndWait(tajo.QueryId)}. */ public SubmitQueryRespose executeQuery(String tql) throws ServiceException { QueryRequest.Builder builder = QueryRequest.newBuilder(); builder.setQuery(tql); return service.submitQuery(null, builder.build()); }
@Test public void toAnnotationQueryWhenNoInputIsNull() { QueryRequest request = QueryRequest.builder().serviceName("security-service").build(); assertThat(request.toAnnotationQuery()).isNull(); }
@Test public void serviceNameCanBeNull() { assertThat(QueryRequest.builder().build().serviceName).isNull(); }