Skip to content

Commit 3c93f74

Browse files
authored
Updated the composite query logic to handle the validateQuery mechanism (#2744)
* Updated the composite query logic to handle the validateQuery mechanism * Updated the filtered query logic and delegating query logic also
1 parent 17a7625 commit 3c93f74

File tree

4 files changed

+133
-0
lines changed

4 files changed

+133
-0
lines changed

core/query/src/main/java/datawave/core/query/logic/DelegatingQueryLogic.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import org.apache.accumulo.core.client.AccumuloClient;
1010
import org.apache.accumulo.core.security.Authorizations;
11+
import org.apache.commons.collections4.Transformer;
1112
import org.apache.commons.collections4.iterators.TransformIterator;
1213

1314
import datawave.audit.SelectorExtractor;
@@ -21,6 +22,7 @@
2122
import datawave.webservice.common.connection.AccumuloClientConfiguration;
2223
import datawave.webservice.query.exception.QueryException;
2324
import datawave.webservice.query.result.event.ResponseObjectFactory;
25+
import datawave.webservice.result.QueryValidationResponse;
2426

2527
/**
2628
* A delegating query logic that simply passes through to a delegate query logic. Intended to simplify extending classes.
@@ -91,6 +93,11 @@ public final QueryLogicTransformer getEnrichedTransformer(Query settings) {
9193
return delegate.getEnrichedTransformer(settings);
9294
}
9395

96+
@Override
97+
public ResultPostprocessor getResultPostprocessor(GenericQueryConfiguration config) {
98+
return delegate.getResultPostprocessor(config);
99+
}
100+
94101
@Override
95102
public String getResponseClass(Query query) throws QueryException {
96103
return delegate.getResponseClass(query);
@@ -368,6 +375,16 @@ public void setServerUser(ProxiedUserDetails serverUser) {
368375
delegate.setServerUser(serverUser);
369376
}
370377

378+
@Override
379+
public Object validateQuery(AccumuloClient client, Query query, Set<Authorizations> auths) throws Exception {
380+
return delegate.validateQuery(client, query, auths);
381+
}
382+
383+
@Override
384+
public Transformer<Object,QueryValidationResponse> getQueryValidationResponseTransformer() {
385+
return delegate.getQueryValidationResponseTransformer();
386+
}
387+
371388
@Override
372389
public UserOperations getUserOperations() {
373390
return delegate.getUserOperations();

core/query/src/main/java/datawave/core/query/logic/composite/CompositeQueryLogic.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.apache.accumulo.core.client.AccumuloClient;
1818
import org.apache.accumulo.core.security.Authorizations;
19+
import org.apache.commons.collections4.Transformer;
1920
import org.apache.commons.collections4.iterators.TransformIterator;
2021
import org.slf4j.Logger;
2122
import org.slf4j.LoggerFactory;
@@ -42,6 +43,7 @@
4243
import datawave.security.authorization.UserOperations;
4344
import datawave.webservice.query.result.event.EventBase;
4445
import datawave.webservice.result.BaseResponse;
46+
import datawave.webservice.result.QueryValidationResponse;
4547

4648
/**
4749
* Query Logic implementation that is configured with more than one query logic delegate. The queries are run in parallel unless configured to be sequential.
@@ -726,6 +728,34 @@ public void setServerUser(ProxiedUserDetails user) {
726728
}
727729
}
728730

731+
@Override
732+
public Object validateQuery(AccumuloClient client, Query query, Set<Authorizations> auths) throws Exception {
733+
// see if we can find a query logic that supports this method
734+
for (QueryLogic<?> logic : getQueryLogics().values()) {
735+
try {
736+
return logic.validateQuery(client, query, auths);
737+
} catch (UnsupportedOperationException uoe) {
738+
// try the next one
739+
}
740+
}
741+
// ok, call the super method to throw the exception
742+
return super.validateQuery(client, query, auths);
743+
}
744+
745+
@Override
746+
public Transformer<Object,QueryValidationResponse> getQueryValidationResponseTransformer() {
747+
// see if we can find a query logic that supports this method
748+
for (QueryLogic<?> logic : getQueryLogics().values()) {
749+
try {
750+
return logic.getQueryValidationResponseTransformer();
751+
} catch (UnsupportedOperationException uoe) {
752+
// try the next one
753+
}
754+
}
755+
// ok, call the super method to throw the exception
756+
return super.getQueryValidationResponseTransformer();
757+
}
758+
729759
/**
730760
* Setting the page processing start time is called after the logic is created. Pass this on to the children.
731761
*

core/query/src/main/java/datawave/core/query/logic/filtered/FilteredQueryLogic.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ public TransformIterator getTransformIterator(Query settings) {
131131
}
132132
}
133133

134+
@Override
135+
public Object validateQuery(AccumuloClient client, Query query, Set<Authorizations> auths) throws Exception {
136+
if (!isFiltered()) {
137+
return super.validateQuery(client, query, auths);
138+
} else {
139+
throw new UnsupportedOperationException("Query validation not implemented");
140+
}
141+
}
142+
134143
@Override
135144
public UserOperations getUserOperations() {
136145
if (!isFiltered()) {

web-services/query/src/test/java/datawave/webservice/query/logic/composite/CompositeQueryLogicTest.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.apache.accumulo.core.security.ColumnVisibility;
2121
import org.apache.accumulo.core.security.VisibilityEvaluator;
2222
import org.apache.accumulo.core.security.VisibilityParseException;
23+
import org.apache.commons.collections4.Transformer;
2324
import org.apache.commons.collections4.iterators.TransformIterator;
2425
import org.junit.Assert;
2526
import org.junit.Before;
@@ -57,6 +58,7 @@
5758
import datawave.webservice.query.result.edge.EdgeBase;
5859
import datawave.webservice.result.BaseQueryResponse;
5960
import datawave.webservice.result.GenericResponse;
61+
import datawave.webservice.result.QueryValidationResponse;
6062

6163
public class CompositeQueryLogicTest {
6264

@@ -88,6 +90,8 @@ public class CompositeQueryLogicTest {
8890
private Value valueFailure = new Value(keyFailure.getRowData().getBackingArray());
8991
private Value valueSpecial = new Value(keySpecial.getRowData().getBackingArray());
9092

93+
private static final String VALIDATION_MESSAGE = "Light is green, the trap is clean";
94+
9195
public static class TestQueryConfiguration extends GenericQueryConfiguration {
9296

9397
}
@@ -454,6 +458,33 @@ public Set<String> getExampleQueries() {
454458
return Collections.emptySet();
455459
}
456460

461+
@Override
462+
public Object validateQuery(AccumuloClient client, Query query, Set<Authorizations> auths) throws Exception {
463+
// return something valid
464+
return VALIDATION_MESSAGE;
465+
}
466+
467+
@Override
468+
public Transformer<Object,QueryValidationResponse> getQueryValidationResponseTransformer() {
469+
return new TestQueryValidationResultTransformer();
470+
}
471+
472+
}
473+
474+
public static class TestQueryValidationResultTransformer implements Transformer<Object,QueryValidationResponse> {
475+
476+
@Override
477+
public QueryValidationResponse transform(Object input) {
478+
String validation = String.valueOf(input);
479+
QueryValidationResponse.Result result = new QueryValidationResponse.Result();
480+
result.setMessages(Collections.singletonList(validation));
481+
482+
QueryValidationResponse response = new QueryValidationResponse();
483+
response.setHasResults(true);
484+
response.setResults(Collections.singletonList(result));
485+
486+
return response;
487+
}
457488
}
458489

459490
public static class TestFilteredQueryLogic extends FilteredQueryLogic {
@@ -1767,4 +1798,50 @@ public void testAuthorizationsUpdate() throws Exception {
17671798
c.close();
17681799
}
17691800

1801+
@Test(expected = UnsupportedOperationException.class)
1802+
public void testValidationFails() throws Exception {
1803+
Map<String,QueryLogic<?>> logics = new HashMap<>();
1804+
TestQueryLogic logic1 = new TestQueryLogic();
1805+
TestQueryLogic2 logic2 = new TestQueryLogic2();
1806+
logics.put("TestQueryLogic", logic1);
1807+
logics.put("TestQueryLogic2", logic2);
1808+
1809+
QueryImpl settings = new QueryImpl();
1810+
settings.setPagesize(100);
1811+
settings.setQueryAuthorizations(auths.toString());
1812+
settings.setQuery("FOO == 'BAR'");
1813+
settings.setParameters(new HashSet<>());
1814+
settings.setId(UUID.randomUUID());
1815+
1816+
CompositeQueryLogic c = new CompositeQueryLogic();
1817+
c.setQueryLogics(logics);
1818+
c.setCurrentUser(principal);
1819+
1820+
c.validateQuery(null, settings, Collections.singleton(auths));
1821+
}
1822+
1823+
@Test
1824+
public void testValidationHappyPath() throws Exception {
1825+
Map<String,QueryLogic<?>> logics = new HashMap<>();
1826+
TestQueryLogic logic1 = new TestQueryLogic();
1827+
DifferentTestQueryLogic logic2 = new DifferentTestQueryLogic();
1828+
logics.put("TestQueryLogic", logic1);
1829+
logics.put("TestQueryLogic2", logic2);
1830+
1831+
QueryImpl settings = new QueryImpl();
1832+
settings.setPagesize(100);
1833+
settings.setQueryAuthorizations(auths.toString());
1834+
settings.setQuery("FOO == 'BAR'");
1835+
settings.setParameters(new HashSet<>());
1836+
settings.setId(UUID.randomUUID());
1837+
1838+
CompositeQueryLogic c = new CompositeQueryLogic();
1839+
c.setQueryLogics(logics);
1840+
c.setCurrentUser(principal);
1841+
1842+
Object validation = c.validateQuery(null, settings, Collections.singleton(auths));
1843+
Transformer<Object,QueryValidationResponse> transformer = c.getQueryValidationResponseTransformer();
1844+
QueryValidationResponse response = transformer.transform(validation);
1845+
Assert.assertEquals(VALIDATION_MESSAGE, response.getResults().get(0).getMessages().get(0));
1846+
}
17701847
}

0 commit comments

Comments
 (0)