Search in sources :

Example 16 with BranchContext

use of com.b2international.snowowl.core.domain.BranchContext in project snow-owl by b2ihealthcare.

the class SnomedConceptCachingRequest method execute.

@Override
public R execute(BranchContext context) {
    SnomedConceptRequestCache cache = new SnomedConceptRequestCache();
    final BranchContext cachingContext = context.inject().bind(SnomedConceptRequestCache.class, cache).build();
    R response = next(cachingContext);
    // compute the cache if the next callback returns successfully
    cache.compute(cachingContext);
    return response;
}
Also used : BranchContext(com.b2international.snowowl.core.domain.BranchContext)

Example 17 with BranchContext

use of com.b2international.snowowl.core.domain.BranchContext in project snow-owl by b2ihealthcare.

the class SaveJobRequest method mergeEquivalentConcepts.

private Set<String> mergeEquivalentConcepts(final BranchContext context, final BulkRequestBuilder<TransactionContext> bulkRequestBuilder, final SnomedNamespaceAndModuleAssigner assigner) {
    if (!fixEquivalences) {
        return Collections.emptySet();
    }
    // XXX: Restrict merging to active components only
    final String expand = "equivalentConcepts(expand(" + "descriptions(active:true)," + "relationships(active:true)," + "inboundRelationships(active:true)," + "members(active:true)))";
    final Multimap<SnomedConcept, SnomedConcept> equivalentConcepts = HashMultimap.create();
    ClassificationRequests.prepareSearchEquivalentConceptSet().setLimit(SCROLL_LIMIT).setExpand(expand).filterByClassificationId(classificationId).stream(context).flatMap(EquivalentConceptSets::stream).filter(equivalentSet -> !equivalentSet.isUnsatisfiable()).forEach(equivalentSet -> {
        final List<SnomedConcept> conceptsToRemove = newArrayList(equivalentSet.getEquivalentConcepts());
        final SnomedConcept conceptToKeep = conceptsToRemove.remove(0);
        equivalentConcepts.putAll(conceptToKeep, conceptsToRemove);
    });
    // Are there any equivalent concepts present? or Were all equivalent concepts unsatisfiable?
    if (equivalentConcepts.isEmpty()) {
        return Collections.emptySet();
    }
    IEquivalentConceptMerger merger = Extensions.getFirstPriorityExtension(IEquivalentConceptMerger.EXTENSION_POINT, IEquivalentConceptMerger.class);
    if (merger == null) {
        merger = new IEquivalentConceptMerger.Default();
    }
    final String mergerName = merger.getClass().getSimpleName();
    LOG.info("Reasoner service will use {} for equivalent concept merging.", mergerName);
    final Set<String> conceptIdsToSkip = merger.merge(equivalentConcepts);
    final Set<String> conceptIdsToKeep = equivalentConcepts.keySet().stream().map(SnomedConcept::getId).collect(Collectors.toSet());
    // Prepare to provide namespace-module for inbound relationship source concepts as well
    final Set<String> relationshipChangeConceptIds = newHashSet(conceptIdsToKeep);
    // Add source concepts on new/about to be inactivated inbound relationships, pointing to "kept" concepts
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedRelationship relationship : conceptToKeep.getInboundRelationships()) {
            if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                relationshipChangeConceptIds.add(relationship.getSourceId());
            } else if (!relationship.isActive()) {
                relationshipChangeConceptIds.add(relationship.getSourceId());
            }
        }
    }
    assigner.collectRelationshipNamespacesAndModules(relationshipChangeConceptIds, context);
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedRelationship relationship : conceptToKeep.getInboundRelationships()) {
            // Already handled as another concept's outbound relationship
            if (relationship.getId() == null) {
                continue;
            }
            if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                relationship.setId(null);
                addComponent(bulkRequestBuilder, assigner, relationship);
            } else if (!relationship.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, relationship);
            }
        }
        for (final SnomedRelationship relationship : conceptToKeep.getRelationships()) {
            // Already handled as another concept's inbound relationship
            if (relationship.getId() == null) {
                continue;
            }
            if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                relationship.setId(null);
                addComponent(bulkRequestBuilder, assigner, relationship);
            } else if (!relationship.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, relationship);
            }
        }
    }
    // CD members are always "outbound", however, so the concept SCTID set can be reduced
    assigner.clear();
    assigner.collectConcreteDomainModules(conceptIdsToKeep, context);
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedReferenceSetMember member : conceptToKeep.getMembers()) {
            if (member.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                member.setId(null);
                addComponent(bulkRequestBuilder, assigner, member);
            } else if (member.getId().startsWith(IEquivalentConceptMerger.PREFIX_UPDATED)) {
                // Trim the prefix from the ID to restore its original form
                member.setId(member.getId().substring(IEquivalentConceptMerger.PREFIX_UPDATED.length()));
                bulkRequestBuilder.add(member.toUpdateRequest());
            } else if (!member.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, member);
            }
        }
    }
    // Descriptions are also "outbound"
    assigner.clear();
    assigner.collectRelationshipNamespacesAndModules(conceptIdsToKeep, context);
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedDescription description : conceptToKeep.getDescriptions()) {
            if (description.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                description.setId(null);
                addComponent(bulkRequestBuilder, assigner, description);
            } else if (description.getId().startsWith(IEquivalentConceptMerger.PREFIX_UPDATED)) {
                // Trim the prefix from the ID to restore its original form
                description.setId(description.getId().substring(IEquivalentConceptMerger.PREFIX_UPDATED.length()));
                bulkRequestBuilder.add(description.toUpdateRequest());
            } else if (!description.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, description);
            }
        }
    }
    // Inactivation of "removed" concepts also requires modules to be collected according to the assigner rules
    assigner.clear();
    assigner.collectRelationshipNamespacesAndModules(conceptIdsToSkip, context);
    for (final SnomedConcept conceptToRemove : equivalentConcepts.values()) {
        // Check if the concept needs to be removed or deactivated
        if (!conceptToRemove.isActive()) {
            removeOrDeactivate(bulkRequestBuilder, assigner, conceptToRemove);
        }
    }
    assigner.clear();
    return conceptIdsToSkip;
}
Also used : SnomedRelationshipIndexEntry(com.b2international.snowowl.snomed.datastore.index.entry.SnomedRelationshipIndexEntry) LoggerFactory(org.slf4j.LoggerFactory) RepositoryRequests(com.b2international.snowowl.core.repository.RepositoryRequests) HashMultimap(com.google.common.collect.HashMultimap) AccessControl(com.b2international.snowowl.core.authorization.AccessControl) Map(java.util.Map) IEquivalentConceptMerger(com.b2international.snowowl.snomed.reasoner.equivalence.IEquivalentConceptMerger) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) Permission(com.b2international.snowowl.core.identity.Permission) ClassificationTracker(com.b2international.snowowl.snomed.reasoner.classification.ClassificationTracker) BulkRequestBuilder(com.b2international.snowowl.core.events.bulk.BulkRequestBuilder) SnomedNamespaceAndModuleAssigner(com.b2international.snowowl.snomed.datastore.id.assigner.SnomedNamespaceAndModuleAssigner) ImmutableMap(com.google.common.collect.ImmutableMap) Request(com.b2international.snowowl.core.events.Request) Set(java.util.Set) Commit(com.b2international.index.revision.Commit) NotNull(javax.validation.constraints.NotNull) Collectors(java.util.stream.Collectors) IProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) List(java.util.List) DatastoreLockContextDescriptions(com.b2international.snowowl.core.internal.locks.DatastoreLockContextDescriptions) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) BranchContext(com.b2international.snowowl.core.domain.BranchContext) SnomedCoreConfiguration(com.b2international.snowowl.snomed.datastore.config.SnomedCoreConfiguration) TerminologyResource(com.b2international.snowowl.core.TerminologyResource) Iterables(com.google.common.collect.Iterables) Locks(com.b2international.snowowl.core.locks.Locks) SubMonitor(org.eclipse.core.runtime.SubMonitor) com.b2international.snowowl.snomed.reasoner.domain(com.b2international.snowowl.snomed.reasoner.domain) Extensions(com.b2international.snowowl.core.plugin.Extensions) com.b2international.snowowl.snomed.core.domain(com.b2international.snowowl.snomed.core.domain) Multimap(com.google.common.collect.Multimap) Branch(com.b2international.snowowl.core.branch.Branch) Strings(com.google.common.base.Strings) BulkRequest(com.b2international.snowowl.core.events.bulk.BulkRequest) DEFAULT_NAMESPACE_AND_MODULE_ASSIGNER(com.b2international.snowowl.snomed.common.SnomedTerminologyComponentConstants.DEFAULT_NAMESPACE_AND_MODULE_ASSIGNER) RepositoryConfiguration(com.b2international.snowowl.core.config.RepositoryConfiguration) SnowOwlConfiguration(com.b2international.snowowl.core.config.SnowOwlConfiguration) BadRequestException(com.b2international.commons.exceptions.BadRequestException) Logger(org.slf4j.Logger) CommitResult(com.b2international.snowowl.core.request.CommitResult) com.b2international.snowowl.snomed.datastore.request(com.b2international.snowowl.snomed.datastore.request) NAMESPACE_AND_MODULE_ASSIGNER(com.b2international.snowowl.snomed.common.SnomedTerminologyComponentConstants.NAMESPACE_AND_MODULE_ASSIGNER) TransactionContext(com.b2international.snowowl.core.domain.TransactionContext) SnomedReferenceSetMember(com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember) NotEmpty(org.hibernate.validator.constraints.NotEmpty) LockedException(com.b2international.commons.exceptions.LockedException) User(com.b2international.snowowl.core.identity.User) SnomedRf2Headers(com.b2international.snowowl.snomed.common.SnomedRf2Headers) Collections(java.util.Collections) ReasonerApiException(com.b2international.snowowl.snomed.reasoner.exceptions.ReasonerApiException) SnomedReferenceSetMember(com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember) IEquivalentConceptMerger(com.b2international.snowowl.snomed.reasoner.equivalence.IEquivalentConceptMerger)

Example 18 with BranchContext

use of com.b2international.snowowl.core.domain.BranchContext in project snow-owl by b2ihealthcare.

the class SaveJobRequest method persistChanges.

private Boolean persistChanges(final BranchContext context, final IProgressMonitor monitor) {
    // Repeat the same checks as in ClassificationSaveRequest, now within the lock
    final ClassificationTask classification = ClassificationRequests.prepareGetClassification(classificationId).build().execute(context);
    final String branchPath = classification.getBranch();
    final Branch branch = RepositoryRequests.branching().prepareGet(branchPath).build().execute(context);
    if (!ClassificationSaveRequest.SAVEABLE_STATUSES.contains(classification.getStatus())) {
        throw new BadRequestException("Classification '%s' is not in the expected state to start saving changes.", classificationId);
    }
    if (classification.getTimestamp() < branch.headTimestamp()) {
        throw new BadRequestException("Classification '%s' on branch '%s' is stale (classification timestamp: %s, head timestamp: %s).", classificationId, branchPath, classification.getTimestamp(), branch.headTimestamp());
    }
    final ClassificationTracker classificationTracker = context.service(ClassificationTracker.class);
    // Signal the state change
    classificationTracker.classificationSaving(classificationId);
    final SubMonitor subMonitor = SubMonitor.convert(monitor, "Persisting changes", 6);
    final BulkRequestBuilder<TransactionContext> bulkRequestBuilder = BulkRequest.create();
    applyChanges(subMonitor, context, bulkRequestBuilder);
    long resultTimeStamp = Commit.NO_COMMIT_TIMESTAMP;
    for (List<Request<TransactionContext, ?>> partition : Iterables.partition(bulkRequestBuilder.build().getRequests(), getCommitLimit(context))) {
        final BulkRequestBuilder<TransactionContext> batchRequest = BulkRequest.create();
        partition.forEach(request -> batchRequest.add(request));
        final Request<BranchContext, CommitResult> commitRequest = SnomedRequests.prepareCommit().setBody(batchRequest.build()).setCommitComment(commitComment).setParentContextDescription(DatastoreLockContextDescriptions.SAVE_CLASSIFICATION_RESULTS).setAuthor(userId).build();
        final CommitResult commitResult = new IdRequest<>(commitRequest).execute(context);
        resultTimeStamp = commitResult.getCommitTimestamp();
    }
    if (Commit.NO_COMMIT_TIMESTAMP == resultTimeStamp) {
        classificationTracker.classificationSaveFailed(classificationId);
        return Boolean.FALSE;
    } else {
        classificationTracker.classificationSaved(classificationId, resultTimeStamp);
        return Boolean.TRUE;
    }
}
Also used : CommitResult(com.b2international.snowowl.core.request.CommitResult) SubMonitor(org.eclipse.core.runtime.SubMonitor) Request(com.b2international.snowowl.core.events.Request) BulkRequest(com.b2international.snowowl.core.events.bulk.BulkRequest) Branch(com.b2international.snowowl.core.branch.Branch) TransactionContext(com.b2international.snowowl.core.domain.TransactionContext) BranchContext(com.b2international.snowowl.core.domain.BranchContext) BadRequestException(com.b2international.commons.exceptions.BadRequestException) ClassificationTracker(com.b2international.snowowl.snomed.reasoner.classification.ClassificationTracker)

Example 19 with BranchContext

use of com.b2international.snowowl.core.domain.BranchContext in project snow-owl by b2ihealthcare.

the class EclExpression method resolve.

public Promise<Set<String>> resolve(final BranchContext context) {
    if (promise == null) {
        RevisionSearcher searcher = context.service(RevisionSearcher.class);
        boolean cached = context.optionalService(PathWithVersion.class).isPresent();
        promise = resolveToExpression(context).then(expression -> {
            // shortcut to extract IDs from the query itself if possible
            if (SnomedEclEvaluationRequest.canExtractIds(expression)) {
                return SnomedEclEvaluationRequest.extractIds(expression);
            }
            try {
                return newHashSet(searcher.search(Query.select(String.class).from(SnomedConceptDocument.class).fields(SnomedConceptDocument.Fields.ID).where(expression).limit(Integer.MAX_VALUE).cached(cached).build()));
            } catch (IOException e) {
                throw new SnowowlRuntimeException(e);
            }
        });
    }
    return promise;
}
Also used : Query(com.b2international.index.query.Query) SnomedRelationshipIndexEntry(com.b2international.snowowl.snomed.datastore.index.entry.SnomedRelationshipIndexEntry) Promise(com.b2international.snowowl.core.events.util.Promise) Multimap(com.google.common.collect.Multimap) Multimaps(com.google.common.collect.Multimaps) SnomedRequests(com.b2international.snowowl.snomed.datastore.request.SnomedRequests) Options(com.b2international.commons.options.Options) NestedExpression(com.b2international.snomed.ecl.ecl.NestedExpression) RevisionSearcher(com.b2international.index.revision.RevisionSearcher) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) SnomedConceptDocument(com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument) Nullable(javax.annotation.Nullable) ResourceURI(com.b2international.snowowl.core.ResourceURI) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) Lists.newArrayListWithCapacity(com.google.common.collect.Lists.newArrayListWithCapacity) Function(com.google.common.base.Function) SnowowlRuntimeException(com.b2international.snowowl.core.api.SnowowlRuntimeException) RevisionDocument(com.b2international.snowowl.core.repository.RevisionDocument) SnomedConcepts(com.b2international.snowowl.snomed.core.domain.SnomedConcepts) Set(java.util.Set) IOException(java.io.IOException) IEventBus(com.b2international.snowowl.eventbus.IEventBus) NotNull(javax.validation.constraints.NotNull) PathWithVersion(com.b2international.snowowl.core.uri.ResourceURIPathResolver.PathWithVersion) SnomedRelationships(com.b2international.snowowl.snomed.core.domain.SnomedRelationships) Any(com.b2international.snomed.ecl.ecl.Any) Trees(com.b2international.snowowl.snomed.core.tree.Trees) SearchResourceRequest(com.b2international.snowowl.core.request.SearchResourceRequest) SnomedRelationship(com.b2international.snowowl.snomed.core.domain.SnomedRelationship) List(java.util.List) Expressions(com.b2international.index.query.Expressions) SnomedReferenceSetMember(com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember) Expression(com.b2international.index.query.Expression) Preconditions(com.google.common.base.Preconditions) Ecl(com.b2international.snomed.ecl.Ecl) SnomedRf2Headers(com.b2international.snowowl.snomed.common.SnomedRf2Headers) EclConceptReference(com.b2international.snomed.ecl.ecl.EclConceptReference) ExpressionConstraint(com.b2international.snomed.ecl.ecl.ExpressionConstraint) BranchContext(com.b2international.snowowl.core.domain.BranchContext) SnomedRefSetType(com.b2international.snowowl.snomed.core.domain.refset.SnomedRefSetType) SnomedCoreConfiguration(com.b2international.snowowl.snomed.datastore.config.SnomedCoreConfiguration) PathWithVersion(com.b2international.snowowl.core.uri.ResourceURIPathResolver.PathWithVersion) IOException(java.io.IOException) RevisionSearcher(com.b2international.index.revision.RevisionSearcher) SnowowlRuntimeException(com.b2international.snowowl.core.api.SnowowlRuntimeException)

Example 20 with BranchContext

use of com.b2international.snowowl.core.domain.BranchContext in project snow-owl by b2ihealthcare.

the class SnomedEclLabelerRequest method execute.

@Override
public LabeledEclExpressions execute(BranchContext context) {
    final EclSerializer eclSerializer = context.service(EclSerializer.class);
    final EclParser eclParser = context.service(EclParser.class);
    final Set<String> conceptIdsToLabel = Sets.newHashSetWithExpectedSize(expressions.size());
    final Map<String, ExpressionConstraint> queries = Maps.newHashMapWithExpectedSize(expressions.size());
    final LinkedHashMap<String, Object> errors = Maps.newLinkedHashMap();
    for (String expression : expressions) {
        if (Strings.isNullOrEmpty(expression)) {
            continue;
        }
        try {
            ExpressionConstraint query = queries.computeIfAbsent(expression, (key) -> eclParser.parse(key));
            conceptIdsToLabel.addAll(collect(query));
        } catch (ApiException e) {
            if (e instanceof SyntaxException) {
                errors.put(expression, List.copyOf(((SyntaxException) e).getAdditionalInfo().values()));
            } else if (e instanceof BadRequestException) {
                errors.put(expression, e.getMessage());
            } else {
                throw e;
            }
        }
    }
    if (!errors.isEmpty()) {
        BadRequestException badRequestException = new BadRequestException("One or more ECL syntax errors");
        badRequestException.withAdditionalInfo("erroneousExpressions", errors);
        throw badRequestException;
    }
    // fetch all concept labels
    final Map<String, String> labels = SnomedRequests.prepareSearchConcept().filterByIds(conceptIdsToLabel).setLimit(conceptIdsToLabel.size()).setExpand(descriptionType.toLowerCase() + "()").setLocales(locales()).build().execute(context).stream().collect(Collectors.toMap(SnomedConcept::getId, this::extractLabel));
    // expand all queries with labels
    List<String> results = expressions.stream().map(expression -> {
        if (Strings.isNullOrEmpty(expression)) {
            return expression;
        } else {
            ExpressionConstraint query = queries.get(expression);
            expand(query, labels);
            return eclSerializer.serialize(query);
        }
    }).collect(Collectors.toList());
    return new LabeledEclExpressions(results);
}
Also used : ExpressionConstraint(com.b2international.snomed.ecl.ecl.ExpressionConstraint) BadRequestException(com.b2international.commons.exceptions.BadRequestException) SnomedConcept(com.b2international.snowowl.snomed.core.domain.SnomedConcept) JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) java.util(java.util) EObjectWalker(com.b2international.snowowl.core.emf.EObjectWalker) EObjectTreeNode(com.b2international.snowowl.core.emf.EObjectTreeNode) NotNull(javax.validation.constraints.NotNull) Collectors(java.util.stream.Collectors) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) Strings(com.google.common.base.Strings) SnomedRequests(com.b2international.snowowl.snomed.datastore.request.SnomedRequests) NotEmpty(org.hibernate.validator.constraints.NotEmpty) AccessControl(com.b2international.snowowl.core.authorization.AccessControl) SyntaxException(com.b2international.commons.exceptions.SyntaxException) Permission(com.b2international.snowowl.core.identity.Permission) EclConceptReference(com.b2international.snomed.ecl.ecl.EclConceptReference) ExpressionConstraint(com.b2international.snomed.ecl.ecl.ExpressionConstraint) BranchContext(com.b2international.snowowl.core.domain.BranchContext) NoopTreeVisitor(com.b2international.commons.tree.NoopTreeVisitor) ApiException(com.b2international.commons.exceptions.ApiException) ResourceRequest(com.b2international.snowowl.core.request.ResourceRequest) SyntaxException(com.b2international.commons.exceptions.SyntaxException) BadRequestException(com.b2international.commons.exceptions.BadRequestException) ApiException(com.b2international.commons.exceptions.ApiException)

Aggregations

BranchContext (com.b2international.snowowl.core.domain.BranchContext)27 Collectors (java.util.stream.Collectors)18 SnomedRequests (com.b2international.snowowl.snomed.datastore.request.SnomedRequests)16 Options (com.b2international.commons.options.Options)15 List (java.util.List)15 Set (java.util.Set)14 Sets.newHashSet (com.google.common.collect.Sets.newHashSet)13 IOException (java.io.IOException)13 BadRequestException (com.b2international.commons.exceptions.BadRequestException)12 RevisionSearcher (com.b2international.index.revision.RevisionSearcher)12 Query (com.b2international.index.query.Query)11 ResourceURI (com.b2international.snowowl.core.ResourceURI)11 SnowowlRuntimeException (com.b2international.snowowl.core.api.SnowowlRuntimeException)11 Request (com.b2international.snowowl.core.events.Request)11 Concepts (com.b2international.snowowl.snomed.common.SnomedConstants.Concepts)11 Expression (com.b2international.index.query.Expression)10 SnomedRf2Headers (com.b2international.snowowl.snomed.common.SnomedRf2Headers)10 Expressions (com.b2international.index.query.Expressions)9 ExpressionBuilder (com.b2international.index.query.Expressions.ExpressionBuilder)9 Function (com.google.common.base.Function)9