use of com.b2international.commons.exceptions.BadRequestException in project snow-owl by b2ihealthcare.
the class ConceptSearchRequest method doExecute.
@Override
protected Concepts doExecute(ServiceProvider context) throws IOException {
final int limit = limit();
Options conceptSearchOptions = Options.builder().putAll(options()).put(ConceptSearchRequestEvaluator.OptionKey.ID, componentIds()).put(ConceptSearchRequestEvaluator.OptionKey.AFTER, searchAfter()).put(ConceptSearchRequestEvaluator.OptionKey.LIMIT, limit).put(ConceptSearchRequestEvaluator.OptionKey.LOCALES, locales()).put(ConceptSearchRequestEvaluator.OptionKey.FIELDS, fields()).put(ConceptSearchRequestEvaluator.OptionKey.EXPAND, expand()).put(SearchResourceRequest.OptionKey.SORT_BY, sortBy()).build();
final CodeSystemSearchRequestBuilder codeSystemSearchReq = CodeSystemRequests.prepareSearchCodeSystem().all();
final Map<ResourceURI, ResourceURI> codeSystemResourceFiltersByResource;
if (containsKey(OptionKey.CODESYSTEM)) {
// remove path so we can use the code resource URI as key
codeSystemResourceFiltersByResource = Maps.uniqueIndex(getCollection(OptionKey.CODESYSTEM, ResourceURI.class), uri -> uri.withoutPath());
// for filtering use the keys
codeSystemSearchReq.filterByIds(codeSystemResourceFiltersByResource.keySet().stream().map(ResourceURI::getResourceId).collect(Collectors.toSet()));
} else {
codeSystemResourceFiltersByResource = Collections.emptyMap();
}
// .filterByToolingIds(toolingIds) TODO perform TOOLING filtering
// .filterByUrls(urls) TODO perform URL filtering
List<Concepts> concepts = codeSystemSearchReq.buildAsync().execute(context).stream().map(codeSystem -> {
final ResourceURI uriToEvaluateOn = codeSystemResourceFiltersByResource.getOrDefault(codeSystem.getResourceURI(), codeSystem.getResourceURI());
return context.service(RepositoryManager.class).get(codeSystem.getToolingId()).service(ConceptSearchRequestEvaluator.class).evaluate(uriToEvaluateOn, context, conceptSearchOptions);
}).collect(Collectors.toList());
// for single CodeSystem searches, sorting, paging works as it should
if (concepts.size() == 1) {
return Iterables.getOnlyElement(concepts);
}
// otherwise, check if searchAfter was used, as it would return bogus results; it can not be applied across code systems
if (searchAfter() != null) {
throw new BadRequestException("searchAfter is not supported in Concept Search API for multiple code systems.");
}
// calculate grand total
int total = 0;
for (Concepts conceptsToAdd : concepts) {
total += conceptsToAdd.getTotal();
}
return new Concepts(// TODO add manual sorting here if multiple resources have been fetched
concepts.stream().flatMap(Concepts::stream).limit(limit).collect(Collectors.toList()), null, /* not supported across codesystems */
limit, total);
}
use of com.b2international.commons.exceptions.BadRequestException in project snow-owl by b2ihealthcare.
the class SnomedRf2ExportRequest method execute.
@Override
public Attachment execute(final BranchContext context) {
final String referenceBranch = context.path();
if (referenceBranch.contains(RevisionIndex.AT_CHAR) && !Rf2ReleaseType.SNAPSHOT.equals(releaseType)) {
throw new BadRequestException("Only snapshot export is allowed for point-in-time branch path '%s'.", referenceBranch);
}
if (referenceBranch.contains(RevisionIndex.REV_RANGE)) {
if (!Rf2ReleaseType.DELTA.equals(releaseType) || needsVersionBranchesForDeltaExport()) {
throw new BadRequestException("Only unpublished delta export is allowed for branch path range '%s'.", referenceBranch);
}
}
// register export start time for later use
final long exportStartTime = Instant.now().toEpochMilli();
// Step 1: check if the export reference branch is a working branch path descendant
final CodeSystem referenceCodeSystem = (CodeSystem) context.service(TerminologyResource.class);
if (!CompareUtils.isEmpty(referenceCodeSystem.getSettings())) {
if (Strings.isNullOrEmpty(countryNamespaceElement)) {
if (maintainerType == null) {
String maintainerType = (String) referenceCodeSystem.getSettings().get(SnomedTerminologyComponentConstants.CODESYSTEM_MAINTAINER_TYPE_CONFIG_KEY);
String nrcCountryCode = (String) referenceCodeSystem.getSettings().get(SnomedTerminologyComponentConstants.CODESYSTEM_NRC_COUNTRY_CODE_CONFIG_KEY);
if (!Strings.isNullOrEmpty(maintainerType)) {
String customCountryNamespaceElement = getCountryNamespaceElement(context, referenceCodeSystem, Rf2MaintainerType.getByNameIgnoreCase(maintainerType), Strings.nullToEmpty(nrcCountryCode));
countryNamespaceElement = customCountryNamespaceElement;
}
} else {
countryNamespaceElement = getCountryNamespaceElement(context, referenceCodeSystem, maintainerType, Strings.nullToEmpty(nrcCountryCode));
}
}
if (refSetExportLayout == null && referenceCodeSystem.getSettings().containsKey(SnomedTerminologyComponentConstants.CODESYSTEM_RF2_EXPORT_LAYOUT_CONFIG_KEY)) {
String refSetLayout = (String) referenceCodeSystem.getSettings().get(SnomedTerminologyComponentConstants.CODESYSTEM_RF2_EXPORT_LAYOUT_CONFIG_KEY);
Rf2RefSetExportLayout rf2RefSetExportLayout = Rf2RefSetExportLayout.getByNameIgnoreCase(refSetLayout);
refSetExportLayout = rf2RefSetExportLayout;
}
}
if (Strings.isNullOrEmpty(countryNamespaceElement)) {
countryNamespaceElement = getCountryNamespaceElement(context, referenceCodeSystem, DEFAULT_MAINTAINER_TYPE, "");
}
if (refSetExportLayout == null) {
refSetExportLayout = DEFAULT_RF2_EXPORT_LAYOUT;
}
// Step 2: retrieve code system versions that are visible from the reference branch
final TreeSet<Version> versionsToExport = getAllExportableCodeSystemVersions(context, referenceCodeSystem);
// Step 3: compute branches to export
final List<String> branchesToExport = computeBranchesToExport(referenceBranch, versionsToExport);
// Step 4: compute possible language codes
Multimap<String, String> availableLanguageCodes = getLanguageCodes(context, branchesToExport);
Path exportDirectory = null;
try {
final UUID exportId = UUID.randomUUID();
// create temporary export directory
exportDirectory = createExportDirectory(exportId);
// get archive effective time based on latest version effective / transient effective time / current date
final LocalDateTime archiveEffectiveDate = getArchiveEffectiveTime(context, versionsToExport);
final String archiveEffectiveDateShort = EffectiveTimes.format(archiveEffectiveDate.toLocalDate(), DateFormats.SHORT);
// create main folder including release status and archive effective date
final Path releaseDirectory = createReleaseDirectory(exportDirectory, archiveEffectiveDate);
final Set<String> visitedComponentEffectiveTimes = newHashSet();
final long effectiveTimeStart = startEffectiveTime != null ? EffectiveTimes.getEffectiveTime(startEffectiveTime) : 0;
final long effectiveTimeEnd = endEffectiveTime != null ? EffectiveTimes.getEffectiveTime(endEffectiveTime) : Long.MAX_VALUE;
// export content from the pre-computed version branches
for (String branch : branchesToExport) {
exportBranch(releaseDirectory, context, branch, archiveEffectiveDateShort, effectiveTimeStart, effectiveTimeEnd, visitedComponentEffectiveTimes, availableLanguageCodes.get(branch));
}
// export content from reference branch
if (includePreReleaseContent) {
// If a special branch path was given, use it directly
final String referenceBranchToExport = containsSpecialCharacter(referenceBranch) ? referenceBranch : RevisionIndex.toBranchAtPath(referenceBranch, exportStartTime);
exportBranch(releaseDirectory, context, referenceBranchToExport, archiveEffectiveDateShort, EffectiveTimes.UNSET_EFFECTIVE_TIME, EffectiveTimes.UNSET_EFFECTIVE_TIME, visitedComponentEffectiveTimes, availableLanguageCodes.get(referenceBranch));
}
// Step 6: compress to archive and upload to the file registry
final AttachmentRegistry fileRegistry = context.service(AttachmentRegistry.class);
registerResult(fileRegistry, exportId, exportDirectory);
final String fileName = releaseDirectory.getFileName() + ".zip";
return new Attachment(exportId, fileName);
} catch (final Exception e) {
throw new SnowowlRuntimeException("Failed to export terminology content to RF2.", e);
} finally {
if (exportDirectory != null) {
FileUtils.deleteDirectory(exportDirectory.toFile());
}
}
}
use of com.b2international.commons.exceptions.BadRequestException in project snow-owl by b2ihealthcare.
the class SnomedRf2ImportRequest method validate.
private void validate(BranchContext context, final Rf2ImportConfiguration importConfig) {
final boolean contentAvailable = context.service(ContentAvailabilityInfoProvider.class).isAvailable(context);
if (!contentAvailable && Rf2ReleaseType.DELTA.equals(releaseType)) {
throw new BadRequestException("Importing a Delta release of SNOMED CT " + "from an archive to any branch is prohibited when SNOMED CT " + "ontology is not available on the terminology server. " + "Please perform either a Full or a Snapshot import instead.");
}
String codeSystemWorkingBranchPath = context.service(TerminologyResource.class).getBranchPath();
if (importConfig.isCreateVersions()) {
if (!codeSystemWorkingBranchPath.equals(context.branch().path())) {
throw new BadRequestException("Creating a version during RF2 import from a branch is not supported. " + "Please perform the import process from the corresponding CodeSystem's working branch, '%s'.", codeSystemWorkingBranchPath);
} else {
// importing into main development branch with create version enabled should be allowed only and only if the branch does not have any unpublished content present
for (Class<?> type : List.of(SnomedConceptDocument.class, SnomedDescriptionIndexEntry.class, SnomedRelationshipIndexEntry.class, SnomedRefSetMemberIndexEntry.class)) {
try {
int numberOfUnpublishedDocuments = context.service(RevisionSearcher.class).search(Query.select(type).where(SnomedDocument.Expressions.effectiveTime(EffectiveTimes.UNSET_EFFECTIVE_TIME)).limit(0).build()).getTotal();
if (numberOfUnpublishedDocuments > 0) {
throw new BadRequestException("Creating a version during RF2 import is prohibited when unpublished content is present on the target.");
}
} catch (IOException e) {
throw new RuntimeException("Failed to check unpublished content presence for type: " + type.getSimpleName(), e);
}
}
}
}
}
use of com.b2international.commons.exceptions.BadRequestException in project snow-owl by b2ihealthcare.
the class SnomedRelationshipUpdateRequest method execute.
@Override
public Boolean execute(final TransactionContext context) {
if (!Strings.isNullOrEmpty(destinationId) && value != null) {
throw new BadRequestException("'destinationId' and 'value' can not be updated at same time");
}
final SnomedRelationshipIndexEntry relationship = context.lookup(componentId(), SnomedRelationshipIndexEntry.class);
final SnomedRelationshipIndexEntry.Builder updatedRelationship = SnomedRelationshipIndexEntry.builder(relationship);
boolean changed = false;
changed |= updateStatus(context, relationship, updatedRelationship);
changed |= updateModuleId(context, relationship, updatedRelationship);
changed |= updateTypeId(context, relationship, updatedRelationship);
changed |= updateDestinationId(context, relationship, updatedRelationship);
changed |= updateValue(context, relationship, updatedRelationship);
changed |= updateGroup(context, relationship, updatedRelationship);
changed |= updateUnionGroup(context, relationship, updatedRelationship);
changed |= updateCharacteristicTypeId(context, relationship, updatedRelationship);
changed |= updateModifierId(context, relationship, updatedRelationship);
changed |= updateEffectiveTime(relationship, updatedRelationship);
if (changed) {
if (!isEffectiveTimeUpdate() && relationship.getEffectiveTime() != EffectiveTimes.UNSET_EFFECTIVE_TIME) {
updatedRelationship.effectiveTime(EffectiveTimes.UNSET_EFFECTIVE_TIME);
}
context.update(relationship, updatedRelationship.build());
}
return changed;
}
use of com.b2international.commons.exceptions.BadRequestException in project snow-owl by b2ihealthcare.
the class CodeSystemUpgradeSynchronizationRequest method execute.
@Override
public Boolean execute(RepositoryContext context) {
final String message = String.format("Merge %s into %s", source, codeSystemId);
CodeSystem codeSystem = CodeSystemRequests.prepareGetCodeSystem(codeSystemId.getResourceId()).build().execute(context);
if (codeSystem.getUpgradeOf() == null) {
throw new BadRequestException("Code System '%s' is not an Upgrade Code System. It cannot be synchronized with '%s'.", codeSystemId, source);
}
final String sourceBranchPath = context.service(ResourceURIPathResolver.class).resolve(context, List.of(source)).stream().findFirst().get();
// merge all changes from the source to the current upgrade of branch
final Merge merge = RepositoryRequests.merging().prepareCreate().setSource(sourceBranchPath).setTarget(codeSystem.getBranchPath()).setUserId(context.service(User.class).getUsername()).setCommitComment(message).setSquash(false).build(codeSystem.getToolingId()).getRequest().execute(context);
if (merge.getStatus() != Merge.Status.COMPLETED) {
// report conflicts
ApiError apiError = merge.getApiError();
Collection<MergeConflict> conflicts = merge.getConflicts();
context.log().error("Failed to sync source CodeSystem content to upgrade CodeSystem. Error: {}. Conflicts: {}", apiError.getMessage(), conflicts);
throw new ConflictException("Upgrade code system synchronization can not be performed due to conflicting content errors.").withAdditionalInfo(Map.of("conflicts", conflicts, "mergeError", apiError.getMessage()));
}
if (!codeSystem.getUpgradeOf().equals(source)) {
return new BranchRequest<>(Branch.MAIN_PATH, new ResourceRepositoryCommitRequestBuilder().setBody((tx) -> {
ResourceDocument entry = tx.lookup(codeSystemId.getResourceId(), ResourceDocument.class);
tx.add(ResourceDocument.builder(entry).upgradeOf(source).build());
tx.commit(String.format("Update upgradeOf from '%s' to '%s'", codeSystem.getUpgradeOf(), source));
return Boolean.TRUE;
}).setCommitComment(String.format("Complete upgrade of %s to %s", codeSystem.getUpgradeOf().getResourceId(), codeSystem.getExtensionOf())).build()).execute(context).getResultAs(Boolean.class);
} else {
return Boolean.TRUE;
}
}
Aggregations