/** * Primary user method for importing a number of import candidates. * * @param config The configuration information. * @param candidates Hosts information about the files to import. * @return if the import did not exit because of an error */ public boolean importCandidates(ImportConfig config, ImportCandidates candidates) { List<ImportContainer> containers = candidates.getContainers(); if (containers != null) { int numDone = 0; for (int index = 0; index < containers.size(); index++) { ImportContainer ic = containers.get(index); ImportTarget target = config.getTarget(); if (target != null) { try { IObject obj = target.load(store, ic); if (!(obj instanceof Annotation)) { ic.setTarget(obj); } else { // This is likely a "post-processing" annotation // so that we don't have to resolve the target // until later. ic.getCustomAnnotationList().add((Annotation) obj); } } catch (Exception e) { log.error("Could not load target: {}", target); throw new RuntimeException("Failed to load target", e); } } if (config.checksumAlgorithm.get() != null) { ic.setChecksumAlgorithm(config.checksumAlgorithm.get()); } try { importImage(ic, index, numDone, containers.size()); numDone++; } catch (Throwable t) { String message = "Error on import"; if (t instanceof ServerError) { final ServerError se = (ServerError) t; if (StringUtils.isNotBlank(se.message)) { message += ": " + se.message; } } log.error(message, t); if (!config.contOnError.get()) { log.info("Exiting on error"); return false; } else { log.info("Continuing after error"); } } } } return true; }
/** * Provide initial configuration to the server in order to create the {@link ImportProcessPrx} * which will manage state server-side. * * @param container the import container * @return the new import process from the server * @throws ServerError if the import process could not be created * @throws IOException if the used files' absolute path could not be found */ public ImportProcessPrx createImport(final ImportContainer container) throws ServerError, IOException { checkManagedRepo(); String[] usedFiles = container.getUsedFiles(); File target = container.getFile(); if (log.isDebugEnabled()) { log.debug("Main file: " + target.getAbsolutePath()); log.debug("Used files before:"); for (String f : usedFiles) { log.debug(f); } } notifyObservers( new ImportEvent.FILESET_UPLOAD_PREPARATION(null, 0, usedFiles.length, null, null, null)); // Copied to ClientPathExclusion // TODO: allow looser sanitization according to server configuration final FilePathRestrictions portableRequiredRules = FilePathRestrictionInstance.getFilePathRestrictions( FilePathRestrictionInstance.WINDOWS_REQUIRED, FilePathRestrictionInstance.UNIX_REQUIRED); final ClientFilePathTransformer sanitizer = new ClientFilePathTransformer(new MakePathComponentSafe(portableRequiredRules)); final ImportSettings settings = new ImportSettings(); final Fileset fs = new FilesetI(); container.fillData(settings, fs, sanitizer, transfer); String caStr = container.getChecksumAlgorithm(); if (caStr != null) { settings.checksumAlgorithm = ChecksumAlgorithmMapper.getChecksumAlgorithm(caStr); } else { // check if the container object has ChecksumAlgorithm // present and pass it into the settings object settings.checksumAlgorithm = repo.suggestChecksumAlgorithm(availableChecksumAlgorithms); if (settings.checksumAlgorithm == null) { throw new RuntimeException("no supported checksum algorithm negotiated with server"); } } return repo.importFileset(fs, settings); }
/** * Primary user method for importing a number * * @param config The configuration information. * @param candidates Hosts information about the files to import. */ public boolean importCandidates(ImportConfig config, ImportCandidates candidates) { List<ImportContainer> containers = candidates.getContainers(); if (containers != null) { int numDone = 0; for (int index = 0; index < containers.size(); index++) { ImportContainer ic = containers.get(index); if (DATASET_CLASS.equals(config.targetClass.get())) { ic.setTarget(store.getTarget(Dataset.class, config.targetId.get())); } else if (SCREEN_CLASS.equals(config.targetClass.get())) { ic.setTarget(store.getTarget(Screen.class, config.targetId.get())); } if (config.checksumAlgorithm.get() != null) { ic.setChecksumAlgorithm(config.checksumAlgorithm.get()); } try { importImage(ic, index, numDone, containers.size()); numDone++; } catch (Throwable t) { String message = "Error on import"; if (t instanceof ServerError) { final ServerError se = (ServerError) t; if (StringUtils.isNotBlank(se.message)) { message += ": " + se.message; } } log.error(message, t); if (!config.contOnError.get()) { log.info("Exiting on error"); return false; } else { log.info("Continuing after error"); } } } } return true; }
/** * Overridden to handle the end of the process. * * @see CmdCallbackI#onFinished(Response, Status, Current) */ @Override public void onFinished(Response rsp, Status status, Current c) { waitOnInitialization(); // Need non-null container ImportResponse rv = null; final ImportRequest req = (ImportRequest) handle.getRequest(); final Fileset fs = req.activity.getParent(); if (rsp instanceof ERR) { final ERR err = (ERR) rsp; final RuntimeException rt = new RuntimeException( String.format( "Failure response on import!\n" + "Category: %s\n" + "Name: %s\n" + "Parameters: %s\n", err.category, err.name, err.parameters)); notifyObservers( new ErrorHandler.INTERNAL_EXCEPTION( container.getFile().getAbsolutePath(), rt, container.getUsedFiles(), container.getReader())); } else if (rsp instanceof ImportResponse) { rv = (ImportResponse) rsp; if (this.importResponse == null) { // Only respond once. notifyObservers( new ImportEvent.IMPORT_DONE( 0, container, null, null, 0, null, rv.pixels, fs, rv.objects)); } this.importResponse = rv; } else { final RuntimeException rt = new RuntimeException("Unknown response: " + rsp); notifyObservers( new ErrorHandler.INTERNAL_EXCEPTION( container.getFile().getAbsolutePath(), rt, container.getUsedFiles(), container.getReader())); } onFinishedDone(); }
/** * Perform an image import uploading files if necessary. * * @param container The import container which houses all the configuration values and target for * the import. * @param index Index of the import in a set. <code>0</code> is safe if this is a singular import. * @param numDone Number of imports completed in a set. <code>0</code> is safe if this is a * singular import. * @param total Total number of imports in a set. <code>1</code> is safe if this is a singular * import. * @return List of Pixels that have been imported. * @throws FormatException If there is a Bio-Formats image file format error during import. * @throws IOException If there is an I/O error. * @throws ServerError If there is an error communicating with the OMERO server we're importing * into. * @since OMERO Beta 4.2.1. */ public List<Pixels> importImage( final ImportContainer container, int index, int numDone, int total) throws FormatException, IOException, Throwable { HandlePrx handle; for (FileExclusion exclusion : exclusions) { Boolean veto = exclusion.suggestExclusion(store.getServiceFactory(), container); if (Boolean.TRUE.equals(veto)) { notifyObservers( new ImportEvent.FILESET_EXCLUSION( container.getFile().getAbsolutePath(), 0, container.getUsedFiles().length)); return Collections.emptyList(); } } final ImportProcessPrx proc = createImport(container); final String[] srcFiles = container.getUsedFiles(); final List<String> checksums = new ArrayList<String>(); final byte[] buf = new byte[store.getDefaultBlockSize()]; final TimeEstimator estimator = new ProportionalTimeEstimatorImpl(container.getUsedFilesTotalSize()); Map<Integer, String> failingChecksums = new HashMap<Integer, String>(); notifyObservers( new ImportEvent.FILESET_UPLOAD_START(null, index, srcFiles.length, null, null, null)); for (int i = 0; i < srcFiles.length; i++) { checksums.add(uploadFile(proc, srcFiles, i, checksumProviderFactory, estimator, buf)); } try { handle = proc.verifyUpload(checksums); } catch (ChecksumValidationException cve) { failingChecksums = cve.failingChecksums; throw cve; } finally { try { proc.close(); } catch (Exception e) { log.warn("Exception while closing proc", e); } notifyObservers( new ImportEvent.FILESET_UPLOAD_END( null, index, srcFiles.length, null, null, srcFiles, checksums, failingChecksums, null)); } // At this point the import is running, check handle for number of // steps. ImportCallback cb = null; try { cb = createCallback(proc, handle, container); if (minutesToWait == 0) { log.info("Disconnecting from import process..."); cb.close(false); cb = null; handle = null; return Collections.emptyList(); // EARLY EXIT } if (minutesToWait < 0) { while (true) { if (cb.block(5000)) { break; } } } else { cb.loop(minutesToWait * 30, 2000); } final ImportResponse rsp = cb.getImportResponse(); if (rsp == null) { throw new Exception("Import failure"); } return rsp.pixels; } finally { if (cb != null) { cb.close(true); // Allow cb to close handle } else if (handle != null) { handle.close(); } } }