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

com.gkatzioura.maven.cloud.s3.S3StorageWagon Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2018 Emmanouil Gkatziouras
 *
 * 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.gkatzioura.maven.cloud.s3;

import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import com.gkatzioura.maven.cloud.resolver.KeyResolver;
import org.apache.commons.io.FileUtils;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.PathUtils;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.events.TransferEvent;
import org.apache.maven.wagon.proxy.ProxyInfoProvider;
import org.apache.maven.wagon.repository.Repository;
import org.apache.maven.wagon.resource.Resource;

import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.gkatzioura.maven.cloud.transfer.TransferProgress;
import com.gkatzioura.maven.cloud.transfer.TransferProgressImpl;
import com.gkatzioura.maven.cloud.wagon.AbstractStorageWagon;
import com.gkatzioura.maven.cloud.wagon.PublicReadProperty;

public class S3StorageWagon extends AbstractStorageWagon {

    private S3StorageRepository s3StorageRepository;
    private final KeyResolver keyResolver = new KeyResolver();

    private String region = System.getenv("AWS_REGION");
    private Boolean publicRepository;

    private static final Logger LOGGER = Logger.getLogger(S3StorageWagon.class.getName());
    private String endpoint;
    private String pathStyleEnabled;

    @Override
    public void get(String resourceName, File file) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {

        Resource resource = new Resource(resourceName);
        transferListenerContainer.fireTransferInitiated(resource, TransferEvent.REQUEST_GET);
        transferListenerContainer.fireTransferStarted(resource, TransferEvent.REQUEST_GET, file);

        final TransferProgress transferProgress = new TransferProgressImpl(resource, TransferEvent.REQUEST_GET, transferListenerContainer);

        try {
            s3StorageRepository.copy(resourceName,file,transferProgress);
            transferListenerContainer.fireTransferCompleted(resource,TransferEvent.REQUEST_GET);
        } catch (Exception e) {
            transferListenerContainer.fireTransferError(resource,TransferEvent.REQUEST_GET,e);
            throw e;
        }
    }

    @Override
    public void put(File file, String resourceName) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {

        Resource resource = new Resource(resourceName);

        LOGGER.log(Level.FINER, String.format("Uploading file %s to %s", file.getAbsolutePath(), resourceName));

        transferListenerContainer.fireTransferInitiated(resource,TransferEvent.REQUEST_PUT);
        transferListenerContainer.fireTransferStarted(resource,TransferEvent.REQUEST_PUT, file);
        final TransferProgress transferProgress = new TransferProgressImpl(resource, TransferEvent.REQUEST_PUT, transferListenerContainer);

        try {
            s3StorageRepository.put(file, resourceName,transferProgress);
            transferListenerContainer.fireTransferCompleted(resource, TransferEvent.REQUEST_PUT);
        } catch (TransferFailedException e) {
            transferListenerContainer.fireTransferError(resource,TransferEvent.REQUEST_PUT,e);
            throw e;
        }
    }

    @Override
    public boolean getIfNewer(String resourceName, File file, long timeStamp) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {

        if(s3StorageRepository.newResourceAvailable(resourceName,timeStamp)) {
            get(resourceName,file);
            return true;
        }

        return false;
    }

    @Override
    public void putDirectory(File source, String destination) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {
        Collection allFiles = FileUtils.listFiles(source, null, true);
        String relativeDestination = destination;
        //removes the initial .
        if (destination != null && destination.startsWith(".")){
            relativeDestination = destination.length() == 1 ? "" : destination.substring(1);
        }
        for (File file : allFiles) {
            //compute relative path
            String relativePath = PathUtils.toRelative(source, file.getAbsolutePath());
            put(file, relativeDestination +"/"+relativePath);
        }
    }

    @Override
    public boolean resourceExists(String resourceName) throws TransferFailedException, AuthorizationException {
        return s3StorageRepository.exists(resourceName);
    }

    @Override
    public List getFileList(String s) throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {
        try {
            List list = s3StorageRepository.list(s);
            list = convertS3ListToMavenFileList(list, s);
            if (list.isEmpty()){
                throw new ResourceDoesNotExistException(s);//expected by maven
            }
            return list;
        } catch (AmazonS3Exception e) {
            throw new TransferFailedException("Could not fetch objects for prefix "+s);
        }
    }

    //removes the prefix path
    //adds folders files
    private List convertS3ListToMavenFileList(List list, String path) {
        String prefix = keyResolver.resolve( s3StorageRepository.getBaseDirectory(), path);
        Set folders = new HashSet<>();
        List result = list.stream().map( key -> {
            String filePath = key;
            //removes the prefix from the object path
            if (prefix != null && prefix.length() > 0) {
                filePath = key.substring(prefix.length() + 1);
            }
            extractFolders(folders, filePath);
            return filePath;
        }).collect(Collectors.toList());
        result.addAll(folders);
        return result;
    }

    private void extractFolders(Set folders, String filePath) {
        if (filePath.contains("/")){
            String folder = filePath.substring(0, filePath.lastIndexOf('/'));
            folders.add(folder +'/');
            if (folder.contains("/")) {//recurse
                extractFolders(folders, folder);
            }//else we already stored it.
        }else{
            folders.add(filePath);
        }
    }

    @Override
    public void connect(Repository repository, AuthenticationInfo authenticationInfo, ProxyInfoProvider proxyInfoProvider) throws ConnectionException, AuthenticationException {

        this.repository = repository;
        this.sessionListenerContainer.fireSessionOpening();

        final String bucket = accountResolver.resolve(repository);
        final String directory = containerResolver.resolve(repository);

        LOGGER.log(Level.FINER,String.format("Opening connection for bucket %s and directory %s",bucket,directory));
        s3StorageRepository = new S3StorageRepository(bucket, directory, new PublicReadProperty(publicRepository));
        s3StorageRepository.connect(authenticationInfo, region, new EndpointProperty(endpoint), new PathStyleEnabledProperty(pathStyleEnabled));

        sessionListenerContainer.fireSessionLoggedIn();
        sessionListenerContainer.fireSessionOpened();
    }

    @Override
    public void disconnect() throws ConnectionException {
        sessionListenerContainer.fireSessionDisconnecting();
        s3StorageRepository.disconnect();
        sessionListenerContainer.fireSessionLoggedOff();
        sessionListenerContainer.fireSessionDisconnected();
    }

	public String getRegion() {
		return region;
	}

	public void setRegion(String region) {
		this.region = region;
	}

    public Boolean getPublicRepository() {
        return publicRepository;
    }

    public void setPublicRepository(Boolean publicRepository) {
        this.publicRepository = publicRepository;
    }

    public String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public String getPathStyleAccessEnabled() {
        return pathStyleEnabled;
    }

    public void setPathStyleAccessEnabled(String pathStyleEnabled) {
        this.pathStyleEnabled = pathStyleEnabled;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy