Search in sources :

Example 1 with OutputStreamSelector

use of com.cloudbees.jenkins.support.util.OutputStreamSelector in project support-core-plugin by jenkinsci.

the class SupportPlugin method writeBundle.

/**
 * Generate a bundle for all components that are selected in the Global Configuration.
 *
 * @param outputStream an {@link OutputStream}
 * @param components a list of {@link Component} to include in the bundle
 * @param componentConsumer a {@link ComponentVisitor}
 * @throws IOException if an error occurs while generating the bundle.
 */
public static void writeBundle(OutputStream outputStream, final List<? extends Component> components, ComponentVisitor componentConsumer) throws IOException {
    StringBuilder manifest = new StringBuilder();
    StringWriter errors = new StringWriter();
    PrintWriter errorWriter = new PrintWriter(errors);
    try {
        try (BulkChange change = new BulkChange(ContentMappings.get());
            ZipArchiveOutputStream binaryOut = new ZipArchiveOutputStream(new BufferedOutputStream(outputStream, 16384))) {
            // Get the filter to be used
            Optional<ContentFilter> maybeFilter = getContentFilter();
            // Recalculate the mappings and stop words and save it to disk
            if (maybeFilter.isPresent()) {
                reloadAndSaveMappings(maybeFilter.get());
            }
            // Generate the content of the manifest.md going trough all the components which will be included. It
            // also returns the contents to include. We pass maybeFilter to filter the names written in the manifest
            appendManifestHeader(manifest);
            List<Content> contents = appendManifestContents(manifest, errorWriter, components, componentConsumer, maybeFilter);
            contents.add(new UnfilteredStringContent("manifest.md", manifest.toString()));
            Optional<FilteredOutputStream> maybeFilteredOut = maybeFilter.map(filter -> new FilteredOutputStream(binaryOut, filter));
            OutputStream textOut = maybeFilteredOut.map(OutputStream.class::cast).orElse(binaryOut);
            OutputStreamSelector selector = new OutputStreamSelector(() -> binaryOut, () -> textOut);
            IgnoreCloseOutputStream unfilteredOut = new IgnoreCloseOutputStream(binaryOut);
            IgnoreCloseOutputStream filteredOut = new IgnoreCloseOutputStream(selector);
            boolean entryCreated = false;
            for (Content content : contents) {
                if (content == null) {
                    continue;
                }
                final String name = getNameFiltered(maybeFilter, content.getName(), content.getFilterableParameters());
                try {
                    final ZipArchiveEntry entry = new ZipArchiveEntry(name);
                    entry.setTime(content.getTime());
                    binaryOut.putArchiveEntry(entry);
                    entryCreated = true;
                    binaryOut.flush();
                    OutputStream out = content.shouldBeFiltered() ? filteredOut : unfilteredOut;
                    if (content instanceof PrefilteredContent && maybeFilter.isPresent()) {
                        ((PrefilteredContent) content).writeTo(out, maybeFilter.get());
                    } else {
                        content.writeTo(out);
                    }
                    out.flush();
                } catch (Throwable e) {
                    String msg = "Could not attach ''" + name + "'' to support bundle";
                    logger.log(e instanceof ChannelClosedException ? Level.FINE : Level.WARNING, msg, e);
                    errorWriter.println(msg);
                    errorWriter.println("-----------------------------------------------------------------------");
                    errorWriter.println();
                    Functions.printStackTrace(e, errorWriter);
                    errorWriter.println();
                } finally {
                    maybeFilteredOut.ifPresent(FilteredOutputStream::reset);
                    selector.reset();
                    if (entryCreated) {
                        binaryOut.closeArchiveEntry();
                        entryCreated = false;
                    }
                }
            }
            errorWriter.close();
            String errorContent = errors.toString();
            if (StringUtils.isNotBlank(errorContent)) {
                try {
                    binaryOut.putArchiveEntry(new ZipArchiveEntry("manifest/errors.txt"));
                    entryCreated = true;
                    textOut.write(errorContent.getBytes(StandardCharsets.UTF_8));
                    textOut.flush();
                } catch (IOException e) {
                    logger.log(Level.WARNING, "Could not write manifest/errors.txt to zip archive", e);
                } finally {
                    if (entryCreated) {
                        binaryOut.closeArchiveEntry();
                    }
                }
            }
            binaryOut.flush();
            change.commit();
        }
    } finally {
        outputStream.flush();
    }
}
Also used : FilteredOutputStream(com.cloudbees.jenkins.support.filter.FilteredOutputStream) OutputStreamSelector(com.cloudbees.jenkins.support.util.OutputStreamSelector) IgnoreCloseOutputStream(com.cloudbees.jenkins.support.util.IgnoreCloseOutputStream) FilteredOutputStream(com.cloudbees.jenkins.support.filter.FilteredOutputStream) IgnoreCloseOutputStream(com.cloudbees.jenkins.support.util.IgnoreCloseOutputStream) BufferedOutputStream(java.io.BufferedOutputStream) ZipArchiveOutputStream(org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) BulkChange(hudson.BulkChange) ZipArchiveOutputStream(org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream) IOException(java.io.IOException) ContentFilter(com.cloudbees.jenkins.support.filter.ContentFilter) ChannelClosedException(hudson.remoting.ChannelClosedException) UnfilteredStringContent(com.cloudbees.jenkins.support.api.UnfilteredStringContent) StringWriter(java.io.StringWriter) PrefilteredContent(com.cloudbees.jenkins.support.filter.PrefilteredContent) UnfilteredStringContent(com.cloudbees.jenkins.support.api.UnfilteredStringContent) Content(com.cloudbees.jenkins.support.api.Content) ZipArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry) PrefilteredContent(com.cloudbees.jenkins.support.filter.PrefilteredContent) BufferedOutputStream(java.io.BufferedOutputStream) PrintWriter(java.io.PrintWriter)

Aggregations

Content (com.cloudbees.jenkins.support.api.Content)1 UnfilteredStringContent (com.cloudbees.jenkins.support.api.UnfilteredStringContent)1 ContentFilter (com.cloudbees.jenkins.support.filter.ContentFilter)1 FilteredOutputStream (com.cloudbees.jenkins.support.filter.FilteredOutputStream)1 PrefilteredContent (com.cloudbees.jenkins.support.filter.PrefilteredContent)1 IgnoreCloseOutputStream (com.cloudbees.jenkins.support.util.IgnoreCloseOutputStream)1 OutputStreamSelector (com.cloudbees.jenkins.support.util.OutputStreamSelector)1 BulkChange (hudson.BulkChange)1 ChannelClosedException (hudson.remoting.ChannelClosedException)1 BufferedOutputStream (java.io.BufferedOutputStream)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 ZipArchiveEntry (org.apache.commons.compress.archivers.zip.ZipArchiveEntry)1 ZipArchiveOutputStream (org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream)1