use of com.b2international.snowowl.core.attachments.Attachment in project snow-owl by b2ihealthcare.
the class SnomedRf2NextReleaseImportTest method doImport.
private void doImport(final String importFile, final String importUntil) {
Attachment attachment = Attachment.upload(Services.context(), PlatformUtil.toAbsolutePathBundleEntry(SnomedContentRule.class, importFile));
String jobId = SnomedRequests.rf2().prepareImport().setRf2Archive(attachment).setReleaseType(Rf2ReleaseType.FULL).setCreateVersions(true).setImportUntil(importUntil).build(SnomedContentRule.SNOMEDCT).runAsJobWithRestart(SnomedRf2Requests.importJobKey(SnomedContentRule.SNOMEDCT), String.format("Import %s release", importFile)).execute(Services.bus()).getSync(1, TimeUnit.MINUTES);
RemoteJobEntry job = JobRequests.waitForJob(Services.bus(), jobId, 2000);
assertTrue("Failed to import RF2 archive", job.isSuccessful());
// assert that the version for importUntil is present in the system
Version latestVersion = CodeSystemVersionRestRequests.getLatestVersion(SnomedContentRule.SNOMEDCT_ID).get();
assertEquals(importUntil, EffectiveTimes.format(latestVersion.getEffectiveTime(), DateFormats.SHORT));
}
use of com.b2international.snowowl.core.attachments.Attachment 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.snowowl.core.attachments.Attachment in project snow-owl by b2ihealthcare.
the class SnomedExportApiTest method executeMultipleExportsAtTheSameTime.
@Test
public void executeMultipleExportsAtTheSameTime() throws Exception {
Promise<Attachment> first = SnomedRequests.rf2().prepareExport().setReleaseType(Rf2ReleaseType.FULL).setCountryNamespaceElement("INT").setRefSetExportLayout(Rf2RefSetExportLayout.COMBINED).setLocales(LOCALES).build(branchPath.getPath()).execute(getBus());
Promise<Attachment> second = SnomedRequests.rf2().prepareExport().setCountryNamespaceElement("INT").setRefSetExportLayout(Rf2RefSetExportLayout.COMBINED).setReleaseType(Rf2ReleaseType.SNAPSHOT).setLocales(LOCALES).build(branchPath.getPath()).execute(getBus());
String message = Promise.all(first, second).then(input -> {
Attachment firstResult = (Attachment) input.get(0);
Attachment secondResult = (Attachment) input.get(1);
InternalAttachmentRegistry fileRegistry = (InternalAttachmentRegistry) ApplicationContext.getServiceForClass(AttachmentRegistry.class);
File firstArchive = fileRegistry.getAttachment(firstResult.getAttachmentId());
File secondArchive = fileRegistry.getAttachment(secondResult.getAttachmentId());
final Map<String, Boolean> firstArchiveMap = ImmutableMap.<String, Boolean>builder().put("sct2_Concept_Full", true).build();
final Map<String, Boolean> secondArchiveMap = ImmutableMap.<String, Boolean>builder().put("sct2_Concept_Snapshot", true).build();
try {
assertArchiveContainsFiles(firstArchive, firstArchiveMap);
assertArchiveContainsFiles(secondArchive, secondArchiveMap);
} catch (Exception e) {
return e.getMessage();
}
fileRegistry.delete(firstResult.getAttachmentId());
fileRegistry.delete(secondResult.getAttachmentId());
return null;
}).fail(input -> input.getMessage()).getSync(2, TimeUnit.MINUTES);
assertNull(message, message);
}
use of com.b2international.snowowl.core.attachments.Attachment in project snow-owl by b2ihealthcare.
the class SnomedRf2ExportRestService method export.
@Operation(summary = "Export SNOMED CT content to RF2", description = "Exports SNOMED CT content from the given branch to RF2.")
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
@GetMapping
@ResponseBody
public ResponseEntity<?> export(@Parameter(description = "The branch path", required = true) @PathVariable(value = "path") final String branch, @ParameterObject final SnomedRf2ExportConfiguration params, @Parameter(description = "Accepted language tags, in order of preference", example = "en-US;q=0.8,en-GB;q=0.6") @RequestHeader(value = HttpHeaders.ACCEPT_LANGUAGE, defaultValue = "en-US;q=0.8,en-GB;q=0.6", required = false) final String acceptLanguage) {
final Attachment exportedFile = SnomedRequests.rf2().prepareExport().setReleaseType(params.getType() == null ? null : Rf2ReleaseType.getByNameIgnoreCase(params.getType())).setExtensionOnly(params.isExtensionOnly()).setLocales(acceptLanguage).setIncludePreReleaseContent(params.isIncludeUnpublished()).setModules(params.getModuleIds()).setRefSets(params.getRefSetIds()).setCountryNamespaceElement(params.getNamespaceId()).setMaintainerType(Strings.isNullOrEmpty(params.getMaintainerType()) ? null : Rf2MaintainerType.getByNameIgnoreCase(params.getMaintainerType())).setNrcCountryCode(params.getNrcCountryCode()).setTransientEffectiveTime(params.getTransientEffectiveTime()).setStartEffectiveTime(params.getStartEffectiveTime()).setEndEffectiveTime(params.getEndEffectiveTime()).setRefSetExportLayout(params.getRefSetLayout() == null ? null : Rf2RefSetExportLayout.getByNameIgnoreCase(params.getRefSetLayout())).setComponentTypes(params.getComponentTypes()).build(branch).execute(getBus()).getSync();
final File file = ((InternalAttachmentRegistry) attachments).getAttachment(exportedFile.getAttachmentId());
final Resource exportZipResource = new FileSystemResource(file);
final HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
httpHeaders.setContentDispositionFormData("attachment", exportedFile.getFileName());
// TODO figure out a smart way to cache export results, probably it could be tied to commitTimestamps/versions/etc.
file.deleteOnExit();
return new ResponseEntity<>(exportZipResource, httpHeaders, HttpStatus.OK);
}
use of com.b2international.snowowl.core.attachments.Attachment in project snow-owl by b2ihealthcare.
the class SnomedRf2ImportRestService method create.
@Operation(summary = "Import SNOMED CT content", description = "Configures processes to import RF2 based archives. The configured process will wait until the archive actually uploaded via the <em>/archive</em> endpoint. " + "The actual import process will start after the file upload completed. Note: unpublished components (with no value entered in the 'effectiveTime' column) are " + "only allowed in DELTA import mode.")
@ApiResponses({ @ApiResponse(responseCode = "201", description = "Created"), @ApiResponse(responseCode = "400", description = "Bad Request"), @ApiResponse(responseCode = "404", description = "Not found") })
@PostMapping(consumes = { AbstractRestService.MULTIPART_MEDIA_TYPE })
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<Void> create(@Parameter(description = "The resource path", required = true) @PathVariable(name = "path") final String path, @Parameter(description = "RF2 Release Type to import from the archive", schema = @Schema(allowableValues = "full,snapshot,delta", defaultValue = "delta")) @RequestParam(name = "type", defaultValue = "delta") final String type, @Parameter(description = "To create versions for the CodeSystem relative to the given path", schema = @Schema(defaultValue = "true")) @RequestParam(name = "createVersions", defaultValue = "true") final Boolean createVersions, @Parameter(description = "Ignore missing referenced components in listed references instead of reporting them as an error.") @RequestParam(name = "ignoreMissingReferencesIn", required = false) final List<String> ignoreMissingReferencesIn, @Parameter(description = "Import all component until this specified effective time value", schema = @Schema(format = "date", pattern = "\\d{6}")) @RequestParam(name = "importUntil", required = false) final String importUntil, @Parameter(description = "Enable to run the import content integrity validations without pushing any changes", schema = @Schema(defaultValue = "false")) @RequestParam(name = "dryRun", defaultValue = "false") final Boolean dryRun, @Parameter(description = "Import file", required = true) @RequestPart("file") final MultipartFile file) throws IOException {
final String importJobId = SnomedRf2Requests.importJobKey(path);
final UUID rf2ArchiveId = UUID.randomUUID();
attachments.upload(rf2ArchiveId, file.getInputStream());
String jobId = SnomedRequests.rf2().prepareImport().setRf2Archive(new Attachment(rf2ArchiveId, file.getName())).setReleaseType(Rf2ReleaseType.getByNameIgnoreCase(type)).setCreateVersions(createVersions).setIgnoreMissingReferencesIn(ignoreMissingReferencesIn).setDryRun(dryRun).setImportUntil(importUntil).build(path).runAsJobWithRestart(importJobId, String.format("Importing SNOMED CT RF2 file '%s'", file.getOriginalFilename())).execute(getBus()).getSync(1, TimeUnit.MINUTES);
return ResponseEntity.created(getResourceLocationURI(path, jobId)).build();
}
Aggregations