Search in sources :

Example 1 with NamespacedIdentifiableCollector

use of com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector in project conquery by bakdata.

the class QueryDescription method addVisitors.

/**
 * Allows the implementation to add visitors that traverse the QueryTree.
 * All visitors are concatenated so only a single traverse needs to be done.
 * @param visitors The structure to which new visitors need to be added.
 */
default void addVisitors(@NonNull ClassToInstanceMap<QueryVisitor> visitors) {
    // Register visitors for permission checks
    visitors.putInstance(NamespacedIdentifiableCollector.class, new NamespacedIdentifiableCollector());
    visitors.putInstance(QueryUtils.ExternalIdChecker.class, new QueryUtils.ExternalIdChecker());
}
Also used : ExternalIdChecker(com.bakdata.conquery.util.QueryUtils.ExternalIdChecker) NamespacedIdentifiableCollector(com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector) QueryUtils(com.bakdata.conquery.util.QueryUtils)

Example 2 with NamespacedIdentifiableCollector

use of com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector in project conquery by bakdata.

the class QueryProcessor method postQuery.

/**
 * Creates a query for all datasets, then submits it for execution on the
 * intended dataset.
 */
public ManagedExecution<?> postQuery(Dataset dataset, QueryDescription query, Subject subject) {
    log.info("Query posted on Dataset[{}] by User[{{}].", dataset.getId(), subject.getId());
    // This maps works as long as we have query visitors that are not configured in anyway.
    // So adding a visitor twice would replace the previous one but both would have yielded the same result.
    // For the future a better data structure might be desired that also regards similar QueryVisitors of different configuration
    ClassToInstanceMap<QueryVisitor> visitors = MutableClassToInstanceMap.create();
    query.addVisitors(visitors);
    // Initialize checks that need to traverse the query tree
    visitors.putInstance(QueryUtils.OnlyReusingChecker.class, new QueryUtils.OnlyReusingChecker());
    visitors.putInstance(NamespacedIdentifiableCollector.class, new NamespacedIdentifiableCollector());
    final String primaryGroupName = AuthorizationHelper.getPrimaryGroup(subject, storage).map(Group::getName).orElse("none");
    visitors.putInstance(ExecutionMetrics.QueryMetricsReporter.class, new ExecutionMetrics.QueryMetricsReporter(primaryGroupName));
    // Chain all Consumers
    Consumer<Visitable> consumerChain = QueryUtils.getNoOpEntryPoint();
    for (QueryVisitor visitor : visitors.values()) {
        consumerChain = consumerChain.andThen(visitor);
    }
    // Apply consumers to the query tree
    query.visit(consumerChain);
    query.authorize(subject, dataset, visitors);
    // After all authorization checks we can now use the actual subject to invoke the query and do not to bubble down the Userish in methods
    ExecutionMetrics.reportNamespacedIds(visitors.getInstance(NamespacedIdentifiableCollector.class).getIdentifiables(), primaryGroupName);
    ExecutionMetrics.reportQueryClassUsage(query.getClass(), primaryGroupName);
    final Namespace namespace = datasetRegistry.get(dataset.getId());
    final ExecutionManager executionManager = namespace.getExecutionManager();
    // If this is only a re-executing query, try to execute the underlying query instead.
    {
        final Optional<ManagedExecutionId> executionId = visitors.getInstance(QueryUtils.OnlyReusingChecker.class).getOnlyReused();
        final Optional<ManagedExecution<?>> execution = executionId.map(id -> tryReuse(query, id, datasetRegistry, config, executionManager, subject.getUser()));
        if (execution.isPresent()) {
            return execution.get();
        }
    }
    // Execute the query
    return executionManager.runQuery(datasetRegistry, query, subject.getUser(), dataset, config);
}
Also used : ManagedQuery(com.bakdata.conquery.models.query.ManagedQuery) ConqueryConfig(com.bakdata.conquery.models.config.ConqueryConfig) URL(java.net.URL) ExternalUpload(com.bakdata.conquery.apiv1.query.ExternalUpload) RequiredArgsConstructor(lombok.RequiredArgsConstructor) ManagedExecution(com.bakdata.conquery.models.execution.ManagedExecution) Map(java.util.Map) DatasetId(com.bakdata.conquery.models.identifiable.ids.specific.DatasetId) BadRequestException(javax.ws.rs.BadRequestException) UriBuilder(javax.ws.rs.core.UriBuilder) QueryDescription(com.bakdata.conquery.apiv1.query.QueryDescription) CQAnd(com.bakdata.conquery.apiv1.query.concept.specific.CQAnd) ExecutionMetrics(com.bakdata.conquery.metrics.ExecutionMetrics) Collection(java.util.Collection) SecondaryIdQuery(com.bakdata.conquery.apiv1.query.SecondaryIdQuery) Visitable(com.bakdata.conquery.models.query.Visitable) Set(java.util.Set) User(com.bakdata.conquery.models.auth.entities.User) Collectors(java.util.stream.Collectors) Dataset(com.bakdata.conquery.models.datasets.Dataset) ConceptQuery(com.bakdata.conquery.apiv1.query.ConceptQuery) ExternalUploadResult(com.bakdata.conquery.apiv1.query.ExternalUploadResult) SecondaryIdDescription(com.bakdata.conquery.models.datasets.SecondaryIdDescription) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Stream(java.util.stream.Stream) Response(javax.ws.rs.core.Response) CancelQuery(com.bakdata.conquery.models.messages.namespaces.specific.CancelQuery) Ability(com.bakdata.conquery.models.auth.permissions.Ability) QueryUtils(com.bakdata.conquery.util.QueryUtils) Optional(java.util.Optional) MetaStorage(com.bakdata.conquery.io.storage.MetaStorage) Namespace(com.bakdata.conquery.models.worker.Namespace) ExecutionManager(com.bakdata.conquery.models.query.ExecutionManager) ResultRendererProvider(com.bakdata.conquery.io.result.ResultRender.ResultRendererProvider) Getter(lombok.Getter) ExecutionState(com.bakdata.conquery.models.execution.ExecutionState) Subject(com.bakdata.conquery.models.auth.entities.Subject) ClassToInstanceMap(com.google.common.collect.ClassToInstanceMap) HttpServletRequest(javax.servlet.http.HttpServletRequest) ManagedExecutionId(com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId) QueryVisitor(com.bakdata.conquery.models.query.visitor.QueryVisitor) NamespacedIdentifiableCollector(com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector) Group(com.bakdata.conquery.models.auth.entities.Group) CQExternal(com.bakdata.conquery.apiv1.query.concept.specific.external.CQExternal) AuthorizationHelper(com.bakdata.conquery.models.auth.AuthorizationHelper) Consumer(java.util.function.Consumer) MutableClassToInstanceMap(com.google.common.collect.MutableClassToInstanceMap) AuthorizationHelper.buildDatasetAbilityMap(com.bakdata.conquery.models.auth.AuthorizationHelper.buildDatasetAbilityMap) DatasetRegistry(com.bakdata.conquery.models.worker.DatasetRegistry) CQElement(com.bakdata.conquery.apiv1.query.CQElement) Query(com.bakdata.conquery.apiv1.query.Query) QueryVisitor(com.bakdata.conquery.models.query.visitor.QueryVisitor) ExecutionManager(com.bakdata.conquery.models.query.ExecutionManager) NamespacedIdentifiableCollector(com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector) Optional(java.util.Optional) Visitable(com.bakdata.conquery.models.query.Visitable) ExecutionMetrics(com.bakdata.conquery.metrics.ExecutionMetrics) Namespace(com.bakdata.conquery.models.worker.Namespace) QueryUtils(com.bakdata.conquery.util.QueryUtils)

Example 3 with NamespacedIdentifiableCollector

use of com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector in project conquery by bakdata.

the class AuthorizationHelper method authorizeDownloadDatasets.

/**
 * Checks if an execution is allowed to be downloaded by a user.
 * This checks all used {@link DatasetId}s for the {@link Ability#DOWNLOAD} on the user.
 */
public static void authorizeDownloadDatasets(@NonNull Subject subject, @NonNull Visitable visitable) {
    NamespacedIdentifiableCollector collector = new NamespacedIdentifiableCollector();
    visitable.visit(collector);
    Set<Dataset> datasets = collector.getIdentifiables().stream().map(NamespacedIdentifiable::getDataset).collect(Collectors.toSet());
    subject.authorize(datasets, Ability.DOWNLOAD);
}
Also used : NamespacedIdentifiableCollector(com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector) Dataset(com.bakdata.conquery.models.datasets.Dataset)

Example 4 with NamespacedIdentifiableCollector

use of com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector in project conquery by bakdata.

the class ManagedQuery method getUsedNamespacedIds.

@Override
@JsonIgnore
public Set<NamespacedIdentifiable<?>> getUsedNamespacedIds() {
    NamespacedIdentifiableCollector collector = new NamespacedIdentifiableCollector();
    query.visit(collector);
    return collector.getIdentifiables();
}
Also used : NamespacedIdentifiableCollector(com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector) JsonIgnore(com.fasterxml.jackson.annotation.JsonIgnore)

Example 5 with NamespacedIdentifiableCollector

use of com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector in project conquery by bakdata.

the class ManagedExecution method setAdditionalFieldsForStatusWithSource.

/**
 * Sets additional fields of an {@link ExecutionStatus} when a more specific status is requested.
 */
protected void setAdditionalFieldsForStatusWithSource(Subject subject, FullExecutionStatus status) {
    QueryDescription query = getSubmitted();
    NamespacedIdentifiableCollector namespacesIdCollector = new NamespacedIdentifiableCollector();
    query.visit(namespacesIdCollector);
    final Set<Concept> concepts = namespacesIdCollector.getIdentifiables().stream().filter(ConceptElement.class::isInstance).map(ConceptElement.class::cast).map(ConceptElement::getConcept).collect(Collectors.toSet());
    boolean canExpand = subject.isPermittedAll(concepts, Ability.READ);
    status.setCanExpand(canExpand);
    status.setQuery(canExpand ? getSubmitted() : null);
}
Also used : Concept(com.bakdata.conquery.models.datasets.concepts.Concept) NamespacedIdentifiableCollector(com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector) ConceptElement(com.bakdata.conquery.models.datasets.concepts.ConceptElement) QueryDescription(com.bakdata.conquery.apiv1.query.QueryDescription)

Aggregations

NamespacedIdentifiableCollector (com.bakdata.conquery.util.QueryUtils.NamespacedIdentifiableCollector)6 Dataset (com.bakdata.conquery.models.datasets.Dataset)3 QueryUtils (com.bakdata.conquery.util.QueryUtils)3 QueryDescription (com.bakdata.conquery.apiv1.query.QueryDescription)2 Concept (com.bakdata.conquery.models.datasets.concepts.Concept)2 ConceptElement (com.bakdata.conquery.models.datasets.concepts.ConceptElement)2 ExternalIdChecker (com.bakdata.conquery.util.QueryUtils.ExternalIdChecker)2 CQElement (com.bakdata.conquery.apiv1.query.CQElement)1 ConceptQuery (com.bakdata.conquery.apiv1.query.ConceptQuery)1 ExternalUpload (com.bakdata.conquery.apiv1.query.ExternalUpload)1 ExternalUploadResult (com.bakdata.conquery.apiv1.query.ExternalUploadResult)1 Query (com.bakdata.conquery.apiv1.query.Query)1 SecondaryIdQuery (com.bakdata.conquery.apiv1.query.SecondaryIdQuery)1 CQAnd (com.bakdata.conquery.apiv1.query.concept.specific.CQAnd)1 CQExternal (com.bakdata.conquery.apiv1.query.concept.specific.external.CQExternal)1 ResultRendererProvider (com.bakdata.conquery.io.result.ResultRender.ResultRendererProvider)1 MetaStorage (com.bakdata.conquery.io.storage.MetaStorage)1 ExecutionMetrics (com.bakdata.conquery.metrics.ExecutionMetrics)1 AuthorizationHelper (com.bakdata.conquery.models.auth.AuthorizationHelper)1 AuthorizationHelper.buildDatasetAbilityMap (com.bakdata.conquery.models.auth.AuthorizationHelper.buildDatasetAbilityMap)1