All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.genie.web.services.impl.LocalFileSystemAttachmentServiceImpl Maven / Gradle / Ivy

There is a newer version: 4.3.20
Show newest version
/*
 *
 *  Copyright 2020 Netflix, Inc.
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */
package com.netflix.genie.web.services.impl;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.netflix.genie.web.exceptions.checked.IllegalAttachmentFileNameException;
import com.netflix.genie.web.exceptions.checked.AttachmentTooLargeException;
import com.netflix.genie.web.exceptions.checked.SaveAttachmentException;
import com.netflix.genie.web.properties.AttachmentServiceProperties;
import com.netflix.genie.web.services.AttachmentService;
import org.springframework.core.io.Resource;

import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import java.util.UUID;

/**
 * Implementation of {@link AttachmentService} that saves the files to a local directory.
 * 

* N.B.: This implementation is currently used for integration tests and lacks some aspects that would make it usable in * production environments (e.g., garbage collection of old files, metrics, etc.). * * @author mprimi * @since 4.0.0 */ public class LocalFileSystemAttachmentServiceImpl implements AttachmentService { private final Path attachmentsDirectoryPath; private final AttachmentServiceProperties attachmentServiceProperties; /** * Constructor. * * @param attachmentServiceProperties the service properties * @throws IOException when failing to create the attachments directory */ public LocalFileSystemAttachmentServiceImpl( final AttachmentServiceProperties attachmentServiceProperties ) throws IOException { this.attachmentServiceProperties = attachmentServiceProperties; this.attachmentsDirectoryPath = Paths.get(attachmentServiceProperties.getLocationPrefix()); // Create base attachments directory Files.createDirectories(this.attachmentsDirectoryPath); } /** * {@inheritDoc} */ @Override public Set saveAttachments( @Nullable final String jobId, final Set attachments ) throws SaveAttachmentException { if (attachments.isEmpty()) { return Sets.newHashSet(); } final Path attachmentsBasePath = this.attachmentsDirectoryPath.resolve(UUID.randomUUID().toString()); try { Files.createDirectories(attachmentsBasePath); } catch (IOException e) { throw new SaveAttachmentException("Failed to create directory for attachments: " + e.getMessage(), e); } long totalSize = 0; final ImmutableSet.Builder setBuilder = ImmutableSet.builder(); for (final Resource attachment : attachments) { try (InputStream inputStream = attachment.getInputStream()) { final long attachmentSize = attachment.contentLength(); final String filename = attachment.getFilename(); if (filename != null) { if ((filename.contains("/") || filename.contains("\\") || filename.equals(".") || filename.equals(".."))) { throw new IllegalAttachmentFileNameException("Attachment filename " + filename + " is illegal. " + "Filenames should not be . or .., or contain /, \\."); } final String attachmentCanonicalPath = createTempFile(String.valueOf(attachmentsBasePath), filename).getCanonicalPath(); final String baseCanonicalPath = new File(String.valueOf(attachmentsBasePath)).getCanonicalPath(); if (!attachmentCanonicalPath.startsWith(baseCanonicalPath) || attachmentCanonicalPath.equals(baseCanonicalPath)) { throw new IllegalAttachmentFileNameException("Attachment filename " + filename + " is illegal. " + "Filenames should not be a relative path."); } } if (attachmentSize > this.attachmentServiceProperties.getMaxSize().toBytes()) { throw new AttachmentTooLargeException("Attachment is too large: " + filename); } totalSize += attachmentSize; if (totalSize > this.attachmentServiceProperties.getMaxTotalSize().toBytes()) { throw new AttachmentTooLargeException("Attachments total size is too large"); } final Path attachmentPath = attachmentsBasePath.resolve( filename != null ? filename : UUID.randomUUID().toString() ); Files.copy(inputStream, attachmentPath); setBuilder.add(attachmentPath.toUri()); } catch (IOException e) { throw new SaveAttachmentException("Failed to save attachment: " + e.getMessage(), e); } } return setBuilder.build(); } /* for testing purposes */ File createTempFile(final String attachmentsBasePath, final String filename) { return new File(attachmentsBasePath, filename); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy