Example usage for java.nio.channels ReadableByteChannel close

List of usage examples for java.nio.channels ReadableByteChannel close

Introduction

In this page you can find the example usage for java.nio.channels ReadableByteChannel close.

Prototype

public void close() throws IOException;

Source Link

Document

Closes this channel.

Usage

From source file:gobblin.data.management.copy.writer.TarArchiveInputStreamDataWriter.java

/**
 * Untars the passed in {@link FileAwareInputStream} to the task's staging directory. Uses the name of the root
 * {@link TarArchiveEntry} in the stream as the directory name for the untarred file. The method also commits the data
 * by moving the file from staging to output directory.
 *
 * @see gobblin.data.management.copy.writer.FileAwareInputStreamDataWriter#write(gobblin.data.management.copy.FileAwareInputStream)
 *//* w ww .j  a  v  a2s.  c  o  m*/
@Override
public void writeImpl(InputStream inputStream, Path writeAt, CopyableFile copyableFile) throws IOException {
    this.closer.register(inputStream);

    TarArchiveInputStream tarIn = new TarArchiveInputStream(inputStream);
    final ReadableByteChannel inputChannel = Channels.newChannel(tarIn);
    TarArchiveEntry tarEntry;

    // flush the first entry in the tar, which is just the root directory
    tarEntry = tarIn.getNextTarEntry();
    String tarEntryRootName = StringUtils.remove(tarEntry.getName(), Path.SEPARATOR);

    log.info("Unarchiving at " + writeAt);

    try {
        while ((tarEntry = tarIn.getNextTarEntry()) != null) {

            // the API tarEntry.getName() is misleading, it is actually the path of the tarEntry in the tar file
            String newTarEntryPath = tarEntry.getName().replace(tarEntryRootName, writeAt.getName());
            Path tarEntryStagingPath = new Path(writeAt.getParent(), newTarEntryPath);

            if (tarEntry.isDirectory() && !this.fs.exists(tarEntryStagingPath)) {
                this.fs.mkdirs(tarEntryStagingPath);
            } else if (!tarEntry.isDirectory()) {
                FSDataOutputStream out = this.fs.create(tarEntryStagingPath, true);
                final WritableByteChannel outputChannel = Channels.newChannel(out);
                try {
                    StreamCopier copier = new StreamCopier(inputChannel, outputChannel);
                    if (isInstrumentationEnabled()) {
                        copier.withCopySpeedMeter(this.copySpeedMeter);
                    }
                    this.bytesWritten.addAndGet(copier.copy());
                    if (isInstrumentationEnabled()) {
                        log.info("File {}: copied {} bytes, average rate: {} B/s",
                                copyableFile.getOrigin().getPath(), this.copySpeedMeter.getCount(),
                                this.copySpeedMeter.getMeanRate());
                    } else {
                        log.info("File {} copied.", copyableFile.getOrigin().getPath());
                    }
                } finally {
                    out.close();
                    outputChannel.close();
                }
            }
        }
    } finally {
        tarIn.close();
        inputChannel.close();
        inputStream.close();
    }
}

From source file:org.apache.gobblin.data.management.copy.writer.TarArchiveInputStreamDataWriter.java

/**
 * Untars the passed in {@link FileAwareInputStream} to the task's staging directory. Uses the name of the root
 * {@link TarArchiveEntry} in the stream as the directory name for the untarred file. The method also commits the data
 * by moving the file from staging to output directory.
 *
 * @see org.apache.gobblin.data.management.copy.writer.FileAwareInputStreamDataWriter#write(org.apache.gobblin.data.management.copy.FileAwareInputStream)
 *//*from w  w  w .  j  a  v  a2s  .  c  o  m*/
@Override
public void writeImpl(InputStream inputStream, Path writeAt, CopyableFile copyableFile) throws IOException {
    this.closer.register(inputStream);

    TarArchiveInputStream tarIn = new TarArchiveInputStream(inputStream);
    final ReadableByteChannel inputChannel = Channels.newChannel(tarIn);
    TarArchiveEntry tarEntry;

    // flush the first entry in the tar, which is just the root directory
    tarEntry = tarIn.getNextTarEntry();
    String tarEntryRootName = StringUtils.remove(tarEntry.getName(), Path.SEPARATOR);

    log.info("Unarchiving at " + writeAt);

    try {
        while ((tarEntry = tarIn.getNextTarEntry()) != null) {

            // the API tarEntry.getName() is misleading, it is actually the path of the tarEntry in the tar file
            String newTarEntryPath = tarEntry.getName().replace(tarEntryRootName, writeAt.getName());
            Path tarEntryStagingPath = new Path(writeAt.getParent(), newTarEntryPath);
            if (!FileUtils.isSubPath(writeAt.getParent(), tarEntryStagingPath)) {
                throw new IOException(
                        String.format("Extracted file: %s is trying to write outside of output directory: %s",
                                tarEntryStagingPath, writeAt.getParent()));
            }

            if (tarEntry.isDirectory() && !this.fs.exists(tarEntryStagingPath)) {
                this.fs.mkdirs(tarEntryStagingPath);
            } else if (!tarEntry.isDirectory()) {
                FSDataOutputStream out = this.fs.create(tarEntryStagingPath, true);
                final WritableByteChannel outputChannel = Channels.newChannel(out);
                try {
                    StreamCopier copier = new StreamCopier(inputChannel, outputChannel);
                    if (isInstrumentationEnabled()) {
                        copier.withCopySpeedMeter(this.copySpeedMeter);
                    }
                    this.bytesWritten.addAndGet(copier.copy());
                    if (isInstrumentationEnabled()) {
                        log.info("File {}: copied {} bytes, average rate: {} B/s",
                                copyableFile.getOrigin().getPath(), this.copySpeedMeter.getCount(),
                                this.copySpeedMeter.getMeanRate());
                    } else {
                        log.info("File {} copied.", copyableFile.getOrigin().getPath());
                    }
                } finally {
                    out.close();
                    outputChannel.close();
                }
            }
        }
    } finally {
        tarIn.close();
        inputChannel.close();
        inputStream.close();
    }
}

From source file:org.cytoscape.app.internal.net.WebQuerier.java

/**
 * Given the unique app name used by the app store, query the app store for the 
 * download URL and download the app to the given directory.
 * //  ww w .j  a  v a2 s .  c o  m
 * If a file with the same name exists in the directory, it is overwritten.
 * 
 * @param appName The unique app name used by the app store
 * @param version The desired version, or <code>null</code> to obtain the latest release
 * @param directory The directory used to store the downloaded file
 * @param taskMonitor 
 */
public File downloadApp(WebApp webApp, String version, File directory, DownloadStatus status)
        throws AppDownloadException {

    List<WebApp.Release> compatibleReleases = getCompatibleReleases(webApp);

    if (compatibleReleases.size() > 0) {
        WebApp.Release releaseToDownload = null;

        if (version != null) {
            for (WebApp.Release compatibleRelease : compatibleReleases) {

                // Check if the desired version is found in the list of available versions
                if (compatibleRelease.getReleaseVersion()
                        .matches("(^\\s*|.*,)\\s*" + version + "\\s*(\\s*$|,.*)")) {
                    releaseToDownload = compatibleRelease;
                }
            }

            if (releaseToDownload == null) {
                throw new AppDownloadException("No release with the requested version " + version
                        + " was found for the requested app " + webApp.getFullName());
            }
        } else {
            releaseToDownload = compatibleReleases.get(compatibleReleases.size() - 1);
        }

        URL downloadUrl = null;
        try {
            downloadUrl = new URL(currentAppStoreUrl + releaseToDownload.getRelativeUrl());
        } catch (MalformedURLException e) {
            throw new AppDownloadException("Unable to obtain URL for version " + version
                    + " of the release for " + webApp.getFullName());
        }

        if (downloadUrl != null) {
            try {

                // Prepare to download
                URLConnection connection = streamUtil.getURLConnection(downloadUrl);
                InputStream inputStream = connection.getInputStream();
                long contentLength = connection.getContentLength();
                ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);

                File outputFile;
                try {
                    // Replace spaces with underscores
                    String outputFileBasename = webApp.getName().replaceAll("\\s", "_");

                    // Append version information
                    outputFileBasename += "-v" + releaseToDownload.getReleaseVersion();

                    // Strip disallowed characters
                    outputFileBasename = OUTPUT_FILENAME_DISALLOWED_CHARACTERS.matcher(outputFileBasename)
                            .replaceAll("");

                    // Append extension
                    outputFileBasename += ".jar";

                    // Output file has same name as app, but spaces and slashes are replaced with hyphens
                    outputFile = new File(directory.getCanonicalPath() + File.separator + outputFileBasename);

                    if (outputFile.exists()) {
                        outputFile.delete();
                    }

                    outputFile.createNewFile();

                    FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
                    try {
                        FileChannel fileChannel = fileOutputStream.getChannel();

                        long currentDownloadPosition = 0;
                        long bytesTransferred;

                        TaskMonitor taskMonitor = status.getTaskMonitor();
                        do {
                            bytesTransferred = fileChannel.transferFrom(readableByteChannel,
                                    currentDownloadPosition, 1 << 14);
                            if (status.isCanceled()) {
                                outputFile.delete();
                                return null;
                            }
                            currentDownloadPosition += bytesTransferred;
                            if (contentLength > 0) {
                                double progress = (double) currentDownloadPosition / contentLength;
                                taskMonitor.setProgress(progress);
                            }
                        } while (bytesTransferred > 0);
                    } finally {
                        fileOutputStream.close();
                    }
                } finally {
                    readableByteChannel.close();
                }
                return outputFile;
            } catch (IOException e) {
                throw new AppDownloadException(
                        "Error while downloading app " + webApp.getFullName() + ", " + e.getMessage());
            }
        }
    } else {
        throw new AppDownloadException(
                "No available releases were found for the app " + webApp.getFullName() + ".");
    }
    return null;
}

From source file:org.apache.nifi.remote.util.SiteToSiteRestApiClient.java

public void openConnectionForSend(final String transactionUrl, final Peer peer) throws IOException {

    final CommunicationsSession commSession = peer.getCommunicationsSession();
    final String flowFilesPath = transactionUrl + "/flow-files";
    final HttpPost post = createPost(flowFilesPath);
    // Set uri so that it'll be used as transit uri.
    ((HttpCommunicationsSession) peer.getCommunicationsSession()).setDataTransferUrl(post.getURI().toString());

    post.setHeader("Content-Type", "application/octet-stream");
    post.setHeader("Accept", "text/plain");
    post.setHeader(HttpHeaders.PROTOCOL_VERSION,
            String.valueOf(transportProtocolVersionNegotiator.getVersion()));

    setHandshakeProperties(post);//from   w ww  . j  av a  2 s  .  c  o  m

    final CountDownLatch initConnectionLatch = new CountDownLatch(1);

    final URI requestUri = post.getURI();
    final PipedOutputStream outputStream = new PipedOutputStream();
    final PipedInputStream inputStream = new PipedInputStream(outputStream,
            DATA_PACKET_CHANNEL_READ_BUFFER_SIZE);
    final ReadableByteChannel dataPacketChannel = Channels.newChannel(inputStream);
    final HttpAsyncRequestProducer asyncRequestProducer = new HttpAsyncRequestProducer() {

        private final ByteBuffer buffer = ByteBuffer.allocate(DATA_PACKET_CHANNEL_READ_BUFFER_SIZE);

        private int totalRead = 0;
        private int totalProduced = 0;

        private boolean requestHasBeenReset = false;

        @Override
        public HttpHost getTarget() {
            return URIUtils.extractHost(requestUri);
        }

        @Override
        public HttpRequest generateRequest() throws IOException, HttpException {

            // Pass the output stream so that Site-to-Site client thread can send
            // data packet through this connection.
            logger.debug("sending data to {} has started...", flowFilesPath);
            ((HttpOutput) commSession.getOutput()).setOutputStream(outputStream);
            initConnectionLatch.countDown();

            final BasicHttpEntity entity = new BasicHttpEntity();
            entity.setChunked(true);
            entity.setContentType("application/octet-stream");
            post.setEntity(entity);
            return post;
        }

        private final AtomicBoolean bufferHasRemainingData = new AtomicBoolean(false);

        /**
         * If the proxy server requires authentication, the same POST request has to be sent again.
         * The first request will result 407, then the next one will be sent with auth headers and actual data.
         * This method produces a content only when it's need to be sent, to avoid producing the flow-file contents twice.
         * Whether we need to wait auth is determined heuristically by the previous POST request which creates transaction.
         * See {@link SiteToSiteRestApiClient#initiateTransactionForSend(HttpPost)} for further detail.
         */
        @Override
        public void produceContent(final ContentEncoder encoder, final IOControl ioControl) throws IOException {

            if (shouldCheckProxyAuth() && proxyAuthRequiresResend.get() && !requestHasBeenReset) {
                logger.debug("Need authentication with proxy server. Postpone producing content.");
                encoder.complete();
                return;
            }

            if (bufferHasRemainingData.get()) {
                // If there's remaining buffer last time, send it first.
                writeBuffer(encoder);
                if (bufferHasRemainingData.get()) {
                    return;
                }
            }

            int read;
            // This read() blocks until data becomes available,
            // or corresponding outputStream is closed.
            if ((read = dataPacketChannel.read(buffer)) > -1) {

                logger.trace("Read {} bytes from dataPacketChannel. {}", read, flowFilesPath);
                totalRead += read;

                buffer.flip();
                writeBuffer(encoder);

            } else {

                final long totalWritten = commSession.getOutput().getBytesWritten();
                logger.debug(
                        "sending data to {} has reached to its end. produced {} bytes by reading {} bytes from channel. {} bytes written in this transaction.",
                        flowFilesPath, totalProduced, totalRead, totalWritten);

                if (totalRead != totalWritten || totalProduced != totalWritten) {
                    final String msg = "Sending data to %s has reached to its end, but produced : read : wrote byte sizes (%d : %d : %d) were not equal. Something went wrong.";
                    throw new RuntimeException(
                            String.format(msg, flowFilesPath, totalProduced, totalRead, totalWritten));
                }
                transferDataLatch.countDown();
                encoder.complete();
                dataPacketChannel.close();
            }

        }

        private void writeBuffer(ContentEncoder encoder) throws IOException {
            while (buffer.hasRemaining()) {
                final int written = encoder.write(buffer);
                logger.trace("written {} bytes to encoder.", written);
                if (written == 0) {
                    logger.trace("Buffer still has remaining. {}", buffer);
                    bufferHasRemainingData.set(true);
                    return;
                }
                totalProduced += written;
            }
            bufferHasRemainingData.set(false);
            buffer.clear();
        }

        @Override
        public void requestCompleted(final HttpContext context) {
            logger.debug("Sending data to {} completed.", flowFilesPath);
            debugProxyAuthState(context);
        }

        @Override
        public void failed(final Exception ex) {
            final String msg = String.format("Failed to send data to %s due to %s", flowFilesPath,
                    ex.toString());
            logger.error(msg, ex);
            eventReporter.reportEvent(Severity.WARNING, EVENT_CATEGORY, msg);
        }

        @Override
        public boolean isRepeatable() {
            // In order to pass authentication, request has to be repeatable.
            return true;
        }

        @Override
        public void resetRequest() throws IOException {
            logger.debug("Sending data request to {} has been reset...", flowFilesPath);
            requestHasBeenReset = true;
        }

        @Override
        public void close() throws IOException {
            logger.debug("Closing sending data request to {}", flowFilesPath);
            closeSilently(outputStream);
            closeSilently(dataPacketChannel);
            stopExtendingTtl();
        }
    };

    postResult = getHttpAsyncClient().execute(asyncRequestProducer, new BasicAsyncResponseConsumer(), null);

    try {
        // Need to wait the post request actually started so that we can write to its output stream.
        if (!initConnectionLatch.await(connectTimeoutMillis, TimeUnit.MILLISECONDS)) {
            throw new IOException("Awaiting initConnectionLatch has been timeout.");
        }

        // Started.
        transferDataLatch = new CountDownLatch(1);
        startExtendingTtl(transactionUrl, dataPacketChannel, null);

    } catch (final InterruptedException e) {
        throw new IOException("Awaiting initConnectionLatch has been interrupted.", e);
    }

}

From source file:com.sonicle.webtop.mail.Service.java

private void fastStreamCopy(final InputStream src, final OutputStream dest) throws IOException {
    final ReadableByteChannel in = Channels.newChannel(src);
    final WritableByteChannel out = Channels.newChannel(dest);
    fastChannelCopy(in, out);/*w  w w  .j ava2 s.  c o  m*/
    in.close();
    out.close();
}