From c06f61b209555bec51b66ee2055d5ae79b30bd66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= <jan@kozusznik.cz> Date: Wed, 7 Nov 2018 09:26:55 +0100 Subject: [PATCH] ISS-1323: improve proper handling of upload/download introduce isUploading status, report cause of upload/download fail --- .../src/main/java/cz/it4i/fiji/haas/Job.java | 20 +++- .../PersistentSynchronizationProcess.java | 25 +++-- .../haas/data_transfer/Synchronization.java | 16 ++- .../haas_java_client/HaaSFileTransferImp.java | 23 ++-- .../core/BenchmarkJobManager.java | 22 ++-- .../core/ObservableBenchmarkJob.java | 21 +++- .../ui/BenchmarkSPIMControl.java | 3 + .../fiji/scpclient/AckowledgementChecker.java | 46 ++++++++ .../cz/it4i/fiji/scpclient/ScpClient.java | 106 ++++++++---------- 9 files changed, 178 insertions(+), 104 deletions(-) create mode 100644 java-scpclient/src/main/java/cz/it4i/fiji/scpclient/AckowledgementChecker.java diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java index b3fd9cbc..db319848 100644 --- a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java @@ -193,6 +193,10 @@ public class Job { return getSafeBoolean(getProperty(JOB_IS_UPLOADED)); } + public boolean isUploading() { + return synchronization.isUploading(); + } + public boolean isDownloaded() { return getSafeBoolean(getProperty(JOB_IS_DOWNLOADED)); } @@ -201,6 +205,10 @@ public class Job { return Boolean.parseBoolean(getProperty(JOB_NEEDS_DOWNLOAD)); } + public boolean isDownloading() { + return synchronization.isDownloading(); + } + public boolean needsUpload() { return Boolean.parseBoolean(getProperty(JOB_NEEDS_UPLOAD)); } @@ -414,6 +422,12 @@ public class Job { return synchronization.getFileTransferInfo(); } + public void createEmptyFile(String fileName) throws InterruptedIOException { + try(HaaSFileTransfer transfer = haasClientSupplier.get().startFileTransfer(getId())) { + transfer.upload(new UploadingFileData(fileName)); + } + } + private void storeInputOutputDirectory() { if (inputDirectory == null) { useDemoData = true; @@ -502,10 +516,4 @@ public class Job { setProperty(JOB_CAN_BE_DOWNLOADED, b); } - public void createEmptyFile(String fileName) throws InterruptedIOException { - try(HaaSFileTransfer transfer = haasClientSupplier.get().startFileTransfer(getId())) { - transfer.upload(new UploadingFileData(fileName)); - } - } - } diff --git a/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/PersistentSynchronizationProcess.java b/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/PersistentSynchronizationProcess.java index 865c4a03..0a4b8eef 100644 --- a/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/PersistentSynchronizationProcess.java +++ b/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/PersistentSynchronizationProcess.java @@ -30,9 +30,10 @@ import cz.it4i.fiji.haas_java_client.TransferFileProgressForHaaSClient; public abstract class PersistentSynchronizationProcess<T> { - private boolean startFinished = true; + + public static final String FAILED_ITEM = "Failed item"; - public static final Logger log = LoggerFactory + private static final Logger log = LoggerFactory .getLogger(cz.it4i.fiji.haas.data_transfer.PersistentSynchronizationProcess.class); private static final TransferFileProgressForHaaSClient DUMMY_FILE_PROGRESS = new TransferFileProgressForHaaSClient( @@ -56,6 +57,8 @@ public abstract class PersistentSynchronizationProcess<T> { private ProgressNotifier notifier; + private boolean startFinished = true; + private final AtomicInteger runningProcessCounter = new AtomicInteger(); private final Collection<P_HolderOfOpenClosables> openedClosables = new LinkedList<>(); @@ -114,6 +117,10 @@ public abstract class PersistentSynchronizationProcess<T> { this.notifier = notifier; } + public synchronized boolean isWorking() { + return !toProcessQueue.isEmpty(); + } + abstract protected Iterable<T> getItems() throws IOException; abstract protected void processItem(HaaSFileTransfer tr, T p) throws InterruptedIOException; @@ -151,15 +158,19 @@ public abstract class PersistentSynchronizationProcess<T> { try { processItem(tr, p); fileTransfered(p); + actualnotifier.itemDone(item); } catch (InterruptedIOException | HaaSClientException e) { - if (e instanceof HaaSClientException) { - log.warn("process ", e); + synchronized (this) { + toProcessQueue.clear(); + interrupted = true; + if (e instanceof HaaSClientException) { + log.warn("process ", e); + actualnotifier.addItem(FAILED_ITEM); + } } - toProcessQueue.clear(); - interrupted = true; } - actualnotifier.itemDone(item); + } while(true); } finally { runningTransferThreads.remove(Thread.currentThread()); diff --git a/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/Synchronization.java b/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/Synchronization.java index e0d7f1db..04b9e2ae 100644 --- a/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/Synchronization.java +++ b/haas-java-client/src/main/java/cz/it4i/fiji/haas/data_transfer/Synchronization.java @@ -32,12 +32,16 @@ import cz.it4i.fiji.haas_java_client.UploadingFileImpl; public class Synchronization implements Closeable { - public static final Logger log = LoggerFactory.getLogger(cz.it4i.fiji.haas.data_transfer.Synchronization.class); - + private final static Logger log = LoggerFactory.getLogger( + cz.it4i.fiji.haas.data_transfer.Synchronization.class); + private static final String FILE_INDEX_TO_UPLOAD_FILENAME = ".toUploadFiles"; + private static final String FILE_INDEX_UPLOADED_FILENAME = ".uploaded"; + private static final String FILE_INDEX_TO_DOWNLOAD_FILENAME = ".toDownloadFiles"; + private static final String FILE_INDEX_DOWNLOADED_FILENAME = ".downloaded"; private final Path workingDirectory; @@ -97,6 +101,10 @@ public class Synchronization implements Closeable { uploadProcess.resume(); } + public boolean isUploading() { + return uploadProcess.isWorking(); + } + public synchronized CompletableFuture<?> startDownload(Collection<String> files) throws IOException { this.downloadProcess.setItems(files); return this.downloadProcess.start(); @@ -110,6 +118,10 @@ public class Synchronization implements Closeable { this.downloadProcess.resume(); } + public boolean isDownloading() { + return downloadProcess.isWorking(); + } + public List<FileTransferInfo> getFileTransferInfo() { final List<FileTransferInfo> list = new LinkedList<>(); filesUploaded.getIndexedItems().forEach(ii -> { diff --git a/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSFileTransferImp.java b/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSFileTransferImp.java index b27c73ec..2695e613 100644 --- a/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSFileTransferImp.java +++ b/haas-java-client/src/main/java/cz/it4i/fiji/haas_java_client/HaaSFileTransferImp.java @@ -43,18 +43,13 @@ class HaaSFileTransferImp implements HaaSFileTransfer { public void upload(final UploadingFile file) throws InterruptedIOException { final String destFile = ft.getSharedBasepath() + "/" + file.getName(); try (InputStream is = file.getInputStream()) { - if (!scpClient.upload(is, destFile, file.getLength(), file.getLastTime(), - progress)) - { - throw new HaaSClientException("Uploading of " + file + " to " + - destFile + " failed"); - } - } - catch (final InterruptedIOException e) { - throw e; + scpClient.upload(is, destFile, file.getLength(), file.getLastTime(), + progress); + } catch (JSchException | IOException e) { - throw new HaaSClientException(e); + throw new HaaSClientException("An upload of " + file + " to " + destFile + + " failed: " + e.getMessage(), e); } } @@ -67,16 +62,14 @@ class HaaSFileTransferImp implements HaaSFileTransfer { final Path rFile = workDirectory.resolve(fileName); final String fileToDownload = "'" + ft.getSharedBasepath() + "/" + fileName + "'"; - if (!scpClient.download(fileToDownload, rFile, progress)) { - throw new HaaSClientException("Downloading of " + fileName + " to " + - workDirectory + " failed"); - } + scpClient.download(fileToDownload, rFile, progress); } catch (final InterruptedIOException e) { throw e; } catch (JSchException | IOException e) { - throw new HaaSClientException(e); + throw new HaaSClientException("A download of " + fileName + " to " + + workDirectory + " failed: " + e.getMessage()); } } diff --git a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java index 3026d22a..4e5e3058 100644 --- a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java +++ b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java @@ -58,7 +58,9 @@ import org.xml.sax.SAXException; import cz.it4i.fiji.commons.WebRoutines; import cz.it4i.fiji.haas.Job; import cz.it4i.fiji.haas.JobManager; +import cz.it4i.fiji.haas.data_transfer.PersistentSynchronizationProcess; import cz.it4i.fiji.haas_java_client.FileTransferInfo; +import cz.it4i.fiji.haas_java_client.HaaSClientException; import cz.it4i.fiji.haas_java_client.HaaSClientSettings; import cz.it4i.fiji.haas_java_client.JobSettings; import cz.it4i.fiji.haas_java_client.JobSettingsBuilder; @@ -205,8 +207,8 @@ public class BenchmarkJobManager implements Closeable { job.stopUploadData(); } - public boolean needsUpload() { - return job.needsUpload(); + public boolean isUploading() { + return job.isUploading(); } public void setUploadNotifier(Progress progress) { @@ -237,10 +239,6 @@ public class BenchmarkJobManager implements Closeable { job.stopDownloadData(); } - public boolean needsDownload() { - return downloadingStatus.needsDownload(); - } - public void setDownloadNotifier(Progress progress) { job.setDownloadNotifier(downloadNotifier = createDownloadNotifierProcessingResultCSV(convertToProgressNotifier( @@ -259,6 +257,10 @@ public class BenchmarkJobManager implements Closeable { return downloadingStatus.isDownloaded(); } + public boolean isDownloading() { + return job.isDownloading(); + } + public void resumeTransfer() { job.resumeDownload(); job.resumeUpload(); @@ -427,14 +429,16 @@ public class BenchmarkJobManager implements Closeable { }).whenComplete((X, e) -> { if (e != null) { log.error(e.getMessage(), e); + downloadNotifier.addItem( + PersistentSynchronizationProcess.FAILED_ITEM); } result.complete(null); }); } - private Set<String> extractNames(Path resolve) { + private Set<String> extractNames(Path pathToXML) { Set<String> result = new HashSet<>(); - try (InputStream fileIS = Files.newInputStream(resolve)) { + try (InputStream fileIS = Files.newInputStream(pathToXML)) { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document xmlDocument = builder.parse(fileIS); @@ -448,7 +452,7 @@ public class BenchmarkJobManager implements Closeable { result.add(nl.item(i).getTextContent()); } } catch (IOException | ParserConfigurationException | SAXException | XPathExpressionException e) { - log.error(e.getMessage(), e); + throw new HaaSClientException("Extract names from " + pathToXML, e); } return result; } diff --git a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ObservableBenchmarkJob.java b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ObservableBenchmarkJob.java index 82f7426a..4918d7fd 100644 --- a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ObservableBenchmarkJob.java +++ b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ObservableBenchmarkJob.java @@ -2,6 +2,7 @@ package cz.it4i.fiji.haas_spim_benchmark.core; import java.io.Closeable; +import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; import java.util.function.Function; @@ -12,6 +13,7 @@ import net.imagej.updater.util.Progress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import cz.it4i.fiji.haas.data_transfer.PersistentSynchronizationProcess; import cz.it4i.fiji.haas.ui.UpdatableObservableValue; import cz.it4i.fiji.haas_java_client.FileTransferInfo; import cz.it4i.fiji.haas_java_client.SynchronizableFileType; @@ -26,10 +28,10 @@ public class ObservableBenchmarkJob extends private final P_TransferProgress downloadProgress = new P_TransferProgress( val -> getValue().setDownloaded(val), () -> getValue().isDownloaded(), - () -> getValue().needsDownload()); + () -> getValue().isDownloading()); private final P_TransferProgress uploadProgress = new P_TransferProgress( val -> getValue().setUploaded(val), () -> getValue().isUploaded(), - () -> getValue().needsUpload()); + () -> getValue().isUploading()); private final Executor executor; private final HaasOutputObservableValueRegistry haasOutputRegistry; @@ -45,6 +47,8 @@ public class ObservableBenchmarkJob extends public boolean isDone(); public boolean isWorking(); + + public boolean isFailed(); public Float getRemainingPercents(); } @@ -115,6 +119,7 @@ public class ObservableBenchmarkJob extends private Long start; private Long remainingMiliseconds; private Float remainingPercents; + private boolean failed = false; public P_TransferProgress(Consumer<Boolean> doneStatusConsumer, Supplier<Boolean> doneStatusSupplier, Supplier<Boolean> workingSupplier) @@ -140,7 +145,11 @@ public class ObservableBenchmarkJob extends @Override public synchronized void addItem(Object item) { - if (start == null) { + if (Objects.equals(item, PersistentSynchronizationProcess.FAILED_ITEM)) { + failed = true; + doneStatusConsumer.accept(false); + fireValueChangedEvent(); + } else if (start == null) { setDone(false); clearProgress(); start = System.currentTimeMillis(); @@ -160,6 +169,11 @@ public class ObservableBenchmarkJob extends public synchronized boolean isWorking() { return workingSupplier.get(); } + + @Override + public boolean isFailed() { + return failed ; + } @Override public synchronized Long getRemainingMiliseconds() { @@ -193,6 +207,7 @@ public class ObservableBenchmarkJob extends } private void setDone(boolean val) { + failed = false; doneStatusConsumer.accept(val); } } diff --git a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/ui/BenchmarkSPIMControl.java b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/ui/BenchmarkSPIMControl.java index a691722a..b94cdf5d 100644 --- a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/ui/BenchmarkSPIMControl.java +++ b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/ui/BenchmarkSPIMControl.java @@ -368,6 +368,9 @@ public class BenchmarkSPIMControl extends BorderPane implements } private String decorateTransfer(TransferProgress progress) { + if (progress.isFailed()) { + return "Failed"; + } if (!progress.isWorking() && !progress.isDone()) { return ""; } diff --git a/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/AckowledgementChecker.java b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/AckowledgementChecker.java new file mode 100644 index 00000000..130f800b --- /dev/null +++ b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/AckowledgementChecker.java @@ -0,0 +1,46 @@ +package cz.it4i.fiji.scpclient; + +import java.io.IOException; +import java.io.InputStream; + +public class AckowledgementChecker { + + private int lastStatus; + + private StringBuilder lastMessage; + + public boolean checkAck(InputStream in) throws IOException { + lastMessage = new StringBuilder(); + return checkAck(in, lastMessage); + } + + + public String getLastMessage() { + return lastMessage.toString(); + } + + + public int getLastStatus() { + return lastStatus; + } + + private boolean checkAck(InputStream in, StringBuilder sb) throws IOException { + lastStatus = in.read(); + // b may be 0 for success, + // 1 for error, + // 2 for fatal error, + // -1 + if (lastStatus == 0) return true; + if (lastStatus == -1) return false; + + if (lastStatus == 1 || lastStatus == 2) { + int c; + do { + c = in.read(); + sb.append((char) c); + } + while (c != '\n'); + } + return lastStatus == 0; + } +} diff --git a/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java index 82026467..9290ea26 100644 --- a/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java +++ b/java-scpclient/src/main/java/cz/it4i/fiji/scpclient/ScpClient.java @@ -34,11 +34,17 @@ import cz.it4i.fiji.commons.DoActionEventualy; public class ScpClient implements Closeable { - private static final String NO_SUCH_FILE_OR_DIRECTORY_ERROR_TEXT = "No such file or directory"; + private static final String NO_SUCH_FILE_OR_DIRECTORY_ERROR_TEXT = + "No such file or directory"; public static final Logger log = LoggerFactory.getLogger( cz.it4i.fiji.scpclient.ScpClient.class); + private static String constructExceptionText(AckowledgementChecker ack) { + return "Check acknowledgement failed with status: " + ack.getLastStatus() + + " and message: " + ack.getLastMessage(); + } + private static final int MAX_NUMBER_OF_CONNECTION_ATTEMPTS = 5; private static final long TIMEOUT_BETWEEN_CONNECTION_ATTEMPTS = 500; @@ -98,20 +104,21 @@ public class ScpClient implements Closeable { download(lfile, rFile, dummyProgress); } - public boolean download(String lfile, Path rfile, + public void download(String lfile, Path rfile, TransferFileProgress progress) throws JSchException, IOException { if (!Files.exists(rfile.getParent())) { Files.createDirectories(rfile.getParent()); } try (OutputStream os = Files.newOutputStream(rfile)) { - return download(lfile, os, progress); + download(lfile, os, progress); } } - public boolean download(String lfile, OutputStream os, + public void download(String lfile, OutputStream os, TransferFileProgress progress) throws JSchException, IOException { + AckowledgementChecker ack = new AckowledgementChecker(); // exec 'scp -f rfile' remotely String command = "scp -f " + lfile; Channel channel = getConnectedSession().openChannel("exec"); @@ -134,8 +141,8 @@ public class ScpClient implements Closeable { out.flush(); while (true) { - int c = checkAck(in); - if (c != 'C') { + ack.checkAck(in); + if (ack.getLastStatus() != 'C') { break; } @@ -186,8 +193,8 @@ public class ScpClient implements Closeable { if (filesize == 0L) break; } - if (checkAck(in) != 0) { - return false; + if (!ack.checkAck(in)) { + throw new JSchException(constructExceptionText(ack)); } // send '\0' @@ -205,36 +212,35 @@ public class ScpClient implements Closeable { finally { channel.disconnect(); } - return true; } - public boolean upload(Path file, String rfile) throws JSchException, + public void upload(Path file, String rfile) throws JSchException, IOException { - return upload(file, rfile, dummyProgress); + upload(file, rfile, dummyProgress); } - public boolean upload(Path file, String rfile, TransferFileProgress progress) + public void upload(Path file, String rfile, TransferFileProgress progress) throws JSchException, IOException { try (InputStream is = Files.newInputStream(file)) { - return upload(is, rfile, file.toFile().length(), file.toFile() + upload(is, rfile, file.toFile().length(), file.toFile() .lastModified(), progress); } } - public boolean upload(InputStream is, String fileName, long length, + public void upload(InputStream is, String fileName, long length, long lastModified, TransferFileProgress progress) throws JSchException, IOException { int noSuchFileExceptionThrown = 0; do { - try { - return scp2Server(is, fileName, length, lastModified, progress); + scp2Server(is, fileName, length, lastModified, progress); + break; } catch (NoSuchFileException e) { - if(noSuchFileExceptionThrown > MAX_NUMBER_OF_CONNECTION_ATTEMPTS) { - break; + if (noSuchFileExceptionThrown > MAX_NUMBER_OF_CONNECTION_ATTEMPTS) { + throw new JSchException(e.getReason()); } if (noSuchFileExceptionThrown > 0) { try { @@ -248,10 +254,10 @@ public class ScpClient implements Closeable { continue; } } while(true); - return false; } public long size(String lfile) throws JSchException, IOException { + AckowledgementChecker ack = new AckowledgementChecker(); // exec 'scp -f rfile' remotely String command = "scp -f " + lfile; Channel channel = getConnectedSession().openChannel("exec"); @@ -274,8 +280,8 @@ public class ScpClient implements Closeable { out.flush(); while (true) { - int c = checkAck(in); - if (c != 'C') { + ack.checkAck(in); + if (ack.getLastStatus() != 'C') { break; } @@ -391,10 +397,11 @@ public class ScpClient implements Closeable { return session; } - private boolean scp2Server(InputStream is, String fileName, long length, + private void scp2Server(InputStream is, String fileName, long length, long lastModified, TransferFileProgress progress) throws JSchException, IOException, InterruptedIOException { + AckowledgementChecker ack = new AckowledgementChecker(); boolean ptimestamp = true; // exec 'scp -t rfile' remotely String command = "scp " + (ptimestamp ? "-p" : "") + " -t '" + fileName + "'"; @@ -405,8 +412,8 @@ public class ScpClient implements Closeable { InputStream in = channel.getInputStream()) { channel.connect(); - if (checkAck(in) != 0) { - return false; + if (!ack.checkAck(in)) { + throw new JSchException(constructExceptionText(ack)); } if (ptimestamp) { @@ -416,8 +423,8 @@ public class ScpClient implements Closeable { command += (" " + (lastModified / 1000) + " 0\n"); out.write(command.getBytes()); out.flush(); - if (checkAck(in) != 0) { - return false; + if (!ack.checkAck(in)) { + throw new JSchException(constructExceptionText(ack)); } } @@ -428,13 +435,14 @@ public class ScpClient implements Closeable { command += "\n"; out.write(command.getBytes()); out.flush(); - StringBuilder sb = new StringBuilder(); - int result; - if ((result = checkAck(in, sb)) != 0) { - if (result == 1 && sb.toString().contains(NO_SUCH_FILE_OR_DIRECTORY_ERROR_TEXT) ) { - throw new NoSuchFileException(getParent(fileName)); + if (!ack.checkAck(in)) { + if (ack.getLastStatus() == 1 && ack.getLastMessage().contains( + NO_SUCH_FILE_OR_DIRECTORY_ERROR_TEXT)) + { + throw new NoSuchFileException(getParent(fileName), null, + constructExceptionText(ack)); } - return false; + throw new JSchException(constructExceptionText(ack)); } byte[] buf = new byte[getBufferSize()]; // send a content of lfile @@ -448,8 +456,8 @@ public class ScpClient implements Closeable { buf[0] = 0; out.write(buf, 0, 1); out.flush(); - if (checkAck(in) != 0) { - return false; + if (!ack.checkAck(in)) { + throw new JSchException(constructExceptionText(ack)); } out.close(); @@ -461,7 +469,6 @@ public class ScpClient implements Closeable { finally { channel.disconnect(); } - return true; } private int mkdir(String file) throws JSchException { @@ -515,31 +522,6 @@ public class ScpClient implements Closeable { } - static int checkAck(InputStream in) throws IOException { - StringBuilder sb = new StringBuilder(); - int result = checkAck(in, sb); - if (result != 0) { - log.warn(sb.toString()); - } - return result; - } - static int checkAck(InputStream in, StringBuilder sb) throws IOException { - int b = in.read(); - // b may be 0 for success, - // 1 for error, - // 2 for fatal error, - // -1 - if (b == 0) return b; - if (b == -1) return b; - - if (b == 1 || b == 2) { - int c; - do { - c = in.read(); - sb.append((char) c); - } - while (c != '\n'); - } - return b; - } + + } -- GitLab