Skip to content

Commit

Permalink
Adopted query factory in AggregationQueryActor
Browse files Browse the repository at this point in the history
Signed-off-by: Philipp Michalski <Philipp.Michalski@bosch-si.com>
  • Loading branch information
Philipp Michalski authored and Philipp Michalski committed Jan 2, 2018
1 parent 0cdf6ab commit f01de6a
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 97 deletions.
Expand Up @@ -11,24 +11,15 @@
*/
package org.eclipse.ditto.services.thingsearch.query.actors;

import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.eclipse.ditto.model.base.auth.AuthorizationContext;
import org.eclipse.ditto.model.base.auth.AuthorizationSubject;
import org.eclipse.ditto.model.base.headers.DittoHeaders;
import org.eclipse.ditto.model.thingsearchparser.ParserException;
import org.eclipse.ditto.model.thingsearchparser.options.rql.RqlOptionParser;
import org.eclipse.ditto.model.thingsearchparser.predicates.ast.RootNode;
import org.eclipse.ditto.model.thingsearchparser.predicates.rql.RqlPredicateParser;
import org.eclipse.ditto.services.models.thingsearch.commands.sudo.SudoCountThings;
import org.eclipse.ditto.services.thingsearch.querymodel.criteria.Criteria;
import org.eclipse.ditto.services.thingsearch.querymodel.criteria.CriteriaFactory;
import org.eclipse.ditto.services.thingsearch.querymodel.criteria.Predicate;
import org.eclipse.ditto.services.thingsearch.querymodel.expression.FilterFieldExpression;
import org.eclipse.ditto.services.thingsearch.querymodel.expression.ThingsFieldExpressionFactory;
import org.eclipse.ditto.services.thingsearch.querymodel.query.AggregationBuilder;
import org.eclipse.ditto.services.thingsearch.querymodel.query.AggregationBuilderFactory;
Expand Down Expand Up @@ -61,20 +52,18 @@ public final class AggregationQueryActor extends AbstractActor {

private final DiagnosticLoggingAdapter logger = LogUtil.obtain(this);

private final CriteriaFactory criteriaFactory;
private final ThingsFieldExpressionFactory fieldExpressionFactory;
private final QueryFilterCriteriaFactory queryFilterCriteriaFactory;
private final AggregationBuilderFactory aggregationBuilderFactory;
private final RqlOptionParser rqlOptionParser;
private final RqlPredicateParser rqlPredicateParser;

private AggregationQueryActor(final CriteriaFactory criteriaFactory,
final ThingsFieldExpressionFactory fieldExpressionFactory,
final AggregationBuilderFactory aggregationBuilderFactory) {
this.criteriaFactory = criteriaFactory;
this.fieldExpressionFactory = fieldExpressionFactory;
this.aggregationBuilderFactory = aggregationBuilderFactory;
this.queryFilterCriteriaFactory = new QueryFilterCriteriaFactory(criteriaFactory, fieldExpressionFactory);
rqlOptionParser = new RqlOptionParser();
rqlPredicateParser = new RqlPredicateParser();
}

/**
Expand All @@ -92,7 +81,7 @@ public static Props props(final CriteriaFactory criteriaFactory,
private static final long serialVersionUID = 1L;

@Override
public AggregationQueryActor create() throws Exception {
public AggregationQueryActor create() {
return new AggregationQueryActor(criteriaFactory, fieldExpressionFactory, aggregationBuilderFactory);
}
});
Expand Down Expand Up @@ -120,91 +109,46 @@ private <T extends Command> void catchDittoRuntimeException(final Consumer<T> co
}

private void handleCountThings(final CountThings command) {
final Criteria criteria = command.getFilter()
.map(filterString -> mapCriteria(filterString, command.getDittoHeaders()))
.orElse(criteriaFactory.any());
final AggregationBuilder aggregationBuilder = aggregationBuilderFactory.newCountBuilder(criteria)
.authorizationSubjects(extractSidsAsStrings(command.getDittoHeaders().getAuthorizationContext()));
Criteria filterCriteria = queryFilterCriteriaFactory.filterCriteriaRestrictedByNamespace(
command.getFilter().orElse(null),
command.getDittoHeaders(),
command.getNamespaces().orElse(null));

final AggregationBuilder aggregationBuilder = aggregationBuilderFactory.newCountBuilder(filterCriteria)
.authorizationSubjects(command.getDittoHeaders().getAuthorizationContext().getAuthorizationSubjectIds());

getSender().tell(aggregationBuilder.build(), getSelf());
}

private void handleQueryThings(final QueryThings command) {
final Criteria criteria = command.getFilter()
.map(filterString -> mapCriteria(filterString, command.getDittoHeaders()))
.orElse(criteriaFactory.any());

EnsureMonotonicityVisitor.apply(criteria, command.getDittoHeaders());

final AggregationBuilder aggregationBuilder = aggregationBuilderFactory.newBuilder(criteria)
.authorizationSubjects(extractSidsAsStrings(command.getDittoHeaders().getAuthorizationContext()));

final AggregationBuilder finalAggregationBuilder;
if (command.getNamespaces().isPresent()) {
final Set<String> namespaces = command.getNamespaces().get();
final FilterFieldExpression namespaceFieldExpression = fieldExpressionFactory.filterByNamespace();
final Predicate namespacesPredicate =
criteriaFactory.in(namespaces.stream().collect(Collectors.toList()));
final Criteria namespaceCriteria =
criteriaFactory.fieldCriteria(namespaceFieldExpression, namespacesPredicate);

final Criteria filteredCriteria =
criteriaFactory.and(Arrays.asList(criteria, namespaceCriteria));
finalAggregationBuilder = aggregationBuilderFactory.newBuilder(filteredCriteria);
} else {
finalAggregationBuilder = aggregationBuilder;
}
Criteria filterCriteria = queryFilterCriteriaFactory.filterCriteriaRestrictedByNamespace(
command.getFilter().orElse(null),
command.getDittoHeaders(),
command.getNamespaces().orElse(null));

EnsureMonotonicityVisitor.apply(filterCriteria, command.getDittoHeaders());

final AggregationBuilder aggregationBuilder = aggregationBuilderFactory.newBuilder(filterCriteria)
.authorizationSubjects(command.getDittoHeaders().getAuthorizationContext().getAuthorizationSubjectIds());

command.getOptions()
.map(optionStrings -> String.join(",", optionStrings))
.ifPresent(options -> setOptions(options, finalAggregationBuilder, command.getDittoHeaders()));
.ifPresent(options -> setOptions(options, aggregationBuilder, command.getDittoHeaders()));

getSender().tell(aggregationBuilder.build(), getSelf());
}

private void handleSudoCountThings(final SudoCountThings command) {
final Criteria criteria = command.getFilter()
.map(filterString -> mapCriteria(filterString, command.getDittoHeaders()))
.orElse(criteriaFactory.any());
final Criteria criteria = queryFilterCriteriaFactory.filterCriteria(
command.getFilter().orElse(null),
command.getDittoHeaders());

final AggregationBuilder aggregationBuilder = aggregationBuilderFactory.newCountBuilder(criteria);
aggregationBuilder.sudo(true);

getSender().tell(aggregationBuilder.build(), getSelf());
}

private static Collection<String> extractSidsAsStrings(final AuthorizationContext authorizationContext) {
return authorizationContext.getAuthorizationSubjects()
.stream()
.map(AuthorizationSubject::getId)
.collect(Collectors.toList());
}

private Criteria mapCriteria(final String filter, final DittoHeaders dittoHeaders) {
try {
final RootNode rootNode = rqlPredicateParser.parse(filter);
final ParameterPredicateVisitor visitor =
new ParameterPredicateVisitor(criteriaFactory, fieldExpressionFactory);

visitor.visit(rootNode);

final Criteria criteria;
if (visitor.getCriteria().size() > 1) {
criteria = criteriaFactory.and(visitor.getCriteria());
} else if (visitor.getCriteria().size() == 1) {
criteria = visitor.getCriteria().get(0);
} else {
criteria = criteriaFactory.any();
}
return criteria;
} catch (final ParserException | IllegalArgumentException e) {
throw InvalidFilterException.newBuilder()
.message(e.getMessage())
.cause(e)
.dittoHeaders(dittoHeaders)
.build();
}
}

private void setOptions(final String options, final AggregationBuilder aggregationBuilder,
final DittoHeaders dittoHeaders) {
try {
Expand Down
Expand Up @@ -13,7 +13,6 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

Expand All @@ -40,11 +39,11 @@ public QueryFilterCriteriaFactory(final CriteriaFactory criteriaFactory,
this.rqlPredicateParser = new RqlPredicateParser();
}

public Criteria filterCriteriaRestrictedByAclAndNamespace(final String filter, final DittoHeaders dittoHeaders,
final List<String> authorisationSubjectIds, final Set<String> namespaces)
public Criteria filterCriteriaRestrictedByNamespace(final String filter, final DittoHeaders dittoHeaders,
final Set<String> namespaces)
{
final Criteria filterCriteria = filterCriteria(filter, dittoHeaders);
return restrictByAclAndNamespace(authorisationSubjectIds, namespaces, filterCriteria);
return restrictByNamespace(namespaces, filterCriteria);
}

public Criteria filterCriteriaRestrictedByAcl(final String filter, final DittoHeaders dittoHeaders,
Expand All @@ -54,18 +53,6 @@ public Criteria filterCriteriaRestrictedByAcl(final String filter, final DittoHe
return restrictByAcl(authorisationSubjectIds, filterCriteria);
}

public Criteria restrictByAclAndNamespace(final List<String> authorisationSubjectIds, final Set<String>
namespaces, Criteria filterCriteria) {
final List<Criteria> criteriaElements = new LinkedList<>();
criteriaElements.add(aclFilterCriteria(authorisationSubjectIds));
if (null != namespaces) {
criteriaElements.add(namespaceFilterCriteria(namespaces));
}

criteriaElements.add(filterCriteria);
return criteriaFactory.and(criteriaElements);
}

public Criteria restrictByAcl(final List<String> authorisationSubjectIds, Criteria filterCriteria) {
return criteriaFactory.and(Arrays.asList(aclFilterCriteria(authorisationSubjectIds), filterCriteria));
}
Expand Down

0 comments on commit f01de6a

Please sign in to comment.