diff --git a/.travis.yml b/.travis.yml index 91983e1..b0bbf9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,5 +18,5 @@ before_script: - chmod a+x ./print_surefire_reports.sh script: mvn clean install after_success: -- mvn jacoco:report coveralls:jacoco +- mvn jacoco:report coveralls:report after_failure: ./print_surefire_reports.sh diff --git a/README.md b/README.md index 5c59e93..1ced1f0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This project provides a first API implementation, little optimized, but "complet com.upplication s3fs - 1.2.3 + 1.3.0 ``` diff --git a/pom.xml b/pom.xml index 0b07072..974b6e3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.upplication s3fs jar - 1.2.3 + 1.3.0 s3fs S3 filesystem provider for Java 7 https://github.com/Upplication/Amazon-S3-FileSystem-NIO2 @@ -216,69 +216,78 @@ - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven.surfire.plugin.version} - - - **/*IT.java - - - - - integration-test - integration-test - - integration-test - - - - verify - verify - - verify - - - - - - - - - travis - - - env.TRAVIS - true - - - + + org.apache.maven.plugins + maven-surefire-plugin + + ${jacoco.agent.arg} + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.7.1 + + + **/*IT.java + + ${jacoco.agent.arg} + + + + integration-test + integration-test + + integration-test + + + + verify + verify + + verify + + + + + org.eluder.coveralls coveralls-maven-plugin - 2.2.0 + 4.1.0 + org.jacoco jacoco-maven-plugin - 0.6.4.201312101107 + 0.7.6.201602180812 + + - prepare-agent + pre-unit-test prepare-agent + + jacoco.agent.arg + true + + + + + post-unit-test + integration-test + + report + - - - - + + release-sign-artifacts diff --git a/src/main/java/com/upplication/s3fs/AmazonS3ClientFactory.java b/src/main/java/com/upplication/s3fs/AmazonS3ClientFactory.java index 5f75702..9143e4b 100644 --- a/src/main/java/com/upplication/s3fs/AmazonS3ClientFactory.java +++ b/src/main/java/com/upplication/s3fs/AmazonS3ClientFactory.java @@ -6,8 +6,8 @@ import com.amazonaws.services.s3.AmazonS3Client; public class AmazonS3ClientFactory extends AmazonS3Factory { - @Override - protected AmazonS3Client createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { - return new AmazonS3Client(credentialsProvider, clientConfiguration, requestMetricsCollector); - } + @Override + protected AmazonS3Client createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { + return new AmazonS3Client(credentialsProvider, clientConfiguration, requestMetricsCollector); + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/AmazonS3Factory.java b/src/main/java/com/upplication/s3fs/AmazonS3Factory.java index f6652b8..114775b 100644 --- a/src/main/java/com/upplication/s3fs/AmazonS3Factory.java +++ b/src/main/java/com/upplication/s3fs/AmazonS3Factory.java @@ -20,100 +20,101 @@ */ public abstract class AmazonS3Factory { - public static final String ACCESS_KEY = "s3fs_access_key"; - public static final String SECRET_KEY = "s3fs_secret_key"; - public static final String REQUEST_METRIC_COLLECTOR_CLASS = "s3fs_request_metric_collector_class"; - public static final String CONNECTION_TIMEOUT = "s3fs_connection_timeout"; - public static final String MAX_CONNECTIONS = "s3fs_max_connections"; - public static final String MAX_ERROR_RETRY = "s3fs_max_retry_error"; - public static final String PROTOCOL = "s3fs_protocol"; - public static final String PROXY_DOMAIN = "s3fs_proxy_domain"; - public static final String PROXY_HOST = "s3fs_proxy_host"; - public static final String PROXY_PASSWORD = "s3fs_proxy_password"; - public static final String PROXY_PORT = "s3fs_proxy_port"; - public static final String PROXY_USERNAME = "s3fs_proxy_username"; - public static final String PROXY_WORKSTATION = "s3fs_proxy_workstation"; - public static final String SOCKET_SEND_BUFFER_SIZE_HINT = "s3fs_socket_send_buffer_size_hint"; - public static final String SOCKET_RECEIVE_BUFFER_SIZE_HINT = "s3fs_socket_receive_buffer_size_hint"; - public static final String SOCKET_TIMEOUT = "s3fs_socket_timeout"; - public static final String USER_AGENT = "s3fs_user_agent"; + public static final String ACCESS_KEY = "s3fs_access_key"; + public static final String SECRET_KEY = "s3fs_secret_key"; + public static final String REQUEST_METRIC_COLLECTOR_CLASS = "s3fs_request_metric_collector_class"; + public static final String CONNECTION_TIMEOUT = "s3fs_connection_timeout"; + public static final String MAX_CONNECTIONS = "s3fs_max_connections"; + public static final String MAX_ERROR_RETRY = "s3fs_max_retry_error"; + public static final String PROTOCOL = "s3fs_protocol"; + public static final String PROXY_DOMAIN = "s3fs_proxy_domain"; + public static final String PROXY_HOST = "s3fs_proxy_host"; + public static final String PROXY_PASSWORD = "s3fs_proxy_password"; + public static final String PROXY_PORT = "s3fs_proxy_port"; + public static final String PROXY_USERNAME = "s3fs_proxy_username"; + public static final String PROXY_WORKSTATION = "s3fs_proxy_workstation"; + public static final String SOCKET_SEND_BUFFER_SIZE_HINT = "s3fs_socket_send_buffer_size_hint"; + public static final String SOCKET_RECEIVE_BUFFER_SIZE_HINT = "s3fs_socket_receive_buffer_size_hint"; + public static final String SOCKET_TIMEOUT = "s3fs_socket_timeout"; + public static final String USER_AGENT = "s3fs_user_agent"; - protected Logger logger = LoggerFactory.getLogger(getClass()); + protected Logger logger = LoggerFactory.getLogger(getClass()); /** * should return a new AmazonS3 - * @param credentialsProvider AWSCredentialsProvider mandatory - * @param clientConfiguration ClientConfiguration mandatory + * + * @param credentialsProvider AWSCredentialsProvider mandatory + * @param clientConfiguration ClientConfiguration mandatory * @param requestMetricsCollector RequestMetricCollector mandatory * @return {@link com.amazonaws.services.s3.AmazonS3} */ - protected abstract AmazonS3 createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector); + protected abstract AmazonS3 createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector); - public AmazonS3 getAmazonS3(URI uri, Properties props) { - AmazonS3 client = createAmazonS3(getCredentialsProvider(props), getClientConfiguration(props), getRequestMetricsCollector(props)); - if (uri.getHost() != null) - client.setEndpoint(uri.getHost()); - return client; - } + public AmazonS3 getAmazonS3(URI uri, Properties props) { + AmazonS3 client = createAmazonS3(getCredentialsProvider(props), getClientConfiguration(props), getRequestMetricsCollector(props)); + if (uri.getHost() != null) + client.setEndpoint(uri.getHost()); + return client; + } - protected AWSCredentialsProvider getCredentialsProvider(Properties props) { - AWSCredentialsProvider credentialsProvider; - if (props.getProperty(ACCESS_KEY) == null && props.getProperty(SECRET_KEY) == null) - credentialsProvider = new DefaultAWSCredentialsProviderChain(); - else - credentialsProvider = new StaticCredentialsProvider(getAWSCredentials(props)); - return credentialsProvider; - } + protected AWSCredentialsProvider getCredentialsProvider(Properties props) { + AWSCredentialsProvider credentialsProvider; + if (props.getProperty(ACCESS_KEY) == null && props.getProperty(SECRET_KEY) == null) + credentialsProvider = new DefaultAWSCredentialsProviderChain(); + else + credentialsProvider = new StaticCredentialsProvider(getAWSCredentials(props)); + return credentialsProvider; + } - protected RequestMetricCollector getRequestMetricsCollector(Properties props) { - RequestMetricCollector requestMetricCollector = null; - if (props.containsKey(REQUEST_METRIC_COLLECTOR_CLASS)) { - try { - requestMetricCollector = (RequestMetricCollector) Class.forName(props.getProperty(REQUEST_METRIC_COLLECTOR_CLASS)).newInstance(); - } catch (Throwable t) { - throw new IllegalArgumentException("Can't instantiate REQUEST_METRIC_COLLECTOR_CLASS " + props.getProperty(REQUEST_METRIC_COLLECTOR_CLASS), t); - } - } - return requestMetricCollector; - } + protected RequestMetricCollector getRequestMetricsCollector(Properties props) { + RequestMetricCollector requestMetricCollector = null; + if (props.containsKey(REQUEST_METRIC_COLLECTOR_CLASS)) { + try { + requestMetricCollector = (RequestMetricCollector) Class.forName(props.getProperty(REQUEST_METRIC_COLLECTOR_CLASS)).newInstance(); + } catch (Throwable t) { + throw new IllegalArgumentException("Can't instantiate REQUEST_METRIC_COLLECTOR_CLASS " + props.getProperty(REQUEST_METRIC_COLLECTOR_CLASS), t); + } + } + return requestMetricCollector; + } - protected ClientConfiguration getClientConfiguration(Properties props) { - ClientConfiguration clientConfiguration = new ClientConfiguration(); - if (props.getProperty(CONNECTION_TIMEOUT) != null) - clientConfiguration.setConnectionTimeout(Integer.parseInt(props.getProperty(CONNECTION_TIMEOUT))); - if (props.getProperty(MAX_CONNECTIONS) != null) - clientConfiguration.setMaxConnections(Integer.parseInt(props.getProperty(MAX_CONNECTIONS))); - if (props.getProperty(MAX_ERROR_RETRY) != null) - clientConfiguration.setMaxErrorRetry(Integer.parseInt(props.getProperty(MAX_ERROR_RETRY))); - if (props.getProperty(PROTOCOL) != null) - clientConfiguration.setProtocol(Protocol.valueOf(props.getProperty(PROTOCOL))); - if (props.getProperty(PROXY_DOMAIN) != null) - clientConfiguration.setProxyDomain(props.getProperty(PROXY_DOMAIN)); - if (props.getProperty(PROXY_HOST) != null) - clientConfiguration.setProxyHost(props.getProperty(PROXY_HOST)); - if (props.getProperty(PROXY_PASSWORD) != null) - clientConfiguration.setProxyPassword(props.getProperty(PROXY_PASSWORD)); - if (props.getProperty(PROXY_PORT) != null) - clientConfiguration.setProxyPort(Integer.parseInt(props.getProperty(PROXY_PORT))); - if (props.getProperty(PROXY_USERNAME) != null) - clientConfiguration.setProxyUsername(props.getProperty(PROXY_USERNAME)); - if (props.getProperty(PROXY_WORKSTATION) != null) - clientConfiguration.setProxyWorkstation(props.getProperty(PROXY_WORKSTATION)); - int socketSendBufferSizeHint = 0; - if (props.getProperty(SOCKET_SEND_BUFFER_SIZE_HINT) != null) - socketSendBufferSizeHint = Integer.parseInt(props.getProperty(SOCKET_SEND_BUFFER_SIZE_HINT)); - int socketReceiveBufferSizeHint = 0; - if (props.getProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT) != null) - socketReceiveBufferSizeHint = Integer.parseInt(props.getProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT)); - clientConfiguration.setSocketBufferSizeHints(socketSendBufferSizeHint, socketReceiveBufferSizeHint); - if (props.getProperty(SOCKET_TIMEOUT) != null) - clientConfiguration.setSocketTimeout(Integer.parseInt(props.getProperty(SOCKET_TIMEOUT))); - if (props.getProperty(USER_AGENT) != null) - clientConfiguration.setUserAgent(props.getProperty(USER_AGENT)); - return clientConfiguration; - } + protected ClientConfiguration getClientConfiguration(Properties props) { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + if (props.getProperty(CONNECTION_TIMEOUT) != null) + clientConfiguration.setConnectionTimeout(Integer.parseInt(props.getProperty(CONNECTION_TIMEOUT))); + if (props.getProperty(MAX_CONNECTIONS) != null) + clientConfiguration.setMaxConnections(Integer.parseInt(props.getProperty(MAX_CONNECTIONS))); + if (props.getProperty(MAX_ERROR_RETRY) != null) + clientConfiguration.setMaxErrorRetry(Integer.parseInt(props.getProperty(MAX_ERROR_RETRY))); + if (props.getProperty(PROTOCOL) != null) + clientConfiguration.setProtocol(Protocol.valueOf(props.getProperty(PROTOCOL))); + if (props.getProperty(PROXY_DOMAIN) != null) + clientConfiguration.setProxyDomain(props.getProperty(PROXY_DOMAIN)); + if (props.getProperty(PROXY_HOST) != null) + clientConfiguration.setProxyHost(props.getProperty(PROXY_HOST)); + if (props.getProperty(PROXY_PASSWORD) != null) + clientConfiguration.setProxyPassword(props.getProperty(PROXY_PASSWORD)); + if (props.getProperty(PROXY_PORT) != null) + clientConfiguration.setProxyPort(Integer.parseInt(props.getProperty(PROXY_PORT))); + if (props.getProperty(PROXY_USERNAME) != null) + clientConfiguration.setProxyUsername(props.getProperty(PROXY_USERNAME)); + if (props.getProperty(PROXY_WORKSTATION) != null) + clientConfiguration.setProxyWorkstation(props.getProperty(PROXY_WORKSTATION)); + int socketSendBufferSizeHint = 0; + if (props.getProperty(SOCKET_SEND_BUFFER_SIZE_HINT) != null) + socketSendBufferSizeHint = Integer.parseInt(props.getProperty(SOCKET_SEND_BUFFER_SIZE_HINT)); + int socketReceiveBufferSizeHint = 0; + if (props.getProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT) != null) + socketReceiveBufferSizeHint = Integer.parseInt(props.getProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT)); + clientConfiguration.setSocketBufferSizeHints(socketSendBufferSizeHint, socketReceiveBufferSizeHint); + if (props.getProperty(SOCKET_TIMEOUT) != null) + clientConfiguration.setSocketTimeout(Integer.parseInt(props.getProperty(SOCKET_TIMEOUT))); + if (props.getProperty(USER_AGENT) != null) + clientConfiguration.setUserAgent(props.getProperty(USER_AGENT)); + return clientConfiguration; + } - protected BasicAWSCredentials getAWSCredentials(Properties props) { - return new BasicAWSCredentials(props.getProperty(ACCESS_KEY), props.getProperty(SECRET_KEY)); - } + protected BasicAWSCredentials getAWSCredentials(Properties props) { + return new BasicAWSCredentials(props.getProperty(ACCESS_KEY), props.getProperty(SECRET_KEY)); + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/S3AccessControlList.java b/src/main/java/com/upplication/s3fs/S3AccessControlList.java index 2d3c73f..a00adcd 100644 --- a/src/main/java/com/upplication/s3fs/S3AccessControlList.java +++ b/src/main/java/com/upplication/s3fs/S3AccessControlList.java @@ -12,52 +12,53 @@ import com.amazonaws.services.s3.model.Permission; public class S3AccessControlList { - private String fileStoreName; - private String key; - private AccessControlList acl; - private Owner owner; - - public S3AccessControlList(String fileStoreName, String key, AccessControlList acl, Owner owner) { - this.fileStoreName = fileStoreName; - this.acl = acl; - this.key = key; - this.owner = owner; - } - - public String getKey() { - return key; - } - - /** - * have almost one of the permission set in the parameter permissions - * @param permissions almost one - * @return - */ - private boolean hasPermission(EnumSet permissions) { - for (Grant grant : acl.getGrants()) - if (grant.getGrantee().getIdentifier().equals(owner.getId()) && permissions.contains(grant.getPermission())) - return true; - return false; - } - - public void checkAccess(AccessMode[] modes) throws AccessDeniedException { - for (AccessMode accessMode : modes) { - switch (accessMode) { - case EXECUTE: - throw new AccessDeniedException(fileName(), null, "file is not executable"); - case READ: - if (!hasPermission(EnumSet.of(Permission.FullControl, Permission.Read))) - throw new AccessDeniedException(fileName(), null, "file is not readable"); - break; - case WRITE: - if (!hasPermission(EnumSet.of(Permission.FullControl, Permission.Write))) - throw new AccessDeniedException(fileName(), null, format("bucket '%s' is not writable", fileStoreName)); - break; - } - } - } - - private String fileName() { - return fileStoreName + S3Path.PATH_SEPARATOR + key; - } + private String fileStoreName; + private String key; + private AccessControlList acl; + private Owner owner; + + public S3AccessControlList(String fileStoreName, String key, AccessControlList acl, Owner owner) { + this.fileStoreName = fileStoreName; + this.acl = acl; + this.key = key; + this.owner = owner; + } + + public String getKey() { + return key; + } + + /** + * have almost one of the permission set in the parameter permissions + * + * @param permissions almost one + * @return + */ + private boolean hasPermission(EnumSet permissions) { + for (Grant grant : acl.getGrants()) + if (grant.getGrantee().getIdentifier().equals(owner.getId()) && permissions.contains(grant.getPermission())) + return true; + return false; + } + + public void checkAccess(AccessMode[] modes) throws AccessDeniedException { + for (AccessMode accessMode : modes) { + switch (accessMode) { + case EXECUTE: + throw new AccessDeniedException(fileName(), null, "file is not executable"); + case READ: + if (!hasPermission(EnumSet.of(Permission.FullControl, Permission.Read))) + throw new AccessDeniedException(fileName(), null, "file is not readable"); + break; + case WRITE: + if (!hasPermission(EnumSet.of(Permission.FullControl, Permission.Write))) + throw new AccessDeniedException(fileName(), null, format("bucket '%s' is not writable", fileStoreName)); + break; + } + } + } + + private String fileName() { + return fileStoreName + S3Path.PATH_SEPARATOR + key; + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/S3FileAttributes.java b/src/main/java/com/upplication/s3fs/S3FileAttributes.java index 0c35a2e..9233e74 100644 --- a/src/main/java/com/upplication/s3fs/S3FileAttributes.java +++ b/src/main/java/com/upplication/s3fs/S3FileAttributes.java @@ -6,80 +6,80 @@ import java.nio.file.attribute.FileTime; public class S3FileAttributes implements BasicFileAttributes { - private final FileTime lastModifiedTime; - private final long size; - private final boolean directory; - private final boolean regularFile; - private final String key; - private long cacheCreated; - - public S3FileAttributes(String key, FileTime lastModifiedTime, long size, boolean isDirectory, boolean isRegularFile) { - this.key = key; - this.lastModifiedTime = lastModifiedTime; - this.size = size; - directory = isDirectory; - regularFile = isRegularFile; - - cacheCreated = System.currentTimeMillis(); - } - - @Override - public FileTime lastModifiedTime() { - return lastModifiedTime; - } - - @Override - public FileTime lastAccessTime() { - return lastModifiedTime; - } - - @Override - public FileTime creationTime() { - return lastModifiedTime; - } - - @Override - public boolean isRegularFile() { - return regularFile; - } - - @Override - public boolean isDirectory() { - return directory; - } - - @Override - public boolean isSymbolicLink() { - return false; - } - - @Override - public boolean isOther() { - return false; - } - - @Override - public long size() { - return size; - } - - @Override - public Object fileKey() { - return key; - } - - @Override - public String toString() { - return format("[%s: lastModified=%s, size=%s, isDirectory=%s, isRegularFile=%s]", key, lastModifiedTime, size, directory, regularFile); - } - - public long getCacheCreated() { - return cacheCreated; - } - - // for testing - - public void setCacheCreated(long time) { - this.cacheCreated = time; - } + private final FileTime lastModifiedTime; + private final long size; + private final boolean directory; + private final boolean regularFile; + private final String key; + private long cacheCreated; + + public S3FileAttributes(String key, FileTime lastModifiedTime, long size, boolean isDirectory, boolean isRegularFile) { + this.key = key; + this.lastModifiedTime = lastModifiedTime; + this.size = size; + this.directory = isDirectory; + this.regularFile = isRegularFile; + + this.cacheCreated = System.currentTimeMillis(); + } + + @Override + public FileTime lastModifiedTime() { + return lastModifiedTime; + } + + @Override + public FileTime lastAccessTime() { + return lastModifiedTime; + } + + @Override + public FileTime creationTime() { + return lastModifiedTime; + } + + @Override + public boolean isRegularFile() { + return regularFile; + } + + @Override + public boolean isDirectory() { + return directory; + } + + @Override + public boolean isSymbolicLink() { + return false; + } + + @Override + public boolean isOther() { + return false; + } + + @Override + public long size() { + return size; + } + + @Override + public Object fileKey() { + return key; + } + + @Override + public String toString() { + return format("[%s: lastModified=%s, size=%s, isDirectory=%s, isRegularFile=%s]", key, lastModifiedTime, size, directory, regularFile); + } + + public long getCacheCreated() { + return cacheCreated; + } + + // for testing + + public void setCacheCreated(long time) { + this.cacheCreated = time; + } } diff --git a/src/main/java/com/upplication/s3fs/S3FileStore.java b/src/main/java/com/upplication/s3fs/S3FileStore.java index 8ebb0d7..724578c 100644 --- a/src/main/java/com/upplication/s3fs/S3FileStore.java +++ b/src/main/java/com/upplication/s3fs/S3FileStore.java @@ -13,135 +13,135 @@ public class S3FileStore extends FileStore implements Comparable { private S3FileSystem fileSystem; - private String name; - - public S3FileStore(S3FileSystem s3FileSystem, String name) { - this.fileSystem = s3FileSystem; - this.name = name; - } - - @Override - public String name() { - return name; - } - - @Override - public String type() { - return "S3Bucket"; - } - - @Override - public boolean isReadOnly() { - return false; - } - - @Override - public long getTotalSpace() throws IOException { - return Long.MAX_VALUE; - } - - @Override - public long getUsableSpace() throws IOException { - return Long.MAX_VALUE; - } - - @Override - public long getUnallocatedSpace() throws IOException { - return Long.MAX_VALUE; - } - - @Override - public boolean supportsFileAttributeView(Class type) { - return false; - } - - @Override - public boolean supportsFileAttributeView(String attributeViewName) { - return false; - } - - @SuppressWarnings("unchecked") - @Override - public V getFileStoreAttributeView(Class type) { - if (type != S3FileStoreAttributeView.class) - throw new IllegalArgumentException("FileStoreAttributeView of type '" + type.getName() + "' is not supported."); - Bucket buck = getBucket(); - Owner owner = buck.getOwner(); - return (V) new S3FileStoreAttributeView(buck.getCreationDate(), buck.getName(), owner.getId(), owner.getDisplayName()); - } - - @Override - public Object getAttribute(String attribute) throws IOException { - return getFileStoreAttributeView(S3FileStoreAttributeView.class).getAttribute(attribute); - } - - public S3FileSystem getFileSystem() { - return fileSystem; - } - - public Bucket getBucket(){ + private String name; + + public S3FileStore(S3FileSystem s3FileSystem, String name) { + this.fileSystem = s3FileSystem; + this.name = name; + } + + @Override + public String name() { + return name; + } + + @Override + public String type() { + return "S3Bucket"; + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public long getTotalSpace() throws IOException { + return Long.MAX_VALUE; + } + + @Override + public long getUsableSpace() throws IOException { + return Long.MAX_VALUE; + } + + @Override + public long getUnallocatedSpace() throws IOException { + return Long.MAX_VALUE; + } + + @Override + public boolean supportsFileAttributeView(Class type) { + return false; + } + + @Override + public boolean supportsFileAttributeView(String attributeViewName) { + return false; + } + + @SuppressWarnings("unchecked") + @Override + public V getFileStoreAttributeView(Class type) { + if (type != S3FileStoreAttributeView.class) + throw new IllegalArgumentException("FileStoreAttributeView of type '" + type.getName() + "' is not supported."); + Bucket buck = getBucket(); + Owner owner = buck.getOwner(); + return (V) new S3FileStoreAttributeView(buck.getCreationDate(), buck.getName(), owner.getId(), owner.getDisplayName()); + } + + @Override + public Object getAttribute(String attribute) throws IOException { + return getFileStoreAttributeView(S3FileStoreAttributeView.class).getAttribute(attribute); + } + + public S3FileSystem getFileSystem() { + return fileSystem; + } + + public Bucket getBucket() { return getBucket(name); } - private Bucket getBucket(String bucketName) { - for (Bucket buck : getClient().listBuckets()) - if (buck.getName().equals(bucketName)) - return buck; - return null; - } - - public S3Path getRootDirectory() { - return new S3Path(fileSystem, this, ImmutableList. of()); - } - - private AmazonS3 getClient() { - return fileSystem.getClient(); - } - - public Owner getOwner() { - Bucket buck = getBucket(); - if (buck != null) - return buck.getOwner(); - return fileSystem.getClient().getS3AccountOwner(); - } - - @Override - public int compareTo(S3FileStore o) { - if (this == o) - return 0; - return o.name().compareTo(name); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fileSystem == null) ? 0 : fileSystem.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof S3FileStore)) - return false; - S3FileStore other = (S3FileStore) obj; - - if (fileSystem == null) { - if (other.fileSystem != null) - return false; - } else if (!fileSystem.equals(other.fileSystem)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } + private Bucket getBucket(String bucketName) { + for (Bucket buck : getClient().listBuckets()) + if (buck.getName().equals(bucketName)) + return buck; + return null; + } + + public S3Path getRootDirectory() { + return new S3Path(fileSystem, this, ImmutableList.of()); + } + + private AmazonS3 getClient() { + return fileSystem.getClient(); + } + + public Owner getOwner() { + Bucket buck = getBucket(); + if (buck != null) + return buck.getOwner(); + return fileSystem.getClient().getS3AccountOwner(); + } + + @Override + public int compareTo(S3FileStore o) { + if (this == o) + return 0; + return o.name().compareTo(name); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((fileSystem == null) ? 0 : fileSystem.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof S3FileStore)) + return false; + S3FileStore other = (S3FileStore) obj; + + if (fileSystem == null) { + if (other.fileSystem != null) + return false; + } else if (!fileSystem.equals(other.fileSystem)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/S3FileStoreAttributeView.java b/src/main/java/com/upplication/s3fs/S3FileStoreAttributeView.java index 6cb443f..df5a32f 100644 --- a/src/main/java/com/upplication/s3fs/S3FileStoreAttributeView.java +++ b/src/main/java/com/upplication/s3fs/S3FileStoreAttributeView.java @@ -5,43 +5,43 @@ public class S3FileStoreAttributeView implements FileStoreAttributeView { - public static final String ATTRIBUTE_VIEW_NAME = "S3FileStoreAttributeView"; + public static final String ATTRIBUTE_VIEW_NAME = "S3FileStoreAttributeView"; private Date creationDate; - private String name; - private String ownerId; - private String ownerDisplayName; - - public static enum AttrID { - creationDate, name, ownerId, ownerDisplayName - } - - public S3FileStoreAttributeView(Date creationDate, String name, String ownerId, String ownerDisplayName) { - this.creationDate = creationDate; - this.name = name; - this.ownerId = ownerId; - this.ownerDisplayName = ownerDisplayName; - } - - @Override - public String name() { - return ATTRIBUTE_VIEW_NAME; - } - - public Object getAttribute(String attribute) { - return getAttribute(AttrID.valueOf(attribute)); - } - - private Object getAttribute(AttrID attrID) { - switch (attrID) { - case creationDate: - return creationDate; - case ownerDisplayName: - return ownerDisplayName; - case ownerId: - return ownerId; - default: - return name; - } - } + private String name; + private String ownerId; + private String ownerDisplayName; + + public static enum AttrID { + creationDate, name, ownerId, ownerDisplayName + } + + public S3FileStoreAttributeView(Date creationDate, String name, String ownerId, String ownerDisplayName) { + this.creationDate = creationDate; + this.name = name; + this.ownerId = ownerId; + this.ownerDisplayName = ownerDisplayName; + } + + @Override + public String name() { + return ATTRIBUTE_VIEW_NAME; + } + + public Object getAttribute(String attribute) { + return getAttribute(AttrID.valueOf(attribute)); + } + + private Object getAttribute(AttrID attrID) { + switch (attrID) { + case creationDate: + return creationDate; + case ownerDisplayName: + return ownerDisplayName; + case ownerId: + return ownerId; + default: + return name; + } + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/S3FileSystem.java b/src/main/java/com/upplication/s3fs/S3FileSystem.java index 6f54a78..4b143af 100644 --- a/src/main/java/com/upplication/s3fs/S3FileSystem.java +++ b/src/main/java/com/upplication/s3fs/S3FileSystem.java @@ -20,165 +20,166 @@ /** * S3FileSystem with a concrete client configured and ready to use. + * * @see AmazonS3 configured by {@link AmazonS3Factory} */ public class S3FileSystem extends FileSystem implements Comparable { - private final S3FileSystemProvider provider; - private final String key; - private final AmazonS3 client; - private final String endpoint; + private final S3FileSystemProvider provider; + private final String key; + private final AmazonS3 client; + private final String endpoint; private int cache; public S3FileSystem(S3FileSystemProvider provider, String key, AmazonS3 client, String endpoint) { - this.provider = provider; - this.key = key; - this.client = client; - this.endpoint = endpoint; + this.provider = provider; + this.key = key; + this.client = client; + this.endpoint = endpoint; this.cache = 60000; // 1 minute cache for the s3Path - } - - @Override - public S3FileSystemProvider provider() { - return provider; - } - - public String getKey() { - return key; - } - - @Override - public void close() throws IOException { - this.provider.close(this); - } - - @Override - public boolean isOpen() { - return this.provider.isOpen(this); - } - - @Override - public boolean isReadOnly() { - return false; - } - - @Override - public String getSeparator() { - return S3Path.PATH_SEPARATOR; - } - - @Override - public Iterable getRootDirectories() { - ImmutableList.Builder builder = ImmutableList.builder(); - for (FileStore fileStore : getFileStores()) { - builder.add(((S3FileStore) fileStore).getRootDirectory()); - } - return builder.build(); - } - - @Override - public Iterable getFileStores() { - ImmutableList.Builder builder = ImmutableList.builder(); - for (Bucket bucket : client.listBuckets()) { - builder.add(new S3FileStore(this, bucket.getName())); - } - return builder.build(); - } - - @Override - public Set supportedFileAttributeViews() { - return ImmutableSet.of("basic"); - } - - @Override - public S3Path getPath(String first, String... more) { - if (more.length == 0) { - return new S3Path(this, first); - } - - return new S3Path(this, first, more); - } - - @Override - public PathMatcher getPathMatcher(String syntaxAndPattern) { - throw new UnsupportedOperationException(); - } - - @Override - public UserPrincipalLookupService getUserPrincipalLookupService() { - throw new UnsupportedOperationException(); - } - - @Override - public WatchService newWatchService() throws IOException { - throw new UnsupportedOperationException(); - } - - public AmazonS3 getClient() { - return client; - } - - /** - * get the endpoint associated with this fileSystem. - * - * @see http://docs.aws.amazon.com/general/latest/gr/rande.html - * @return string - */ - public String getEndpoint() { - return endpoint; - } - - public String[] key2Parts(String keyParts) { - String[] parts = keyParts.split(PATH_SEPARATOR); - String[] split = new String[parts.length]; - int i=0; - for (String part : parts) { - split[i++] = part; + } + + @Override + public S3FileSystemProvider provider() { + return provider; + } + + public String getKey() { + return key; + } + + @Override + public void close() throws IOException { + this.provider.close(this); + } + + @Override + public boolean isOpen() { + return this.provider.isOpen(this); + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public String getSeparator() { + return S3Path.PATH_SEPARATOR; + } + + @Override + public Iterable getRootDirectories() { + ImmutableList.Builder builder = ImmutableList.builder(); + for (FileStore fileStore : getFileStores()) { + builder.add(((S3FileStore) fileStore).getRootDirectory()); + } + return builder.build(); + } + + @Override + public Iterable getFileStores() { + ImmutableList.Builder builder = ImmutableList.builder(); + for (Bucket bucket : client.listBuckets()) { + builder.add(new S3FileStore(this, bucket.getName())); + } + return builder.build(); + } + + @Override + public Set supportedFileAttributeViews() { + return ImmutableSet.of("basic"); + } + + @Override + public S3Path getPath(String first, String... more) { + if (more.length == 0) { + return new S3Path(this, first); + } + + return new S3Path(this, first, more); + } + + @Override + public PathMatcher getPathMatcher(String syntaxAndPattern) { + throw new UnsupportedOperationException(); + } + + @Override + public UserPrincipalLookupService getUserPrincipalLookupService() { + throw new UnsupportedOperationException(); + } + + @Override + public WatchService newWatchService() throws IOException { + throw new UnsupportedOperationException(); + } + + public AmazonS3 getClient() { + return client; + } + + /** + * get the endpoint associated with this fileSystem. + * + * @return string + * @see http://docs.aws.amazon.com/general/latest/gr/rande.html + */ + public String getEndpoint() { + return endpoint; + } + + public String[] key2Parts(String keyParts) { + String[] parts = keyParts.split(PATH_SEPARATOR); + String[] split = new String[parts.length]; + int i = 0; + for (String part : parts) { + split[i++] = part; } return split; - } + } - public String parts2Key(List parts) { - if (parts.isEmpty()) - return ""; + public String parts2Key(List parts) { + if (parts.isEmpty()) + return ""; return Joiner.on(PATH_SEPARATOR).join(ImmutableList.copyOf(parts)); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((endpoint == null) ? 0 : endpoint.hashCode()); - result = prime * result + ((key == null) ? 0 : key.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof S3FileSystem)) - return false; - S3FileSystem other = (S3FileSystem) obj; - if (endpoint == null) { - if (other.endpoint != null) - return false; - } else if (!endpoint.equals(other.endpoint)) - return false; - if (key == null) { - if (other.key != null) - return false; - } else if (!key.equals(other.key)) - return false; - return true; - } - - @Override - public int compareTo(S3FileSystem o) { - return key.compareTo(o.getKey()); - } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((endpoint == null) ? 0 : endpoint.hashCode()); + result = prime * result + ((key == null) ? 0 : key.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof S3FileSystem)) + return false; + S3FileSystem other = (S3FileSystem) obj; + if (endpoint == null) { + if (other.endpoint != null) + return false; + } else if (!endpoint.equals(other.endpoint)) + return false; + if (key == null) { + if (other.key != null) + return false; + } else if (!key.equals(other.key)) + return false; + return true; + } + + @Override + public int compareTo(S3FileSystem o) { + return key.compareTo(o.getKey()); + } public int getCache() { return cache; diff --git a/src/main/java/com/upplication/s3fs/S3FileSystemConfigurationException.java b/src/main/java/com/upplication/s3fs/S3FileSystemConfigurationException.java index 655085c..7f203f8 100644 --- a/src/main/java/com/upplication/s3fs/S3FileSystemConfigurationException.java +++ b/src/main/java/com/upplication/s3fs/S3FileSystemConfigurationException.java @@ -1,9 +1,9 @@ package com.upplication.s3fs; public class S3FileSystemConfigurationException extends RuntimeException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public S3FileSystemConfigurationException(String message, Throwable cause) { - super(message, cause); - } + public S3FileSystemConfigurationException(String message, Throwable cause) { + super(message, cause); + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java b/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java index af53c13..41dae96 100644 --- a/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java +++ b/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java @@ -41,194 +41,195 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; +import com.upplication.s3fs.util.AttributesUtils; import com.upplication.s3fs.util.Cache; import com.upplication.s3fs.util.S3Utils; /** * Spec: - * + *

* URI: s3://[endpoint]/{bucket}/{key} If endpoint is missing, it's assumed to * be the default S3 endpoint (s3.amazonaws.com) - * + *

* FileSystem roots: /{bucket}/ - * + *

* Treatment of S3 objects: - If a key ends in "/" it's considered a directory * *and* a regular file. Otherwise, it's just a regular file. - It is legal for * a key "xyz" and "xyz/" to exist at the same time. The latter is treated as a * directory. - If a file "a/b/c" exists but there's no "a" or "a/b/", these are * considered "implicit" directories. They can be listed, traversed and deleted. - * + *

* Deviations from FileSystem provider API: - Deleting a file or directory * always succeeds, regardless of whether the file/directory existed before the * operation was issued i.e. Files.delete() and Files.deleteIfExists() are * equivalent. - * - * + *

+ *

* Future versions of this provider might allow for a strict mode that mimics * the semantics of the FileSystem provider API on a best effort basis, at an * increased processing cost. - * - * */ public class S3FileSystemProvider extends FileSystemProvider { - public static final String CHARSET_KEY = "s3fs_charset"; - public static final String AMAZON_S3_FACTORY_CLASS = "s3fs_amazon_s3_factory"; + public static final String CHARSET_KEY = "s3fs_charset"; + public static final String AMAZON_S3_FACTORY_CLASS = "s3fs_amazon_s3_factory"; private static final ConcurrentMap fileSystems = new ConcurrentHashMap<>(); private S3Utils s3Utils = new S3Utils(); private Cache cache = new Cache(); - @Override - public String getScheme() { - return "s3"; - } - - @Override - public FileSystem newFileSystem(URI uri, Map env) { - validateUri(uri); - // get properties for the env or properties or system - Properties props = getProperties(uri, env); - validateProperties(props); + @Override + public String getScheme() { + return "s3"; + } + + @Override + public FileSystem newFileSystem(URI uri, Map env) { + validateUri(uri); + // get properties for the env or properties or system + Properties props = getProperties(uri, env); + validateProperties(props); // try to get the filesystem by the key - String key = getFileSystemKey(uri, props); - if (fileSystems.containsKey(key)) { + String key = getFileSystemKey(uri, props); + if (fileSystems.containsKey(key)) { throw new FileSystemAlreadyExistsException("File system " + uri.getScheme() + ':' + key + " already exists"); } // create the filesystem with the final properties, store and return - S3FileSystem fileSystem = createFileSystem(uri, props); - fileSystems.put(fileSystem.getKey(), fileSystem); - return fileSystem; - } - - private void validateProperties(Properties props) { - Preconditions.checkArgument( - (props.getProperty(ACCESS_KEY) == null && props.getProperty(SECRET_KEY) == null) - || (props.getProperty(ACCESS_KEY) != null && props.getProperty(SECRET_KEY) != null), "%s and %s should both be provided or should both be omitted", - ACCESS_KEY, SECRET_KEY); - } - - private Properties getProperties(URI uri, Map env) { - Properties props = loadAmazonProperties(); - // but can be overloaded by envs vars - overloadProperties(props, env); + S3FileSystem fileSystem = createFileSystem(uri, props); + fileSystems.put(fileSystem.getKey(), fileSystem); + return fileSystem; + } + + private void validateProperties(Properties props) { + Preconditions.checkArgument( + (props.getProperty(ACCESS_KEY) == null && props.getProperty(SECRET_KEY) == null) + || (props.getProperty(ACCESS_KEY) != null && props.getProperty(SECRET_KEY) != null), "%s and %s should both be provided or should both be omitted", + ACCESS_KEY, SECRET_KEY); + } + + private Properties getProperties(URI uri, Map env) { + Properties props = loadAmazonProperties(); + // but can be overloaded by envs vars + overloadProperties(props, env); // and access key and secret key can be override - String userInfo = uri.getUserInfo(); - if (userInfo != null) { - String[] keys = userInfo.split(":"); - props.setProperty(ACCESS_KEY, keys[0]); + String userInfo = uri.getUserInfo(); + if (userInfo != null) { + String[] keys = userInfo.split(":"); + props.setProperty(ACCESS_KEY, keys[0]); if (keys.length > 1) { props.setProperty(SECRET_KEY, keys[1]); } - } - return props; - } + } + return props; + } - private String getFileSystemKey(URI uri) { - return getFileSystemKey(uri, getProperties(uri, null)); - } + private String getFileSystemKey(URI uri) { + return getFileSystemKey(uri, getProperties(uri, null)); + } /** * get the file system key represented by: the access key @ endpoint. * Example: access-key@s3.amazonaws.com * If uri host is empty then s3.amazonaws.com are used as host - * @param uri URI with the endpoint + * + * @param uri URI with the endpoint * @param props with the access key property * @return String */ - protected String getFileSystemKey(URI uri, Properties props) { + protected String getFileSystemKey(URI uri, Properties props) { // we don`t use uri.getUserInfo and uri.getHost because secret key and access key have special chars // and dont return the correct strings String uriString = uri.toString().replace("s3://", ""); String authority = null; int authoritySeparator = uriString.indexOf("@"); - if (authoritySeparator > 0){ + if (authoritySeparator > 0) { authority = uriString.substring(0, authoritySeparator); } if (authority != null) { - String host = uriString.substring(uriString.indexOf("@")+1, uriString.length()); + String host = uriString.substring(uriString.indexOf("@") + 1, uriString.length()); int lastPath = host.indexOf("/"); - if (lastPath > 0){ + if (lastPath > 0) { host = host.substring(0, lastPath); - } - else { + } else { host = Constants.S3_HOSTNAME; } return authority + "@" + host; - } - else { + } else { String accessKey = (String) props.get(ACCESS_KEY); - return (accessKey != null ? accessKey+"@" : "" ) + + return (accessKey != null ? accessKey + "@" : "") + (uri.getHost() != null ? uri.getHost() : Constants.S3_HOSTNAME); } - } - - protected void validateUri(URI uri) { - Preconditions.checkNotNull(uri, "uri is null"); - Preconditions.checkArgument(uri.getScheme().equals(getScheme()), "uri scheme must be 's3': '%s'", uri); - } - - protected void overloadProperties(Properties props, Map env) { - if (env == null) - env = new HashMap<>(); - for (String key : new String[] { ACCESS_KEY, SECRET_KEY, REQUEST_METRIC_COLLECTOR_CLASS, CONNECTION_TIMEOUT, MAX_CONNECTIONS, MAX_ERROR_RETRY, PROTOCOL, PROXY_DOMAIN, - PROXY_HOST, PROXY_PASSWORD, PROXY_PORT, PROXY_USERNAME, PROXY_WORKSTATION, SOCKET_SEND_BUFFER_SIZE_HINT, SOCKET_RECEIVE_BUFFER_SIZE_HINT, SOCKET_TIMEOUT, - USER_AGENT, AMAZON_S3_FACTORY_CLASS }){ + } + + protected void validateUri(URI uri) { + Preconditions.checkNotNull(uri, "uri is null"); + Preconditions.checkArgument(uri.getScheme().equals(getScheme()), "uri scheme must be 's3': '%s'", uri); + } + + protected void overloadProperties(Properties props, Map env) { + if (env == null) + env = new HashMap<>(); + for (String key : new String[]{ACCESS_KEY, SECRET_KEY, REQUEST_METRIC_COLLECTOR_CLASS, CONNECTION_TIMEOUT, MAX_CONNECTIONS, MAX_ERROR_RETRY, PROTOCOL, PROXY_DOMAIN, + PROXY_HOST, PROXY_PASSWORD, PROXY_PORT, PROXY_USERNAME, PROXY_WORKSTATION, SOCKET_SEND_BUFFER_SIZE_HINT, SOCKET_RECEIVE_BUFFER_SIZE_HINT, SOCKET_TIMEOUT, + USER_AGENT, AMAZON_S3_FACTORY_CLASS}) { overloadProperty(props, env, key); } - } + } /** * try to override the properties props with: *

    - *
  1. the map or if not setted:
  2. - *
  3. the system property or if not setted:
  4. - *
  5. the system vars
  6. + *
  7. the map or if not setted:
  8. + *
  9. the system property or if not setted:
  10. + *
  11. the system vars
  12. *
+ * * @param props Properties to override - * @param env Map the first option - * @param key String the key + * @param env Map the first option + * @param key String the key */ - private void overloadProperty(Properties props, Map env, String key) { + private void overloadProperty(Properties props, Map env, String key) { boolean overloaded = overloadPropertiesWithEnv(props, env, key); - if (!overloaded){ + if (!overloaded) { overloaded = overloadPropertiesWithSystemProps(props, key); } - if (!overloaded){ + if (!overloaded) { overloadPropertiesWithSystemEnv(props, key); } - } + } /** * @return true if the key are overloaded by the map parameter */ - protected boolean overloadPropertiesWithEnv(Properties props, Map env, String key){ + protected boolean overloadPropertiesWithEnv(Properties props, Map env, String key) { if (env.get(key) != null && env.get(key) instanceof String) { props.setProperty(key, (String) env.get(key)); return true; } return false; } + /** * @return true if the key are overloaded by a system property */ - protected boolean overloadPropertiesWithSystemProps(Properties props, String key){ + protected boolean overloadPropertiesWithSystemProps(Properties props, String key) { if (System.getProperty(key) != null) { props.setProperty(key, System.getProperty(key)); return true; } return false; } + /** * @return true if the key are overloaded by a system property */ - protected boolean overloadPropertiesWithSystemEnv(Properties props, String key){ + protected boolean overloadPropertiesWithSystemEnv(Properties props, String key) { if (systemGetEnv(key) != null) { props.setProperty(key, systemGetEnv(key)); return true; @@ -236,76 +237,76 @@ protected boolean overloadPropertiesWithSystemEnv(Properties props, String key){ return false; } - protected String systemGetEnv(String key){ + protected String systemGetEnv(String key) { return System.getenv(key); } - /** - * Get existing filesystem based on a combination of URI and env settings. Create new filesystem otherwise. - * @param uri URI of existing, or to be created filesystem. - * @param env environment settings. - * @return new or existing filesystem. - */ - public FileSystem getFileSystem(URI uri, Map env) { - validateUri(uri); - Properties props = getProperties(uri, env); - String key = this.getFileSystemKey(uri, props); // s3fs_access_key is part of the key here. - if (fileSystems.containsKey(key)) - return fileSystems.get(key); - return newFileSystem(uri, env); - } - - @Override - public S3FileSystem getFileSystem(URI uri) { - validateUri(uri); - String key = this.getFileSystemKey(uri); - if (fileSystems.containsKey(key)) { + /** + * Get existing filesystem based on a combination of URI and env settings. Create new filesystem otherwise. + * + * @param uri URI of existing, or to be created filesystem. + * @param env environment settings. + * @return new or existing filesystem. + */ + public FileSystem getFileSystem(URI uri, Map env) { + validateUri(uri); + Properties props = getProperties(uri, env); + String key = this.getFileSystemKey(uri, props); // s3fs_access_key is part of the key here. + if (fileSystems.containsKey(key)) return fileSystems.get(key); - } - else{ + return newFileSystem(uri, env); + } + + @Override + public S3FileSystem getFileSystem(URI uri) { + validateUri(uri); + String key = this.getFileSystemKey(uri); + if (fileSystems.containsKey(key)) { + return fileSystems.get(key); + } else { throw new FileSystemNotFoundException("S3 filesystem not yet created. Use newFileSystem() instead"); } - } + } - private S3Path toS3Path(Path path) { - Preconditions.checkArgument(path instanceof S3Path, "path must be an instance of %s", S3Path.class.getName()); - return (S3Path) path; - } + private S3Path toS3Path(Path path) { + Preconditions.checkArgument(path instanceof S3Path, "path must be an instance of %s", S3Path.class.getName()); + return (S3Path) path; + } - /** - * Deviation from spec: throws FileSystemNotFoundException if FileSystem - * hasn't yet been initialized. Call newFileSystem() first. - * Need credentials. Maybe set credentials after? how? + /** + * Deviation from spec: throws FileSystemNotFoundException if FileSystem + * hasn't yet been initialized. Call newFileSystem() first. + * Need credentials. Maybe set credentials after? how? * TODO: we can create a new one if the credentials are present by: * s3://access-key:secret-key@endpoint.com/ - */ - @Override - public Path getPath(URI uri) { - FileSystem fileSystem = getFileSystem(uri); - /** - * TODO: set as a list. one s3FileSystem by region - */ - return fileSystem.getPath(uri.getPath()); - } - - @Override - public DirectoryStream newDirectoryStream(Path dir, DirectoryStream.Filter filter) throws IOException { - final S3Path s3Path = toS3Path(dir); - return new DirectoryStream() { - @Override - public void close() throws IOException { - // nothing to do here - } - - @Override - public Iterator iterator() { - return new S3Iterator(s3Path); - } - }; - } - - @Override - public InputStream newInputStream(Path path, OpenOption... options) throws IOException { + */ + @Override + public Path getPath(URI uri) { + FileSystem fileSystem = getFileSystem(uri); + /** + * TODO: set as a list. one s3FileSystem by region + */ + return fileSystem.getPath(uri.getPath()); + } + + @Override + public DirectoryStream newDirectoryStream(Path dir, DirectoryStream.Filter filter) throws IOException { + final S3Path s3Path = toS3Path(dir); + return new DirectoryStream() { + @Override + public void close() throws IOException { + // nothing to do here + } + + @Override + public Iterator iterator() { + return new S3Iterator(s3Path); + } + }; + } + + @Override + public InputStream newInputStream(Path path, OpenOption... options) throws IOException { S3Path s3Path = toS3Path(path); String key = s3Path.getKey(); @@ -320,46 +321,45 @@ public InputStream newInputStream(Path path, OpenOption... options) throws IOExc throw new IOException(String.format("The specified path is a directory: %s", path)); return res; - } - catch (AmazonS3Exception e) { + } catch (AmazonS3Exception e) { if (e.getStatusCode() == 404) throw new NoSuchFileException(path.toString()); // otherwise throws a generic IO exception throw new IOException(String.format("Cannot access file: %s", path), e); } - } + } - @Override - public SeekableByteChannel newByteChannel(Path path, Set options, FileAttribute... attrs) throws IOException { + @Override + public SeekableByteChannel newByteChannel(Path path, Set options, FileAttribute... attrs) throws IOException { S3Path s3Path = toS3Path(path); return new S3SeekableByteChannel(s3Path, options); - } - - /** - * Deviations from spec: Does not perform atomic check-and-create. Since a - * directory is just an S3 object, all directories in the hierarchy are - * created or it already existed. - */ - @Override - public void createDirectory(Path dir, FileAttribute... attrs) throws IOException { - S3Path s3Path = toS3Path(dir); - Preconditions.checkArgument(attrs.length == 0, "attrs not yet supported: %s", ImmutableList.copyOf(attrs)); // TODO + } + + /** + * Deviations from spec: Does not perform atomic check-and-create. Since a + * directory is just an S3 object, all directories in the hierarchy are + * created or it already existed. + */ + @Override + public void createDirectory(Path dir, FileAttribute... attrs) throws IOException { + S3Path s3Path = toS3Path(dir); + Preconditions.checkArgument(attrs.length == 0, "attrs not yet supported: %s", ImmutableList.copyOf(attrs)); // TODO if (exists(s3Path)) throw new FileAlreadyExistsException(format("target already exists: %s", s3Path)); // create bucket if necesary Bucket bucket = s3Path.getFileStore().getBucket(); String bucketName = s3Path.getFileStore().name(); - if (bucket == null){ + if (bucket == null) { s3Path.getFileSystem().getClient().createBucket(bucketName); } // create the object as directory ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(0); s3Path.getFileSystem().getClient().putObject(bucketName, s3Path.getKey() + "/", new ByteArrayInputStream(new byte[0]), metadata); - } + } - @Override - public void delete(Path path) throws IOException { + @Override + public void delete(Path path) throws IOException { S3Path s3Path = toS3Path(path); if (Files.notExists(s3Path)) throw new NoSuchFileException("the path: " + this + " not exists"); @@ -371,24 +371,24 @@ public void delete(Path path) throws IOException { s3Path.getFileSystem().getClient().deleteObject(bucketName, key); // we delete the two objects (sometimes exists the key '/' and sometimes not) s3Path.getFileSystem().getClient().deleteObject(bucketName, key + "/"); - } + } + + @Override + public void copy(Path source, Path target, CopyOption... options) throws IOException { + if (isSameFile(source, target)) + return; - @Override - public void copy(Path source, Path target, CopyOption... options) throws IOException { - if (isSameFile(source, target)) - return; + S3Path s3Source = toS3Path(source); + S3Path s3Target = toS3Path(target); + // TODO: implements support for copying directories - S3Path s3Source = toS3Path(source); - S3Path s3Target = toS3Path(target); - // TODO: implements support for copying directories + Preconditions.checkArgument(!Files.isDirectory(source), "copying directories is not yet supported: %s", source); + Preconditions.checkArgument(!Files.isDirectory(target), "copying directories is not yet supported: %s", target); - Preconditions.checkArgument(!Files.isDirectory(source), "copying directories is not yet supported: %s", source); - Preconditions.checkArgument(!Files.isDirectory(target), "copying directories is not yet supported: %s", target); - - ImmutableSet actualOptions = ImmutableSet.copyOf(options); - verifySupportedOptions(EnumSet.of(StandardCopyOption.REPLACE_EXISTING), actualOptions); + ImmutableSet actualOptions = ImmutableSet.copyOf(options); + verifySupportedOptions(EnumSet.of(StandardCopyOption.REPLACE_EXISTING), actualOptions); - if (exists(s3Target) && !actualOptions.contains(StandardCopyOption.REPLACE_EXISTING)){ + if (exists(s3Target) && !actualOptions.contains(StandardCopyOption.REPLACE_EXISTING)) { throw new FileAlreadyExistsException(format("target already exists: %s", target)); } @@ -398,39 +398,39 @@ public void copy(Path source, Path target, CopyOption... options) throws IOExcep String keyTarget = s3Target.getKey(); s3Source.getFileSystem() .getClient().copyObject( - bucketNameOrigin, - keySource, - bucketNameTarget, - keyTarget); - } - - @Override - public void move(Path source, Path target, CopyOption... options) throws IOException { - if (options != null && Arrays.asList(options).contains(StandardCopyOption.ATOMIC_MOVE)) + bucketNameOrigin, + keySource, + bucketNameTarget, + keyTarget); + } + + @Override + public void move(Path source, Path target, CopyOption... options) throws IOException { + if (options != null && Arrays.asList(options).contains(StandardCopyOption.ATOMIC_MOVE)) throw new AtomicMoveNotSupportedException(source.toString(), target.toString(), "Atomic not supported"); - copy(source, target, options); - delete(source); - } - - @Override - public boolean isSameFile(Path path1, Path path2) throws IOException { - return path1.isAbsolute() && path2.isAbsolute() && path1.equals(path2); - } - - @Override - public boolean isHidden(Path path) throws IOException { - return false; - } - - @Override - public FileStore getFileStore(Path path) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void checkAccess(Path path, AccessMode... modes) throws IOException { - S3Path s3Path = toS3Path(path); - Preconditions.checkArgument(s3Path.isAbsolute(), "path must be absolute: %s", s3Path); + copy(source, target, options); + delete(source); + } + + @Override + public boolean isSameFile(Path path1, Path path2) throws IOException { + return path1.isAbsolute() && path2.isAbsolute() && path1.equals(path2); + } + + @Override + public boolean isHidden(Path path) throws IOException { + return false; + } + + @Override + public FileStore getFileStore(Path path) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void checkAccess(Path path, AccessMode... modes) throws IOException { + S3Path s3Path = toS3Path(path); + Preconditions.checkArgument(s3Path.isAbsolute(), "path must be absolute: %s", s3Path); if (modes.length == 0) { if (exists(s3Path)) return; @@ -442,24 +442,23 @@ public void checkAccess(Path path, AccessMode... modes) throws IOException { new S3AccessControlList(s3Path.getFileStore().name(), key, s3Path.getFileSystem().getClient().getObjectAcl(s3Path.getFileStore().name(), key), s3Path.getFileStore().getOwner()); accessControlList.checkAccess(modes); - } - + } - @Override - public V getFileAttributeView(Path path, Class type, LinkOption... options) { - throw new UnsupportedOperationException(); - } + @Override + public V getFileAttributeView(Path path, Class type, LinkOption... options) { + throw new UnsupportedOperationException(); + } - @Override - public A readAttributes(Path path, Class type, LinkOption... options) throws IOException { - S3Path s3Path = toS3Path(path); + @Override + public A readAttributes(Path path, Class type, LinkOption... options) throws IOException { + S3Path s3Path = toS3Path(path); if (type == BasicFileAttributes.class) { if (cache.isInTime(s3Path.getFileSystem().getCache(), s3Path.getFileAttributes())) { - A result = type.cast(s3Path.getFileAttributes()); - s3Path.setFileAttributes(null); - return result; - } else { + A result = type.cast(s3Path.getFileAttributes()); + s3Path.setFileAttributes(null); + return result; + } else { S3FileAttributes attrs = s3Utils.getS3FileAttributes(s3Path); s3Path.setFileAttributes(attrs); return type.cast(attrs); @@ -467,76 +466,96 @@ public A readAttributes(Path path, Class type } throw new UnsupportedOperationException(format("only %s supported", BasicFileAttributes.class)); - } - - @Override - public Map readAttributes(Path path, String attributes, LinkOption... options) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException { - throw new UnsupportedOperationException(); - } - - // ~~ - - /** - * Create the fileSystem - * @param uri URI - * @param props Properties - * @return S3FileSystem never null - */ - protected S3FileSystem createFileSystem(URI uri, Properties props) { - return new S3FileSystem(this, getFileSystemKey(uri, props), getAmazonS3(uri, props), uri.getHost()); - } - - protected AmazonS3 getAmazonS3(URI uri, Properties props) { - return getAmazonS3Factory(props).getAmazonS3(uri, props); - } - - protected AmazonS3Factory getAmazonS3Factory(Properties props) { - if (props.containsKey(AMAZON_S3_FACTORY_CLASS)) { - String amazonS3FactoryClass = props.getProperty(AMAZON_S3_FACTORY_CLASS); - try { - return (AmazonS3Factory) Class.forName(amazonS3FactoryClass).newInstance(); - } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException e) { - throw new S3FileSystemConfigurationException("Configuration problem, couldn't instantiate AmazonS3Factory (" + amazonS3FactoryClass + "): ", e); - } - } - return new AmazonS3ClientFactory(); - } - - /** - * find /amazon.properties in the classpath - * @return Properties amazon.properties - */ - protected Properties loadAmazonProperties() { - Properties props = new Properties(); - // http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html - // http://www.javaworld.com/javaqa/2003-08/01-qa-0808-property.html - try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("amazon.properties")) { - if (in != null) - props.load(in); - } catch (IOException e) { - // If amazon.properties can't be loaded that's ok. - } - return props; - } - - // ~~~ - - private void verifySupportedOptions(Set allowedOptions, Set actualOptions) { - Sets.SetView unsupported = difference(actualOptions, allowedOptions); - Preconditions.checkArgument(unsupported.isEmpty(), "the following options are not supported: %s", unsupported); - } - - /** - * check that the paths exists or not - * @param path S3Path - * @return true if exists - */ - boolean exists(S3Path path) { + } + + @Override + public Map readAttributes(Path path, String attributes, LinkOption... options) throws IOException { + if (attributes == null) { + throw new IllegalArgumentException("Attributes null"); + } + + if (attributes.contains(":") && !attributes.contains("basic:")) { + throw new UnsupportedOperationException(format("attributes %s are not supported, only basic are supported", attributes)); + } + + if (attributes.equals("*") || attributes.equals("basic:*")) { + BasicFileAttributes attr = readAttributes(path, BasicFileAttributes.class, options); + return AttributesUtils.fileAttributeToMap(attr); + } else if (attributes.contains(",")) { + String[] filters = attributes.split(","); + BasicFileAttributes attr = readAttributes(path, BasicFileAttributes.class, options); + return AttributesUtils.fileAttributeToMap(attr, filters); + } + + throw new UnsupportedOperationException(); + } + + @Override + public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException { + throw new UnsupportedOperationException(); + } + + // ~~ + + /** + * Create the fileSystem + * + * @param uri URI + * @param props Properties + * @return S3FileSystem never null + */ + protected S3FileSystem createFileSystem(URI uri, Properties props) { + return new S3FileSystem(this, getFileSystemKey(uri, props), getAmazonS3(uri, props), uri.getHost()); + } + + protected AmazonS3 getAmazonS3(URI uri, Properties props) { + return getAmazonS3Factory(props).getAmazonS3(uri, props); + } + + protected AmazonS3Factory getAmazonS3Factory(Properties props) { + if (props.containsKey(AMAZON_S3_FACTORY_CLASS)) { + String amazonS3FactoryClass = props.getProperty(AMAZON_S3_FACTORY_CLASS); + try { + return (AmazonS3Factory) Class.forName(amazonS3FactoryClass).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException e) { + throw new S3FileSystemConfigurationException("Configuration problem, couldn't instantiate AmazonS3Factory (" + amazonS3FactoryClass + "): ", e); + } + } + return new AmazonS3ClientFactory(); + } + + /** + * find /amazon.properties in the classpath + * + * @return Properties amazon.properties + */ + protected Properties loadAmazonProperties() { + Properties props = new Properties(); + // http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html + // http://www.javaworld.com/javaqa/2003-08/01-qa-0808-property.html + try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("amazon.properties")) { + if (in != null) + props.load(in); + } catch (IOException e) { + // If amazon.properties can't be loaded that's ok. + } + return props; + } + + // ~~~ + + private void verifySupportedOptions(Set allowedOptions, Set actualOptions) { + Sets.SetView unsupported = difference(actualOptions, allowedOptions); + Preconditions.checkArgument(unsupported.isEmpty(), "the following options are not supported: %s", unsupported); + } + + /** + * check that the paths exists or not + * + * @param path S3Path + * @return true if exists + */ + boolean exists(S3Path path) { S3Path s3Path = toS3Path(path); try { s3Utils.getS3ObjectSummary(s3Path); @@ -544,24 +563,24 @@ boolean exists(S3Path path) { } catch (NoSuchFileException e) { return false; } - } + } - public void close(S3FileSystem fileSystem) { - if(fileSystem.getKey() != null && fileSystems.containsKey(fileSystem.getKey())) - fileSystems.remove(fileSystem.getKey()); - } + public void close(S3FileSystem fileSystem) { + if (fileSystem.getKey() != null && fileSystems.containsKey(fileSystem.getKey())) + fileSystems.remove(fileSystem.getKey()); + } - public boolean isOpen(S3FileSystem s3FileSystem) { - return fileSystems.containsKey(s3FileSystem.getKey()); - } + public boolean isOpen(S3FileSystem s3FileSystem) { + return fileSystems.containsKey(s3FileSystem.getKey()); + } /** * only 4 testing */ - protected static ConcurrentMap getFilesystems() { - return fileSystems; - } + protected static ConcurrentMap getFilesystems() { + return fileSystems; + } public Cache getCache() { return cache; diff --git a/src/main/java/com/upplication/s3fs/S3Iterator.java b/src/main/java/com/upplication/s3fs/S3Iterator.java index 08df7a5..b7eb6c5 100644 --- a/src/main/java/com/upplication/s3fs/S3Iterator.java +++ b/src/main/java/com/upplication/s3fs/S3Iterator.java @@ -1,6 +1,5 @@ package com.upplication.s3fs; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -9,6 +8,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Set; + import com.amazonaws.services.s3.model.ListObjectsRequest; import com.amazonaws.services.s3.model.ObjectListing; import com.amazonaws.services.s3.model.S3ObjectSummary; @@ -23,26 +23,26 @@ */ public class S3Iterator implements Iterator { private S3FileSystem fileSystem; - private S3FileStore fileStore; - private String key; - private List items = Lists.newArrayList(); - private Set addedVirtualDirectories = Sets.newHashSet(); - private ObjectListing current; - private int cursor; // index of next element to return - private int size; - private boolean incremental; + private S3FileStore fileStore; + private String key; + private List items = Lists.newArrayList(); + private Set addedVirtualDirectories = Sets.newHashSet(); + private ObjectListing current; + private int cursor; // index of next element to return + private int size; + private boolean incremental; private S3Utils s3Utils = new S3Utils(); - public S3Iterator(S3Path path) { - this(path, false); - } + public S3Iterator(S3Path path) { + this(path, false); + } + + public S3Iterator(S3Path path, boolean incremental) { + this(path.getFileStore(), path.getKey().length() == 0 ? "" : (path.getKey() + (incremental ? "" : "/")), incremental); + } - public S3Iterator(S3Path path, boolean incremental) { - this(path.getFileStore(), path.getKey().length() == 0 ? "" : (path.getKey() + (incremental ? "" : "/")), incremental); - } - - public S3Iterator(S3FileStore fileStore, String key, boolean incremental) { + public S3Iterator(S3FileStore fileStore, String key, boolean incremental) { ListObjectsRequest listObjectsRequest = buildRequest(fileStore.name(), key, incremental); this.fileStore = fileStore; @@ -51,28 +51,28 @@ public S3Iterator(S3FileStore fileStore, String key, boolean incremental) { this.current = fileSystem.getClient().listObjects(listObjectsRequest); this.incremental = incremental; loadObjects(); - } - - @Override - public boolean hasNext() { - return cursor != size || current.isTruncated(); - } - - @Override - public S3Path next() { - if(cursor == size && current.isTruncated()) { - this.current = fileSystem.getClient().listNextBatchOfObjects(current); - loadObjects(); - } - if(cursor == size) - throw new NoSuchElementException(); - return items.get(cursor++); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } + } + + @Override + public boolean hasNext() { + return cursor != size || current.isTruncated(); + } + + @Override + public S3Path next() { + if (cursor == size && current.isTruncated()) { + this.current = fileSystem.getClient().listNextBatchOfObjects(current); + loadObjects(); + } + if (cursor == size) + throw new NoSuchElementException(); + return items.get(cursor++); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } private void loadObjects() { this.items.clear(); @@ -97,24 +97,24 @@ private void parseObjects() { } private void addParentPaths(String[] keyParts) { - if(keyParts.length <= 1) + if (keyParts.length <= 1) return; - String[] subParts = Arrays.copyOf(keyParts, keyParts.length-1); + String[] subParts = Arrays.copyOf(keyParts, keyParts.length - 1); List parentPaths = new ArrayList<>(); while (subParts.length > 0) { S3Path path = new S3Path(fileSystem, fileStore, subParts); String prefix = current.getPrefix(); String parentKey = path.getKey(); - if(prefix.length() > parentKey.length() && prefix.contains(parentKey)) + if (prefix.length() > parentKey.length() && prefix.contains(parentKey)) break; if (items.contains(path) || addedVirtualDirectories.contains(path)) { - subParts = Arrays.copyOf(subParts, subParts.length-1); + subParts = Arrays.copyOf(subParts, subParts.length - 1); continue; } parentPaths.add(path); addedVirtualDirectories.add(path); - subParts = Arrays.copyOf(subParts, subParts.length-1); + subParts = Arrays.copyOf(subParts, subParts.length - 1); } Collections.reverse(parentPaths); items.addAll(parentPaths); @@ -123,13 +123,14 @@ private void addParentPaths(String[] keyParts) { /** * add to the listPath the elements at the same level that s3Path - * @param key the uri to parse + * + * @param key the uri to parse * @param listPath List not null list to add - * @param current ObjectListing to walk + * @param current ObjectListing to walk */ private void parseObjectListing(String key, List listPath, ObjectListing current) { - for (String commonPrefix : current.getCommonPrefixes()){ - if (!commonPrefix.equals("/")){ + for (String commonPrefix : current.getCommonPrefixes()) { + if (!commonPrefix.equals("/")) { listPath.add(new S3Path(fileSystem, fileStore, fileSystem.key2Parts(commonPrefix))); } } @@ -152,10 +153,11 @@ private void parseObjectListing(String key, List listPath, ObjectListing * The current #buildRequest() get all subdirectories and her content. * This method filter the keyChild and check if is a inmediate * descendant of the keyParent parameter + * * @param keyParent String - * @param keyChild String + * @param keyChild String * @return String parsed - * or null when the keyChild and keyParent are the same and not have to be returned + * or null when the keyChild and keyParent are the same and not have to be returned */ private String getImmediateDescendant(String keyParent, String keyChild) { keyParent = deleteExtraPath(keyParent); @@ -178,13 +180,12 @@ private String deleteExtraPath(String keyChild) { } - ListObjectsRequest buildRequest(String bucketName, String key, boolean incremental) { return buildRequest(bucketName, key, incremental, null); } ListObjectsRequest buildRequest(String bucketName, String key, boolean incremental, Integer maxKeys) { - if(incremental) + if (incremental) return new ListObjectsRequest(bucketName, key, null, null, maxKeys); return new ListObjectsRequest(bucketName, key, key, "/", maxKeys); } diff --git a/src/main/java/com/upplication/s3fs/S3Path.java b/src/main/java/com/upplication/s3fs/S3Path.java index a9003f9..726c747 100644 --- a/src/main/java/com/upplication/s3fs/S3Path.java +++ b/src/main/java/com/upplication/s3fs/S3Path.java @@ -29,398 +29,398 @@ public class S3Path implements Path { - public static final String PATH_SEPARATOR = "/"; - /** - * S3FileStore which represents the Bucket this path resides in. - */ - private final S3FileStore fileStore; - /** - * Parts without bucket name. - */ - private final List parts; - /** - * actual filesystem - */ - private S3FileSystem fileSystem; + public static final String PATH_SEPARATOR = "/"; + /** + * S3FileStore which represents the Bucket this path resides in. + */ + private final S3FileStore fileStore; + /** + * Parts without bucket name. + */ + private final List parts; + /** + * actual filesystem + */ + private S3FileSystem fileSystem; /** * S3FileAttributes cache */ private S3FileAttributes fileAttributes; - /** - * path must be a string of the form "/{bucket}", "/{bucket}/{key}" or just - * "{key}". - * Examples: - *
    - *
  • "/{bucket}//{value}" good, empty key paths are ignored
  • - *
  • "//{key}" error, missing bucket
  • - *
  • "/" error, missing bucket
  • - *
- * - */ - public S3Path(S3FileSystem fileSystem, String path) { - this(fileSystem, path, ""); - } - - /** - * Build an S3Path from path segments. '/' are stripped from each segment. - * @param first should be start with a '/' and is the bucket name - * @param more directories and files - */ - public S3Path(S3FileSystem fileSystem, String first, String... more) { - String bucket = null; - List pathParts = Lists.newArrayList(Splitter.on(PATH_SEPARATOR).split(first)); - - if (first.endsWith(PATH_SEPARATOR)) - pathParts.remove(pathParts.size() - 1); - - if (first.startsWith(PATH_SEPARATOR)) { // absolute path - pathParts = pathParts.subList(1, pathParts.size()); - Preconditions.checkArgument(pathParts.size() >= 1, "path must start with bucket name"); - Preconditions.checkArgument(!pathParts.get(0).isEmpty(), "bucket name must be not empty"); - bucket = pathParts.get(0); - pathParts = pathParts.subList(1, pathParts.size()); - } - - List moreSplitted = Lists.newArrayList(); - for (String part : more) - moreSplitted.addAll(Lists.newArrayList(Splitter.on(PATH_SEPARATOR).split(part))); - - pathParts.addAll(moreSplitted); - if (bucket != null) - this.fileStore = new S3FileStore(fileSystem, bucket); - else - this.fileStore = null; - this.parts = KeyParts.parse(pathParts); - this.fileSystem = fileSystem; - } - - S3Path(S3FileSystem fileSystem, S3FileStore fileStore, Iterable keys) { - this.fileStore = fileStore; - this.parts = KeyParts.parse(keys); - this.fileSystem = fileSystem; - } - - S3Path(S3FileSystem fileSystem, S3FileStore fileStore, String... keys) { - this.fileStore = fileStore; - this.parts = KeyParts.parse(keys); - this.fileSystem = fileSystem; - } - - public S3FileStore getFileStore() { - return fileStore; - } - - /** - * key for amazon without final slash. - * note: the final slash need to be added to save a directory (Amazon s3 spec) - */ - public String getKey() { - return fileSystem.parts2Key(parts); - } - - @Override - public S3FileSystem getFileSystem() { - return this.fileSystem; - } - - @Override - public boolean isAbsolute() { - return fileStore != null; - } - - @Override - public Path getRoot() { - if (isAbsolute()) { - return new S3Path(fileSystem, fileStore, ImmutableList. of()); - } - - return null; - } - - @Override - public Path getFileName() { - if (!parts.isEmpty()) - return new S3Path(fileSystem, null, parts.subList(parts.size() - 1, parts.size())); - return new S3Path(fileSystem, (S3FileStore) null, fileStore != null ? fileStore.name() : null); // bucket dont have fileName - } - - @Override - public Path getParent() { - // bucket is not present in the parts - if (parts.isEmpty()) { - return null; - } - - if (parts.size() == 1 && fileStore == null) { - return null; - } - - return new S3Path(fileSystem, fileStore, parts.subList(0, parts.size() - 1)); - } - - @Override - public int getNameCount() { - return parts.size(); - } - - @Override - public Path getName(int index) { - return new S3Path(fileSystem, null, parts.subList(index, index + 1)); - } - - @Override - public Path subpath(int beginIndex, int endIndex) { - return new S3Path(fileSystem, null, parts.subList(beginIndex, endIndex)); - } - - @Override - public boolean startsWith(Path other) { - - if (other.getNameCount() > this.getNameCount()) { - return false; - } - - if (!(other instanceof S3Path)) { - return false; - } - - S3Path path = (S3Path) other; - - if (path.parts.size() == 0 && path.fileStore == null && (this.parts.size() != 0 || this.fileStore != null)) { - return false; - } - - if ((path.getFileStore() != null && !path.getFileStore().equals(this.getFileStore())) || (path.getFileStore() == null && this.getFileStore() != null)) { - return false; - } - - for (int i = 0; i < path.parts.size(); i++) { - if (!path.parts.get(i).equals(this.parts.get(i))) { - return false; - } - } - return true; - } - - @Override - public boolean startsWith(String path) { - S3Path other = new S3Path(this.fileSystem, path); - return this.startsWith(other); - } - - @Override - public boolean endsWith(Path other) { - if (other.getNameCount() > this.getNameCount()) { - return false; - } - // empty - if (other.getNameCount() == 0 && this.getNameCount() != 0) { - return false; - } - - if (!(other instanceof S3Path)) { - return false; - } - - S3Path path = (S3Path) other; - - if ((path.getFileStore() != null && !path.getFileStore().equals(this.getFileStore())) || (path.getFileStore() != null && this.getFileStore() == null)) { - return false; - } - - // check subkeys - - int i = path.parts.size() - 1; - int j = this.parts.size() - 1; - for (; i >= 0 && j >= 0;) { - - if (!path.parts.get(i).equals(this.parts.get(j))) { - return false; - } - i--; - j--; - } - return true; - } - - @Override - public boolean endsWith(String other) { - return this.endsWith(new S3Path(this.fileSystem, other)); - } - - @Override - public Path normalize() { - return this; - } - - @Override - public Path resolve(Path other) { - if (other.isAbsolute()) { - Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s", S3Path.class.getName()); - return other; - } - - ImmutableList.Builder builder = ImmutableList.builder(); - for (int i = 0; i < other.getNameCount(); i++) - builder.add(other.getName(i).toString()); - ImmutableList otherParts = builder.build(); - if (otherParts.isEmpty()) // other is relative and empty - return this; - - return new S3Path(fileSystem, fileStore, concat(parts, otherParts)); - } - - @Override - public Path resolve(String other) { - return resolve(new S3Path(this.getFileSystem(), other)); - } - - @Override - public Path resolveSibling(Path other) { - Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s", S3Path.class.getName()); - - S3Path s3Path = (S3Path) other; - - Path parent = getParent(); - - if (parent == null || s3Path.isAbsolute()) { - return s3Path; - } - - if (s3Path.parts.isEmpty()) { // other is relative and empty - return parent; - } - - return new S3Path(fileSystem, fileStore, concat(parts.subList(0, parts.size() - 1), s3Path.parts)); - } - - @Override - public Path resolveSibling(String other) { - return resolveSibling(new S3Path(this.getFileSystem(), other)); - } - - @Override - public Path relativize(Path other) { - Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s", S3Path.class.getName()); - S3Path s3Path = (S3Path) other; - - if (this.equals(other)) { - return new S3Path(this.getFileSystem(), ""); - } - - Preconditions.checkArgument(isAbsolute(), "Path is already relative: %s", this); - Preconditions.checkArgument(s3Path.isAbsolute(), "Cannot relativize against a relative path: %s", s3Path); - Preconditions.checkArgument(fileStore.equals(s3Path.getFileStore()), "Cannot relativize paths with different buckets: '%s', '%s'", this, other); - Preconditions.checkArgument(parts.size() <= s3Path.parts.size(), "Cannot relativize against a parent path: '%s', '%s'", this, other); - - int startPart = 0; - for (int i = 0; i < this.parts.size(); i++) - if (this.parts.get(i).equals(s3Path.parts.get(i))) - startPart++; - return new S3Path(fileSystem, null, s3Path.parts.subList(startPart, s3Path.parts.size())); - } - - @Override - public URI toUri() { - if (fileStore == null) - return null; - - StringBuilder builder = new StringBuilder(); - builder.append("s3://"); + /** + * path must be a string of the form "/{bucket}", "/{bucket}/{key}" or just + * "{key}". + * Examples: + *
    + *
  • "/{bucket}//{value}" good, empty key paths are ignored
  • + *
  • "//{key}" error, missing bucket
  • + *
  • "/" error, missing bucket
  • + *
+ */ + public S3Path(S3FileSystem fileSystem, String path) { + this(fileSystem, path, ""); + } + + /** + * Build an S3Path from path segments. '/' are stripped from each segment. + * + * @param first should be start with a '/' and is the bucket name + * @param more directories and files + */ + public S3Path(S3FileSystem fileSystem, String first, String... more) { + String bucket = null; + List pathParts = Lists.newArrayList(Splitter.on(PATH_SEPARATOR).split(first)); + + if (first.endsWith(PATH_SEPARATOR)) + pathParts.remove(pathParts.size() - 1); + + if (first.startsWith(PATH_SEPARATOR)) { // absolute path + pathParts = pathParts.subList(1, pathParts.size()); + Preconditions.checkArgument(pathParts.size() >= 1, "path must start with bucket name"); + Preconditions.checkArgument(!pathParts.get(0).isEmpty(), "bucket name must be not empty"); + bucket = pathParts.get(0); + pathParts = pathParts.subList(1, pathParts.size()); + } + + List moreSplitted = Lists.newArrayList(); + for (String part : more) + moreSplitted.addAll(Lists.newArrayList(Splitter.on(PATH_SEPARATOR).split(part))); + + pathParts.addAll(moreSplitted); + if (bucket != null) + this.fileStore = new S3FileStore(fileSystem, bucket); + else + this.fileStore = null; + this.parts = KeyParts.parse(pathParts); + this.fileSystem = fileSystem; + } + + S3Path(S3FileSystem fileSystem, S3FileStore fileStore, Iterable keys) { + this.fileStore = fileStore; + this.parts = KeyParts.parse(keys); + this.fileSystem = fileSystem; + } + + S3Path(S3FileSystem fileSystem, S3FileStore fileStore, String... keys) { + this.fileStore = fileStore; + this.parts = KeyParts.parse(keys); + this.fileSystem = fileSystem; + } + + public S3FileStore getFileStore() { + return fileStore; + } + + /** + * key for amazon without final slash. + * note: the final slash need to be added to save a directory (Amazon s3 spec) + */ + public String getKey() { + return fileSystem.parts2Key(parts); + } + + @Override + public S3FileSystem getFileSystem() { + return this.fileSystem; + } + + @Override + public boolean isAbsolute() { + return fileStore != null; + } + + @Override + public Path getRoot() { + if (isAbsolute()) { + return new S3Path(fileSystem, fileStore, ImmutableList.of()); + } + + return null; + } + + @Override + public Path getFileName() { + if (!parts.isEmpty()) + return new S3Path(fileSystem, null, parts.subList(parts.size() - 1, parts.size())); + return new S3Path(fileSystem, (S3FileStore) null, fileStore != null ? fileStore.name() : null); // bucket dont have fileName + } + + @Override + public Path getParent() { + // bucket is not present in the parts + if (parts.isEmpty()) { + return null; + } + + if (parts.size() == 1 && fileStore == null) { + return null; + } + + return new S3Path(fileSystem, fileStore, parts.subList(0, parts.size() - 1)); + } + + @Override + public int getNameCount() { + return parts.size(); + } + + @Override + public Path getName(int index) { + return new S3Path(fileSystem, null, parts.subList(index, index + 1)); + } + + @Override + public Path subpath(int beginIndex, int endIndex) { + return new S3Path(fileSystem, null, parts.subList(beginIndex, endIndex)); + } + + @Override + public boolean startsWith(Path other) { + + if (other.getNameCount() > this.getNameCount()) { + return false; + } + + if (!(other instanceof S3Path)) { + return false; + } + + S3Path path = (S3Path) other; + + if (path.parts.size() == 0 && path.fileStore == null && (this.parts.size() != 0 || this.fileStore != null)) { + return false; + } + + if ((path.getFileStore() != null && !path.getFileStore().equals(this.getFileStore())) || (path.getFileStore() == null && this.getFileStore() != null)) { + return false; + } + + for (int i = 0; i < path.parts.size(); i++) { + if (!path.parts.get(i).equals(this.parts.get(i))) { + return false; + } + } + return true; + } + + @Override + public boolean startsWith(String path) { + S3Path other = new S3Path(this.fileSystem, path); + return this.startsWith(other); + } + + @Override + public boolean endsWith(Path other) { + if (other.getNameCount() > this.getNameCount()) { + return false; + } + // empty + if (other.getNameCount() == 0 && this.getNameCount() != 0) { + return false; + } + + if (!(other instanceof S3Path)) { + return false; + } + + S3Path path = (S3Path) other; + + if ((path.getFileStore() != null && !path.getFileStore().equals(this.getFileStore())) || (path.getFileStore() != null && this.getFileStore() == null)) { + return false; + } + + // check subkeys + + int i = path.parts.size() - 1; + int j = this.parts.size() - 1; + for (; i >= 0 && j >= 0; ) { + + if (!path.parts.get(i).equals(this.parts.get(j))) { + return false; + } + i--; + j--; + } + return true; + } + + @Override + public boolean endsWith(String other) { + return this.endsWith(new S3Path(this.fileSystem, other)); + } + + @Override + public Path normalize() { + return this; + } + + @Override + public Path resolve(Path other) { + if (other.isAbsolute()) { + Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s", S3Path.class.getName()); + return other; + } + + ImmutableList.Builder builder = ImmutableList.builder(); + for (int i = 0; i < other.getNameCount(); i++) + builder.add(other.getName(i).toString()); + ImmutableList otherParts = builder.build(); + if (otherParts.isEmpty()) // other is relative and empty + return this; + + return new S3Path(fileSystem, fileStore, concat(parts, otherParts)); + } + + @Override + public Path resolve(String other) { + return resolve(new S3Path(this.getFileSystem(), other)); + } + + @Override + public Path resolveSibling(Path other) { + Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s", S3Path.class.getName()); + + S3Path s3Path = (S3Path) other; + + Path parent = getParent(); + + if (parent == null || s3Path.isAbsolute()) { + return s3Path; + } + + if (s3Path.parts.isEmpty()) { // other is relative and empty + return parent; + } + + return new S3Path(fileSystem, fileStore, concat(parts.subList(0, parts.size() - 1), s3Path.parts)); + } + + @Override + public Path resolveSibling(String other) { + return resolveSibling(new S3Path(this.getFileSystem(), other)); + } + + @Override + public Path relativize(Path other) { + Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s", S3Path.class.getName()); + S3Path s3Path = (S3Path) other; + + if (this.equals(other)) { + return new S3Path(this.getFileSystem(), ""); + } + + Preconditions.checkArgument(isAbsolute(), "Path is already relative: %s", this); + Preconditions.checkArgument(s3Path.isAbsolute(), "Cannot relativize against a relative path: %s", s3Path); + Preconditions.checkArgument(fileStore.equals(s3Path.getFileStore()), "Cannot relativize paths with different buckets: '%s', '%s'", this, other); + Preconditions.checkArgument(parts.size() <= s3Path.parts.size(), "Cannot relativize against a parent path: '%s', '%s'", this, other); + + int startPart = 0; + for (int i = 0; i < this.parts.size(); i++) + if (this.parts.get(i).equals(s3Path.parts.get(i))) + startPart++; + return new S3Path(fileSystem, null, s3Path.parts.subList(startPart, s3Path.parts.size())); + } + + @Override + public URI toUri() { + if (fileStore == null) + return null; + + StringBuilder builder = new StringBuilder(); + builder.append("s3://"); builder.append(fileSystem.getKey()); - builder.append("/"); - builder.append(fileStore.name()); - builder.append(PATH_SEPARATOR); - builder.append(Joiner.on(PATH_SEPARATOR).join(parts)); - return URI.create(builder.toString()); - } - - @Override - public Path toAbsolutePath() { - if (isAbsolute()) { - return this; - } - - throw new IllegalStateException(format("Relative path cannot be made absolute: %s", this)); - } - - @Override - public Path toRealPath(LinkOption... options) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public File toFile() { - throw new UnsupportedOperationException(); - } - - @Override - public WatchKey register(WatchService watcher, WatchEvent.Kind[] events, WatchEvent.Modifier... modifiers) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public WatchKey register(WatchService watcher, WatchEvent.Kind... events) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public Iterator iterator() { - ImmutableList.Builder builder = ImmutableList.builder(); - - for (String part : parts) { - builder.add(new S3Path(fileSystem, null, ImmutableList.of(part))); - } - - return builder.build().iterator(); - } - - @Override - public int compareTo(Path other) { - return toString().compareTo(other.toString()); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - if (isAbsolute()) { - builder.append(PATH_SEPARATOR); - builder.append(fileStore.name()); - builder.append(PATH_SEPARATOR); - } - List parts2 = parts; - for (Iterator iterator = parts2.iterator(); iterator.hasNext();) { - String part = iterator.next(); - builder.append(part); - if(iterator.hasNext()) - builder.append(PATH_SEPARATOR); - } - return builder.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - S3Path paths = (S3Path) o; - if (fileStore != null ? !fileStore.equals(paths.fileStore) : paths.fileStore != null) - return false; - if (!parts.equals(paths.parts)) - return false; - return true; - } - - @Override - public int hashCode() { - int result = fileStore != null ? fileStore.name().hashCode() : 0; - result = 31 * result + parts.hashCode(); - return result; - } + builder.append("/"); + builder.append(fileStore.name()); + builder.append(PATH_SEPARATOR); + builder.append(Joiner.on(PATH_SEPARATOR).join(parts)); + return URI.create(builder.toString()); + } + + @Override + public Path toAbsolutePath() { + if (isAbsolute()) { + return this; + } + + throw new IllegalStateException(format("Relative path cannot be made absolute: %s", this)); + } + + @Override + public Path toRealPath(LinkOption... options) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public File toFile() { + throw new UnsupportedOperationException(); + } + + @Override + public WatchKey register(WatchService watcher, WatchEvent.Kind[] events, WatchEvent.Modifier... modifiers) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public WatchKey register(WatchService watcher, WatchEvent.Kind... events) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public Iterator iterator() { + ImmutableList.Builder builder = ImmutableList.builder(); + + for (String part : parts) { + builder.add(new S3Path(fileSystem, null, ImmutableList.of(part))); + } + + return builder.build().iterator(); + } + + @Override + public int compareTo(Path other) { + return toString().compareTo(other.toString()); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + if (isAbsolute()) { + builder.append(PATH_SEPARATOR); + builder.append(fileStore.name()); + builder.append(PATH_SEPARATOR); + } + List parts2 = parts; + for (Iterator iterator = parts2.iterator(); iterator.hasNext(); ) { + String part = iterator.next(); + builder.append(part); + if (iterator.hasNext()) + builder.append(PATH_SEPARATOR); + } + return builder.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + S3Path paths = (S3Path) o; + if (fileStore != null ? !fileStore.equals(paths.fileStore) : paths.fileStore != null) + return false; + if (!parts.equals(paths.parts)) + return false; + return true; + } + + @Override + public int hashCode() { + int result = fileStore != null ? fileStore.name().hashCode() : 0; + result = 31 * result + parts.hashCode(); + return result; + } public S3FileAttributes getFileAttributes() { return fileAttributes; @@ -430,45 +430,45 @@ public void setFileAttributes(S3FileAttributes fileAttributes) { this.fileAttributes = fileAttributes; } - // ~ helpers methods - - private static Function strip(final String... strs) { - return new Function() { - @Override - public String apply(String input) { - String res = input; - if(res != null) - for (String str : strs) - res = res.replace(str, ""); - return res; - } - }; - } - - private static Predicate notEmpty() { - return new Predicate() { - @Override - public boolean apply(@Nullable String input) { - return input != null && !input.isEmpty(); - } - }; - } + // ~ helpers methods + + private static Function strip(final String... strs) { + return new Function() { + @Override + public String apply(String input) { + String res = input; + if (res != null) + for (String str : strs) + res = res.replace(str, ""); + return res; + } + }; + } + + private static Predicate notEmpty() { + return new Predicate() { + @Override + public boolean apply(@Nullable String input) { + return input != null && !input.isEmpty(); + } + }; + } /* * delete redundant "/" and empty parts */ - private abstract static class KeyParts { - private static ImmutableList parse(String[] parts) { - return ImmutableList.copyOf(filter(transform(Arrays.asList(parts), strip("/")), notEmpty())); - } - - private static ImmutableList parse(List parts) { - return ImmutableList.copyOf(filter(transform(parts, strip("/")), notEmpty())); - } - - private static ImmutableList parse(Iterable parts) { - return ImmutableList.copyOf(filter(transform(parts, strip("/")), notEmpty())); - } - } + private abstract static class KeyParts { + private static ImmutableList parse(String[] parts) { + return ImmutableList.copyOf(filter(transform(Arrays.asList(parts), strip("/")), notEmpty())); + } + + private static ImmutableList parse(List parts) { + return ImmutableList.copyOf(filter(transform(parts, strip("/")), notEmpty())); + } + + private static ImmutableList parse(Iterable parts) { + return ImmutableList.copyOf(filter(transform(parts, strip("/")), notEmpty())); + } + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/S3SeekableByteChannel.java b/src/main/java/com/upplication/s3fs/S3SeekableByteChannel.java index 8512b67..127f746 100644 --- a/src/main/java/com/upplication/s3fs/S3SeekableByteChannel.java +++ b/src/main/java/com/upplication/s3fs/S3SeekableByteChannel.java @@ -24,79 +24,81 @@ public class S3SeekableByteChannel implements SeekableByteChannel { - private S3Path path; - private Set options; - private SeekableByteChannel seekable; - private Path tempFile; + private S3Path path; + private Set options; + private SeekableByteChannel seekable; + private Path tempFile; /** * Open or creates a file, returning a seekable byte channel - * @param path the path open or create + * + * @param path the path open or create * @param options options specifying how the file is opened * @throws IOException if an I/O error occurs */ - public S3SeekableByteChannel(S3Path path, Set options) throws IOException { - this.path = path; - this.options = Collections.unmodifiableSet(new HashSet<>(options)); - String key = path.getKey(); - boolean existed = path.getFileSystem().provider().exists(path); + public S3SeekableByteChannel(S3Path path, Set options) throws IOException { + this.path = path; + this.options = Collections.unmodifiableSet(new HashSet<>(options)); + String key = path.getKey(); + boolean existed = path.getFileSystem().provider().exists(path); if (existed && this.options.contains(StandardOpenOption.CREATE_NEW)) throw new FileAlreadyExistsException(format("target already exists: %s", path)); - tempFile = Files.createTempFile("temp-s3-", key.replaceAll("/", "_")); - boolean removeTempFile = true; - try { - if (existed) { - try (S3Object object = path.getFileSystem() - .getClient() - .getObject(path.getFileStore().getBucket().getName(), key)) { - Files.copy(object.getObjectContent(), tempFile, StandardCopyOption.REPLACE_EXISTING); - } - } - - Set seekOptions = new HashSet<>(this.options); - seekOptions.remove(StandardOpenOption.CREATE_NEW); - seekable = Files.newByteChannel(tempFile, seekOptions); - removeTempFile = false; - } finally { - if (removeTempFile) { - Files.deleteIfExists(tempFile); - } - } - } - - @Override - public boolean isOpen() { - return seekable.isOpen(); - } - - @Override - public void close() throws IOException { - try { - if (!seekable.isOpen()) - return; - - seekable.close(); - - if (options.contains(StandardOpenOption.DELETE_ON_CLOSE)) { + tempFile = Files.createTempFile("temp-s3-", key.replaceAll("/", "_")); + boolean removeTempFile = true; + try { + if (existed) { + try (S3Object object = path.getFileSystem() + .getClient() + .getObject(path.getFileStore().getBucket().getName(), key)) { + Files.copy(object.getObjectContent(), tempFile, StandardCopyOption.REPLACE_EXISTING); + } + } + + Set seekOptions = new HashSet<>(this.options); + seekOptions.remove(StandardOpenOption.CREATE_NEW); + seekable = Files.newByteChannel(tempFile, seekOptions); + removeTempFile = false; + } finally { + if (removeTempFile) { + Files.deleteIfExists(tempFile); + } + } + } + + @Override + public boolean isOpen() { + return seekable.isOpen(); + } + + @Override + public void close() throws IOException { + try { + if (!seekable.isOpen()) + return; + + seekable.close(); + + if (options.contains(StandardOpenOption.DELETE_ON_CLOSE)) { path.getFileSystem().provider().delete(path); - return; - } + return; + } - if (options.contains(StandardOpenOption.READ) && options.size() == 1) { - return; - } + if (options.contains(StandardOpenOption.READ) && options.size() == 1) { + return; + } sync(); - } finally { - Files.deleteIfExists(tempFile); - } - } + } finally { + Files.deleteIfExists(tempFile); + } + } /** * try to sync the temp file with the remote s3 path. + * * @throws IOException */ protected void sync() throws IOException { @@ -111,33 +113,33 @@ protected void sync() throws IOException { } } - @Override - public int write(ByteBuffer src) throws IOException { - return seekable.write(src); - } - - @Override - public SeekableByteChannel truncate(long size) throws IOException { - return seekable.truncate(size); - } - - @Override - public long size() throws IOException { - return seekable.size(); - } - - @Override - public int read(ByteBuffer dst) throws IOException { - return seekable.read(dst); - } - - @Override - public SeekableByteChannel position(long newPosition) throws IOException { - return seekable.position(newPosition); - } - - @Override - public long position() throws IOException { - return seekable.position(); - } + @Override + public int write(ByteBuffer src) throws IOException { + return seekable.write(src); + } + + @Override + public SeekableByteChannel truncate(long size) throws IOException { + return seekable.truncate(size); + } + + @Override + public long size() throws IOException { + return seekable.size(); + } + + @Override + public int read(ByteBuffer dst) throws IOException { + return seekable.read(dst); + } + + @Override + public SeekableByteChannel position(long newPosition) throws IOException { + return seekable.position(newPosition); + } + + @Override + public long position() throws IOException { + return seekable.position(); + } } \ No newline at end of file diff --git a/src/main/java/com/upplication/s3fs/util/AttributesUtils.java b/src/main/java/com/upplication/s3fs/util/AttributesUtils.java new file mode 100644 index 0000000..fb7764e --- /dev/null +++ b/src/main/java/com/upplication/s3fs/util/AttributesUtils.java @@ -0,0 +1,81 @@ +package com.upplication.s3fs.util; + + +import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashMap; +import java.util.Map; + +/** + * Utilities to help transforming BasicFileAttributes to Map + */ +public abstract class AttributesUtils { + + /** + * Given a BasicFileAttributes not null then return a Map + * with the keys as the fields of the BasicFileAttributes and the values + * with the content of the fields + * + * @param attr BasicFileAttributes + * @return Map String Object never null + */ + public static Map fileAttributeToMap(BasicFileAttributes attr) { + Map result = new HashMap<>(); + result.put("creationTime", attr.creationTime()); + result.put("fileKey", attr.fileKey()); + result.put("isDirectory", attr.isDirectory()); + result.put("isOther", attr.isOther()); + result.put("isRegularFile", attr.isRegularFile()); + result.put("isSymbolicLink", attr.isSymbolicLink()); + result.put("lastAccessTime", attr.lastAccessTime()); + result.put("lastModifiedTime", attr.lastModifiedTime()); + result.put("size", attr.size()); + return result; + } + + /** + * transform the BasicFileAttributes to Map filtering by the keys + * given in the filters param + * + * @param attr BasicFileAttributes not null to tranform to map + * @param filters String[] filters + * @return Map String Object with the same keys as the filters + */ + public static Map fileAttributeToMap(BasicFileAttributes attr, String[] filters) { + Map result = new HashMap<>(); + + for (String filter : filters) { + filter = filter.replace("basic:", ""); + switch (filter) { + case "creationTime": + result.put("creationTime", attr.creationTime()); + break; + case "fileKey": + result.put("fileKey", attr.fileKey()); + break; + case "isDirectory": + result.put("isDirectory", attr.isDirectory()); + break; + case "isOther": + result.put("isOther", attr.isOther()); + break; + case "isRegularFile": + result.put("isRegularFile", attr.isRegularFile()); + break; + case "isSymbolicLink": + result.put("isSymbolicLink", attr.isSymbolicLink()); + break; + case "lastAccessTime": + result.put("lastAccessTime", attr.lastAccessTime()); + break; + case "lastModifiedTime": + result.put("lastModifiedTime", attr.lastModifiedTime()); + break; + case "size": + result.put("size", attr.size()); + break; + } + } + + return result; + } +} diff --git a/src/main/java/com/upplication/s3fs/util/Cache.java b/src/main/java/com/upplication/s3fs/util/Cache.java index e3f77cf..4fe8e3f 100644 --- a/src/main/java/com/upplication/s3fs/util/Cache.java +++ b/src/main/java/com/upplication/s3fs/util/Cache.java @@ -6,11 +6,12 @@ public class Cache { /** * check if the cache of the S3FileAttributes is still valid - * @param cache int cache time of the fileAttributes in milliseconds + * + * @param cache int cache time of the fileAttributes in milliseconds * @param fileAttributes S3FileAttributes to check if is still valid, can be null * @return true or false, if cache are -1 and fileAttributes are not null then always return true */ - public boolean isInTime(int cache, S3FileAttributes fileAttributes){ + public boolean isInTime(int cache, S3FileAttributes fileAttributes) { if (fileAttributes == null) { return false; } @@ -22,7 +23,7 @@ public boolean isInTime(int cache, S3FileAttributes fileAttributes){ return getCurrentTime() - cache <= fileAttributes.getCacheCreated(); } - public long getCurrentTime(){ + public long getCurrentTime() { return System.currentTimeMillis(); } } diff --git a/src/main/java/com/upplication/s3fs/util/IOUtils.java b/src/main/java/com/upplication/s3fs/util/IOUtils.java index ac106a4..1dfa91f 100644 --- a/src/main/java/com/upplication/s3fs/util/IOUtils.java +++ b/src/main/java/com/upplication/s3fs/util/IOUtils.java @@ -10,6 +10,7 @@ public abstract class IOUtils { /** * get the stream content and return as a byte array + * * @param is InputStream * @return byte array * @throws IOException if the stream is closed diff --git a/src/main/java/com/upplication/s3fs/util/S3Utils.java b/src/main/java/com/upplication/s3fs/util/S3Utils.java index a84affd..e618f90 100644 --- a/src/main/java/com/upplication/s3fs/util/S3Utils.java +++ b/src/main/java/com/upplication/s3fs/util/S3Utils.java @@ -16,6 +16,7 @@ public class S3Utils { /** * Get the {@link S3ObjectSummary} that represent this Path or her first child if this path not exists + * * @param s3Path {@link S3Path} * @return {@link S3ObjectSummary} * @throws NoSuchFileException if not found the path and any child @@ -57,6 +58,7 @@ public S3ObjectSummary getS3ObjectSummary(S3Path s3Path) throws NoSuchFileExcept /** * getS3FileAttributes for the s3Path + * * @param s3Path S3Path mandatory not null * @return S3FileAttributes */ @@ -67,16 +69,17 @@ public S3FileAttributes getS3FileAttributes(S3Path s3Path) throws NoSuchFileExce /** * convert S3ObjectSummary to S3FileAttributes + * * @param objectSummary S3ObjectSummary mandatory not null, the real objectSummary with * exactly the same key than the key param or the immediate descendant * if it is a virtual directory - * @param key String the real key that can be exactly equal than the objectSummary or + * @param key String the real key that can be exactly equal than the objectSummary or * @return S3FileAttributes */ public S3FileAttributes toS3FileAttributes(S3ObjectSummary objectSummary, String key) { // parse the data to BasicFileAttributes. FileTime lastModifiedTime = null; - if (objectSummary.getLastModified() != null){ + if (objectSummary.getLastModified() != null) { lastModifiedTime = FileTime.from(objectSummary.getLastModified().getTime(), TimeUnit.MILLISECONDS); } long size = objectSummary.getSize(); @@ -90,8 +93,7 @@ public S3FileAttributes toS3FileAttributes(S3ObjectSummary objectSummary, String } else if (key.isEmpty()) { // is a bucket (no key) directory = true; resolvedKey = "/"; - } - else if (!resolvedKey.equals(key) && resolvedKey.startsWith(key)) { // is a directory but not exists at amazon s3 + } else if (!resolvedKey.equals(key) && resolvedKey.startsWith(key)) { // is a directory but not exists at amazon s3 directory = true; // no metadata, we fake one size = 0; diff --git a/src/test/java/com/upplication/s3fs/AmazonS3ClientFactoryTest.java b/src/test/java/com/upplication/s3fs/AmazonS3ClientFactoryTest.java index 524ace5..939f292 100644 --- a/src/test/java/com/upplication/s3fs/AmazonS3ClientFactoryTest.java +++ b/src/test/java/com/upplication/s3fs/AmazonS3ClientFactoryTest.java @@ -35,130 +35,130 @@ import com.upplication.s3fs.util.ExposingAmazonS3ClientFactory; public class AmazonS3ClientFactoryTest { - @Test - public void neverTrustTheDefaults() { - AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); - Properties props = new Properties(); - props.setProperty(ACCESS_KEY, "some_access_key"); - props.setProperty(SECRET_KEY, "super_secret_key"); - props.setProperty(REQUEST_METRIC_COLLECTOR_CLASS, "com.upplication.s3fs.util.NoOpRequestMetricCollector"); - props.setProperty(CONNECTION_TIMEOUT, "10"); - props.setProperty(MAX_CONNECTIONS, "50"); - props.setProperty(MAX_ERROR_RETRY, "3"); - props.setProperty(PROTOCOL, "HTTP"); - props.setProperty(PROXY_DOMAIN, "localhost"); - props.setProperty(PROXY_HOST, "127.0.0.1"); - props.setProperty(PROXY_PASSWORD, "proxy_password"); - props.setProperty(PROXY_PORT, "12345"); - props.setProperty(PROXY_USERNAME, "proxy_username"); - props.setProperty(PROXY_WORKSTATION, "what.does.this.do.localhost"); - props.setProperty(SOCKET_SEND_BUFFER_SIZE_HINT, "48000"); - props.setProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT, "49000"); - props.setProperty(SOCKET_TIMEOUT, "30"); - props.setProperty(USER_AGENT, "I-am-Groot"); - ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); - AWSCredentialsProvider credentialsProvider = client.getAWSCredentialsProvider(); - AWSCredentials credentials = credentialsProvider.getCredentials(); - assertEquals("some_access_key", credentials.getAWSAccessKeyId()); - assertEquals("super_secret_key", credentials.getAWSSecretKey()); - assertEquals("class com.upplication.s3fs.util.NoOpRequestMetricCollector", client.getRequestMetricsCollector().getClass().toString()); - ClientConfiguration clientConfiguration = client.getClientConfiguration(); - assertEquals(10, clientConfiguration.getConnectionTimeout()); - assertEquals(50, clientConfiguration.getMaxConnections()); - assertEquals(3, clientConfiguration.getMaxErrorRetry()); - assertEquals(Protocol.HTTP, clientConfiguration.getProtocol()); - assertEquals("localhost", clientConfiguration.getProxyDomain()); - assertEquals("127.0.0.1", clientConfiguration.getProxyHost()); - assertEquals("proxy_password", clientConfiguration.getProxyPassword()); - assertEquals(12345, clientConfiguration.getProxyPort()); - assertEquals("proxy_username", clientConfiguration.getProxyUsername()); - assertEquals("what.does.this.do.localhost", clientConfiguration.getProxyWorkstation()); - assertEquals(48000, clientConfiguration.getSocketBufferSizeHints()[0]); - assertEquals(49000, clientConfiguration.getSocketBufferSizeHints()[1]); - assertEquals(30, clientConfiguration.getSocketTimeout()); - assertEquals("I-am-Groot", clientConfiguration.getUserAgent()); - } + @Test + public void neverTrustTheDefaults() { + AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); + Properties props = new Properties(); + props.setProperty(ACCESS_KEY, "some_access_key"); + props.setProperty(SECRET_KEY, "super_secret_key"); + props.setProperty(REQUEST_METRIC_COLLECTOR_CLASS, "com.upplication.s3fs.util.NoOpRequestMetricCollector"); + props.setProperty(CONNECTION_TIMEOUT, "10"); + props.setProperty(MAX_CONNECTIONS, "50"); + props.setProperty(MAX_ERROR_RETRY, "3"); + props.setProperty(PROTOCOL, "HTTP"); + props.setProperty(PROXY_DOMAIN, "localhost"); + props.setProperty(PROXY_HOST, "127.0.0.1"); + props.setProperty(PROXY_PASSWORD, "proxy_password"); + props.setProperty(PROXY_PORT, "12345"); + props.setProperty(PROXY_USERNAME, "proxy_username"); + props.setProperty(PROXY_WORKSTATION, "what.does.this.do.localhost"); + props.setProperty(SOCKET_SEND_BUFFER_SIZE_HINT, "48000"); + props.setProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT, "49000"); + props.setProperty(SOCKET_TIMEOUT, "30"); + props.setProperty(USER_AGENT, "I-am-Groot"); + ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); + AWSCredentialsProvider credentialsProvider = client.getAWSCredentialsProvider(); + AWSCredentials credentials = credentialsProvider.getCredentials(); + assertEquals("some_access_key", credentials.getAWSAccessKeyId()); + assertEquals("super_secret_key", credentials.getAWSSecretKey()); + assertEquals("class com.upplication.s3fs.util.NoOpRequestMetricCollector", client.getRequestMetricsCollector().getClass().toString()); + ClientConfiguration clientConfiguration = client.getClientConfiguration(); + assertEquals(10, clientConfiguration.getConnectionTimeout()); + assertEquals(50, clientConfiguration.getMaxConnections()); + assertEquals(3, clientConfiguration.getMaxErrorRetry()); + assertEquals(Protocol.HTTP, clientConfiguration.getProtocol()); + assertEquals("localhost", clientConfiguration.getProxyDomain()); + assertEquals("127.0.0.1", clientConfiguration.getProxyHost()); + assertEquals("proxy_password", clientConfiguration.getProxyPassword()); + assertEquals(12345, clientConfiguration.getProxyPort()); + assertEquals("proxy_username", clientConfiguration.getProxyUsername()); + assertEquals("what.does.this.do.localhost", clientConfiguration.getProxyWorkstation()); + assertEquals(48000, clientConfiguration.getSocketBufferSizeHints()[0]); + assertEquals(49000, clientConfiguration.getSocketBufferSizeHints()[1]); + assertEquals(30, clientConfiguration.getSocketTimeout()); + assertEquals("I-am-Groot", clientConfiguration.getUserAgent()); + } - @Test - public void theDefaults() { - AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); - System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "giev.ma.access!"); - System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); - Properties props = new Properties(); - ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); - AWSCredentialsProvider credentialsProvider = client.getAWSCredentialsProvider(); - AWSCredentials credentials = credentialsProvider.getCredentials(); - assertEquals("giev.ma.access!", credentials.getAWSAccessKeyId()); - assertEquals("I'll never teeeeeellllll!", credentials.getAWSSecretKey()); - assertNull(client.getRequestMetricsCollector()); - ClientConfiguration clientConfiguration = client.getClientConfiguration(); - assertEquals(50000, clientConfiguration.getConnectionTimeout()); - assertEquals(50, clientConfiguration.getMaxConnections()); - assertEquals(-1, clientConfiguration.getMaxErrorRetry()); - assertEquals(Protocol.HTTPS, clientConfiguration.getProtocol()); - assertNull(clientConfiguration.getProxyDomain()); - assertNull(clientConfiguration.getProxyHost()); - assertNull(clientConfiguration.getProxyPassword()); - assertEquals(-1, clientConfiguration.getProxyPort()); - assertNull(clientConfiguration.getProxyUsername()); - assertNull(clientConfiguration.getProxyWorkstation()); - assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[0]); - assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[1]); - assertEquals(50000, clientConfiguration.getSocketTimeout()); - assertTrue(clientConfiguration.getUserAgent().startsWith("aws-sdk-java")); - } + @Test + public void theDefaults() { + AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); + System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "giev.ma.access!"); + System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); + Properties props = new Properties(); + ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); + AWSCredentialsProvider credentialsProvider = client.getAWSCredentialsProvider(); + AWSCredentials credentials = credentialsProvider.getCredentials(); + assertEquals("giev.ma.access!", credentials.getAWSAccessKeyId()); + assertEquals("I'll never teeeeeellllll!", credentials.getAWSSecretKey()); + assertNull(client.getRequestMetricsCollector()); + ClientConfiguration clientConfiguration = client.getClientConfiguration(); + assertEquals(50000, clientConfiguration.getConnectionTimeout()); + assertEquals(50, clientConfiguration.getMaxConnections()); + assertEquals(-1, clientConfiguration.getMaxErrorRetry()); + assertEquals(Protocol.HTTPS, clientConfiguration.getProtocol()); + assertNull(clientConfiguration.getProxyDomain()); + assertNull(clientConfiguration.getProxyHost()); + assertNull(clientConfiguration.getProxyPassword()); + assertEquals(-1, clientConfiguration.getProxyPort()); + assertNull(clientConfiguration.getProxyUsername()); + assertNull(clientConfiguration.getProxyWorkstation()); + assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[0]); + assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[1]); + assertEquals(50000, clientConfiguration.getSocketTimeout()); + assertTrue(clientConfiguration.getUserAgent().startsWith("aws-sdk-java")); + } - @Test(expected = IllegalArgumentException.class) - public void halfTheCredentials() { - AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); - System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); - Properties props = new Properties(); - props.setProperty(ACCESS_KEY, "I want access"); - clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); - } + @Test(expected = IllegalArgumentException.class) + public void halfTheCredentials() { + AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); + System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); + Properties props = new Properties(); + props.setProperty(ACCESS_KEY, "I want access"); + clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); + } - @Test(expected = IllegalArgumentException.class) - public void theOtherHalf() { - AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); - System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "I want access"); - Properties props = new Properties(); - props.setProperty(SECRET_KEY, "I'll never teeeeeellllll!"); - clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); - } + @Test(expected = IllegalArgumentException.class) + public void theOtherHalf() { + AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); + System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "I want access"); + Properties props = new Properties(); + props.setProperty(SECRET_KEY, "I'll never teeeeeellllll!"); + clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); + } - @Test(expected = IllegalArgumentException.class) - public void wrongMetricsCollector() { - AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); - Properties props = new Properties(); - props.setProperty(ACCESS_KEY, "I want access"); - props.setProperty(SECRET_KEY, "I'll never teeeeeellllll!"); - props.setProperty(REQUEST_METRIC_COLLECTOR_CLASS, "com.upplication.s3fs.util.WrongRequestMetricCollector"); - clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); - } + @Test(expected = IllegalArgumentException.class) + public void wrongMetricsCollector() { + AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); + Properties props = new Properties(); + props.setProperty(ACCESS_KEY, "I want access"); + props.setProperty(SECRET_KEY, "I'll never teeeeeellllll!"); + props.setProperty(REQUEST_METRIC_COLLECTOR_CLASS, "com.upplication.s3fs.util.WrongRequestMetricCollector"); + clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); + } - @Test - public void defaultSendBufferHint() { - AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); - System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "giev.ma.access!"); - System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); - Properties props = new Properties(); - props.setProperty(SOCKET_SEND_BUFFER_SIZE_HINT, "12345"); - ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); - ClientConfiguration clientConfiguration = client.getClientConfiguration(); - assertEquals(12345, clientConfiguration.getSocketBufferSizeHints()[0]); - assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[1]); - } + @Test + public void defaultSendBufferHint() { + AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); + System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "giev.ma.access!"); + System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); + Properties props = new Properties(); + props.setProperty(SOCKET_SEND_BUFFER_SIZE_HINT, "12345"); + ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); + ClientConfiguration clientConfiguration = client.getClientConfiguration(); + assertEquals(12345, clientConfiguration.getSocketBufferSizeHints()[0]); + assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[1]); + } - @Test - public void defaultReceiveBufferHint() { - AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); - System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "giev.ma.access!"); - System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); - Properties props = new Properties(); - props.setProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT, "54321"); - ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); - ClientConfiguration clientConfiguration = client.getClientConfiguration(); - assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[0]); - assertEquals(54321, clientConfiguration.getSocketBufferSizeHints()[1]); - } + @Test + public void defaultReceiveBufferHint() { + AmazonS3ClientFactory clientFactory = new ExposingAmazonS3ClientFactory(); + System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "giev.ma.access!"); + System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "I'll never teeeeeellllll!"); + Properties props = new Properties(); + props.setProperty(SOCKET_RECEIVE_BUFFER_SIZE_HINT, "54321"); + ExposingAmazonS3Client client = (ExposingAmazonS3Client) clientFactory.getAmazonS3(S3UnitTestBase.S3_GLOBAL_URI, props); + ClientConfiguration clientConfiguration = client.getClientConfiguration(); + assertEquals(0, clientConfiguration.getSocketBufferSizeHints()[0]); + assertEquals(54321, clientConfiguration.getSocketBufferSizeHints()[1]); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/AmazonS3ClientIT.java b/src/test/java/com/upplication/s3fs/AmazonS3ClientIT.java index 7c77d3e..a4f04bd 100644 --- a/src/test/java/com/upplication/s3fs/AmazonS3ClientIT.java +++ b/src/test/java/com/upplication/s3fs/AmazonS3ClientIT.java @@ -27,59 +27,63 @@ public class AmazonS3ClientIT { - AmazonS3 client; + AmazonS3 client; - @Before - public void setup() { - // s3client - final Map credentials = getRealEnv(); - BasicAWSCredentials credentialsS3 = new BasicAWSCredentials(credentials.get(ACCESS_KEY).toString(), credentials.get(SECRET_KEY).toString()); - client = new com.amazonaws.services.s3.AmazonS3Client(credentialsS3); - } + @Before + public void setup() { + // s3client + final Map credentials = getRealEnv(); + BasicAWSCredentials credentialsS3 = new BasicAWSCredentials(credentials.get(ACCESS_KEY).toString(), credentials.get(SECRET_KEY).toString()); + client = new com.amazonaws.services.s3.AmazonS3Client(credentialsS3); + } @Test - public void putObject() throws IOException { - Path file = Files.createTempFile("file-se", "file"); - Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); + public void putObject() throws IOException { + Path file = Files.createTempFile("file-se", "file"); + Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); - PutObjectResult result = client.putObject(getBucket(), randomUUID().toString(), file.toFile()); + PutObjectResult result = client.putObject(getBucket(), randomUUID().toString(), file.toFile()); + + assertNotNull(result); + } - assertNotNull(result); - } @Test - public void putObjectWithEndSlash() throws IOException { - Path file = Files.createTempFile("file-se", "file"); - Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); + public void putObjectWithEndSlash() throws IOException { + Path file = Files.createTempFile("file-se", "file"); + Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); + + PutObjectResult result = client.putObject(getBucket(), randomUUID().toString() + "/", file.toFile()); - PutObjectResult result = client.putObject(getBucket(), randomUUID().toString() + "/", file.toFile()); + assertNotNull(result); + } - assertNotNull(result); - } @Test - public void putObjectWithStartSlash() throws IOException { - Path file = Files.createTempFile("file-se", "file"); - Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); + public void putObjectWithStartSlash() throws IOException { + Path file = Files.createTempFile("file-se", "file"); + Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); + + client.putObject(getBucket(), "/" + randomUUID().toString(), file.toFile()); + } - client.putObject(getBucket(), "/" + randomUUID().toString(), file.toFile()); - } @Test - public void putObjectWithBothSlash() throws IOException { - Path file = Files.createTempFile("file-se", "file"); - Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); + public void putObjectWithBothSlash() throws IOException { + Path file = Files.createTempFile("file-se", "file"); + Files.write(file, "content".getBytes(), StandardOpenOption.APPEND); + + PutObjectResult result = client.putObject(getBucket(), "/" + randomUUID().toString() + "/", file.toFile()); - PutObjectResult result = client.putObject(getBucket(), "/" + randomUUID().toString() + "/", file.toFile()); + assertNotNull(result); + } - assertNotNull(result); - } @Test - public void putObjectByteArray() { + public void putObjectByteArray() { - PutObjectResult result = client.putObject(getBucket(), randomUUID().toString(), new ByteArrayInputStream("contenido1".getBytes()), new ObjectMetadata()); + PutObjectResult result = client.putObject(getBucket(), randomUUID().toString(), new ByteArrayInputStream("contenido1".getBytes()), new ObjectMetadata()); - assertNotNull(result); - } + assertNotNull(result); + } - private String getBucket() { - return EnvironmentBuilder.getBucket().replace("/", ""); - } + private String getBucket() { + return EnvironmentBuilder.getBucket().replace("/", ""); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/AttributesUtilsTest.java b/src/test/java/com/upplication/s3fs/AttributesUtilsTest.java new file mode 100644 index 0000000..effad18 --- /dev/null +++ b/src/test/java/com/upplication/s3fs/AttributesUtilsTest.java @@ -0,0 +1,47 @@ +package com.upplication.s3fs; + +import com.upplication.s3fs.util.AttributesUtils; +import org.junit.Test; + +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; + + +public class AttributesUtilsTest { + /** + * http://stackoverflow.com/questions/9700179/junit-testing-helper-class-with-only-static-methods + */ + @Test + public void just_to_silence_coverage() { + new AttributesUtils() { + // ignore this + }; + } + + @Test + public void filterAll() { + final String key = "key"; + final FileTime fileTime = FileTime.from(10L, TimeUnit.DAYS); + final long size = 10L; + final boolean isDirectory = true; + final String[] filters = new String[]{"isDirectory", "isRegularFile", "isOther", "creationTime", "fileKey", "isSymbolicLink", "lastAccessTime", "lastModifiedTime", "size"}; + BasicFileAttributes attrs = new S3FileAttributes(key, fileTime, size, isDirectory, !isDirectory); + + Map map = AttributesUtils.fileAttributeToMap(attrs, filters); + + assertEquals(filters.length, map.size()); + assertEquals(key, map.get("fileKey")); + assertEquals(fileTime, map.get("creationTime")); + assertEquals(isDirectory, map.get("isDirectory")); + assertEquals(false, map.get("isRegularFile")); + assertEquals(false, map.get("isOther")); + assertEquals(false, map.get("isSymbolicLink")); + assertEquals(fileTime, map.get("lastAccessTime")); + assertEquals(fileTime, map.get("lastModifiedTime")); + assertEquals(size, map.get("size")); + } +} diff --git a/src/test/java/com/upplication/s3fs/FileSystemProviderIT.java b/src/test/java/com/upplication/s3fs/FileSystemProviderIT.java index 7340234..72a7e5c 100644 --- a/src/test/java/com/upplication/s3fs/FileSystemProviderIT.java +++ b/src/test/java/com/upplication/s3fs/FileSystemProviderIT.java @@ -1,4 +1,5 @@ package com.upplication.s3fs; + import static com.upplication.s3fs.AmazonS3Factory.ACCESS_KEY; import static com.upplication.s3fs.AmazonS3Factory.SECRET_KEY; import static com.upplication.s3fs.S3UnitTestBase.S3_GLOBAL_URI; @@ -25,45 +26,44 @@ public class FileSystemProviderIT { - private S3FileSystemProvider provider; - - @Before - public void setup() throws IOException { - System.clearProperty(S3FileSystemProvider.AMAZON_S3_FACTORY_CLASS); + private S3FileSystemProvider provider; + + @Before + public void setup() throws IOException { + System.clearProperty(S3FileSystemProvider.AMAZON_S3_FACTORY_CLASS); System.clearProperty(ACCESS_KEY); System.clearProperty(SECRET_KEY); - try { - FileSystems.getFileSystem(S3_GLOBAL_URI).close(); - } - catch(FileSystemNotFoundException e) { - // ignore this - } - provider = spy(new S3FileSystemProvider()); + try { + FileSystems.getFileSystem(S3_GLOBAL_URI).close(); + } catch (FileSystemNotFoundException e) { + // ignore this + } + provider = spy(new S3FileSystemProvider()); doReturn(buildFakeProps()).when(provider).loadAmazonProperties(); // dont override with system envs that we can have setted, like travis doReturn(false).when(provider).overloadPropertiesWithSystemEnv(any(Properties.class), anyString()); doReturn(false).when(provider).overloadPropertiesWithSystemProps(any(Properties.class), anyString()); - } - - @Test - public void createAuthenticatedByProperties(){ - - URI uri = URI.create("s3://yadi/"); - - FileSystem fileSystem = provider.newFileSystem(uri, null); - assertNotNull(fileSystem); - - verify(provider).createFileSystem(eq(uri), eq(buildFakeProps())); - } - - - @Test - public void createsAuthenticatedByEnvOverridesProps() { - - final Map env = buildFakeEnv(); - provider.newFileSystem(S3_GLOBAL_URI, env); - - verify(provider).createFileSystem(eq(S3_GLOBAL_URI), argThat(new ArgumentMatcher() { + } + + @Test + public void createAuthenticatedByProperties() { + + URI uri = URI.create("s3://yadi/"); + + FileSystem fileSystem = provider.newFileSystem(uri, null); + assertNotNull(fileSystem); + + verify(provider).createFileSystem(eq(uri), eq(buildFakeProps())); + } + + + @Test + public void createsAuthenticatedByEnvOverridesProps() { + + final Map env = buildFakeEnv(); + provider.newFileSystem(S3_GLOBAL_URI, env); + + verify(provider).createFileSystem(eq(S3_GLOBAL_URI), argThat(new ArgumentMatcher() { @Override public boolean matches(Object argument) { Properties called = (Properties) argument; @@ -72,7 +72,7 @@ public boolean matches(Object argument) { return true; } })); - } + } @Test public void createsAuthenticatedBySystemProps() { @@ -89,7 +89,7 @@ public void createsAuthenticatedBySystemProps() { verify(provider).createFileSystem(eq(S3_GLOBAL_URI), argThat(new ArgumentMatcher() { @Override public boolean matches(Object argument) { - Properties called = (Properties)argument; + Properties called = (Properties) argument; assertEquals(propAccessKey, called.get(ACCESS_KEY)); assertEquals(propSecretKey, called.get(SECRET_KEY)); return true; @@ -112,7 +112,7 @@ public void createsAuthenticatedBySystemEnv() { verify(provider).createFileSystem(eq(S3_GLOBAL_URI), argThat(new ArgumentMatcher() { @Override public boolean matches(Object argument) { - Properties called = (Properties)argument; + Properties called = (Properties) argument; assertEquals(propAccessKey, called.get(ACCESS_KEY)); assertEquals(propSecretKey, called.get(SECRET_KEY)); return true; @@ -131,7 +131,7 @@ public void createsAuthenticatedByUri() { verify(provider).createFileSystem(eq(uri), argThat(new ArgumentMatcher() { @Override public boolean matches(Object argument) { - Properties called = (Properties)argument; + Properties called = (Properties) argument; assertEquals(accessKeyUri, called.get(ACCESS_KEY)); assertEquals(secretKeyUri, called.get(SECRET_KEY)); return true; @@ -139,39 +139,38 @@ public boolean matches(Object argument) { })); } - @Test - public void createsAnonymousNotPossible() { - FileSystem fileSystem = provider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); - assertNotNull(fileSystem); - verify(provider).createFileSystem(eq(S3_GLOBAL_URI), eq(buildFakeProps())); - } + @Test + public void createsAnonymousNotPossible() { + FileSystem fileSystem = provider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + assertNotNull(fileSystem); + verify(provider).createFileSystem(eq(S3_GLOBAL_URI), eq(buildFakeProps())); + } @Test public void getFileSystemWithSameEnvReturnSameFileSystem() { doCallRealMethod().when(provider).loadAmazonProperties(); - Map env = ImmutableMap. of("s3fs_access_key", "a", "s3fs_secret_key", "b"); + Map env = ImmutableMap.of("s3fs_access_key", "a", "s3fs_secret_key", "b"); FileSystem fileSystem = provider.getFileSystem(S3_GLOBAL_URI, env); assertNotNull(fileSystem); FileSystem sameFileSystem = provider.getFileSystem(S3_GLOBAL_URI, env); assertSame(fileSystem, sameFileSystem); } - - private Map buildFakeEnv(){ - return ImmutableMap. builder() - .put(ACCESS_KEY, "access-key") - .put(SECRET_KEY, "secret-key").build(); - } - - private Properties buildFakeProps() { + + private Map buildFakeEnv() { + return ImmutableMap.builder() + .put(ACCESS_KEY, "access-key") + .put(SECRET_KEY, "secret-key").build(); + } + + private Properties buildFakeProps() { try { Properties props = new Properties(); props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("amazon-test-sample.properties")); return props; - } - catch (IOException e){ + } catch (IOException e) { throw new RuntimeException("amazon-test-sample.properties not present"); } - } + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/FilesOperationsIT.java b/src/test/java/com/upplication/s3fs/FilesOperationsIT.java index 2877b52..ac9a65e 100644 --- a/src/test/java/com/upplication/s3fs/FilesOperationsIT.java +++ b/src/test/java/com/upplication/s3fs/FilesOperationsIT.java @@ -19,6 +19,7 @@ import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.EnumSet; +import java.util.Map; import java.util.UUID; import com.amazonaws.services.s3.AmazonS3; @@ -33,64 +34,64 @@ public class FilesOperationsIT { - private static final URI uriEurope = URI.create("s3://s3-eu-west-1.amazonaws.com/"); - private static final String bucket = EnvironmentBuilder.getBucket(); + private static final URI uriEurope = URI.create("s3://s3-eu-west-1.amazonaws.com/"); + private static final String bucket = EnvironmentBuilder.getBucket(); private static final URI uriGlobal = EnvironmentBuilder.getS3URI(S3_GLOBAL_URI); - private FileSystem fileSystemAmazon; + private FileSystem fileSystemAmazon; @Before - public void setup() throws IOException { + public void setup() throws IOException { System.clearProperty(S3FileSystemProvider.AMAZON_S3_FACTORY_CLASS); - fileSystemAmazon = build(); - } - - private static FileSystem build() throws IOException { - try { - FileSystems.getFileSystem(uriGlobal).close(); - return createNewFileSystem(); - } catch (FileSystemNotFoundException e) { - return createNewFileSystem(); - } - } - - private static FileSystem createNewFileSystem() throws IOException { - return FileSystems.newFileSystem(uriGlobal, EnvironmentBuilder.getRealEnv()); - } + fileSystemAmazon = build(); + } + + private static FileSystem build() throws IOException { + try { + FileSystems.getFileSystem(uriGlobal).close(); + return createNewFileSystem(); + } catch (FileSystemNotFoundException e) { + return createNewFileSystem(); + } + } + + private static FileSystem createNewFileSystem() throws IOException { + return FileSystems.newFileSystem(uriGlobal, EnvironmentBuilder.getRealEnv()); + } @Test - public void buildEnv() { - FileSystem fileSystem = FileSystems.getFileSystem(uriGlobal); - assertSame(fileSystemAmazon, fileSystem); - } + public void buildEnv() { + FileSystem fileSystem = FileSystems.getFileSystem(uriGlobal); + assertSame(fileSystemAmazon, fileSystem); + } @Test - public void buildEnvAnotherURIReturnDifferent() throws IOException { - FileSystem fileSystem = FileSystems.newFileSystem(uriEurope, null); - assertNotSame(fileSystemAmazon, fileSystem); - } + public void buildEnvAnotherURIReturnDifferent() throws IOException { + FileSystem fileSystem = FileSystems.newFileSystem(uriEurope, null); + assertNotSame(fileSystemAmazon, fileSystem); + } @Test - public void notExistsDir() { - Path dir = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + "/"); - assertTrue(!Files.exists(dir)); - } + public void notExistsDir() { + Path dir = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + "/"); + assertTrue(!Files.exists(dir)); + } @Test - public void notExistsFile() { - Path file = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); - assertTrue(!Files.exists(file)); - } + public void notExistsFile() { + Path file = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); + assertTrue(!Files.exists(file)); + } @Test - public void existsFile() throws IOException { - Path file = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); + public void existsFile() throws IOException { + Path file = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); - EnumSet options = EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); - Files.newByteChannel(file, options).close(); + EnumSet options = EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); + Files.newByteChannel(file, options).close(); - assertTrue(Files.exists(file)); - } + assertTrue(Files.exists(file)); + } @Test public void existsFileWithSpace() throws IOException { @@ -104,216 +105,198 @@ public void existsFileWithSpace() throws IOException { } @Test - public void createEmptyDirTest() throws IOException { - Path dir = createEmptyDir(); + public void createEmptyDirTest() throws IOException { + Path dir = createEmptyDir(); - assertTrue(Files.exists(dir)); - assertTrue(Files.isDirectory(dir)); - } + assertTrue(Files.exists(dir)); + assertTrue(Files.isDirectory(dir)); + } @Test - public void createEmptyFileTest() throws IOException { - Path file = createEmptyFile(); + public void createEmptyFileTest() throws IOException { + Path file = createEmptyFile(); - assertTrue(Files.exists(file)); - assertTrue(Files.isRegularFile(file)); - } + assertTrue(Files.exists(file)); + assertTrue(Files.isRegularFile(file)); + } @Test - public void createTempFile() throws IOException { - Path dir = createEmptyDir(); + public void createTempFile() throws IOException { + Path dir = createEmptyDir(); - Path file = Files.createTempFile(dir, "file", "temp"); + Path file = Files.createTempFile(dir, "file", "temp"); - assertTrue(Files.exists(file)); - } + assertTrue(Files.exists(file)); + } @Test - public void createTempDir() throws IOException { - Path dir = createEmptyDir(); + public void createTempDir() throws IOException { + Path dir = createEmptyDir(); - Path dir2 = Files.createTempDirectory(dir, "dir-temp"); + Path dir2 = Files.createTempDirectory(dir, "dir-temp"); - assertTrue(Files.exists(dir2)); - } + assertTrue(Files.exists(dir2)); + } @Test - public void deleteFile() throws IOException { - Path file = createEmptyFile(); - Files.delete(file); + public void deleteFile() throws IOException { + Path file = createEmptyFile(); + Files.delete(file); - Files.notExists(file); - } + Files.notExists(file); + } @Test - public void deleteDir() throws IOException { - Path dir = createEmptyDir(); - Files.delete(dir); + public void deleteDir() throws IOException { + Path dir = createEmptyDir(); + Files.delete(dir); - Files.notExists(dir); - } + Files.notExists(dir); + } @Test - public void copyDir() throws IOException { - Path dir = uploadDir(); - assertTrue(Files.exists(dir.resolve("assets1/"))); - assertTrue(Files.exists(dir.resolve("assets1/").resolve("index.html"))); - assertTrue(Files.exists(dir.resolve("assets1/").resolve("img").resolve("Penguins.jpg"))); - assertTrue(Files.exists(dir.resolve("assets1/").resolve("js").resolve("main.js"))); - } + public void copyDir() throws IOException { + Path dir = uploadDir(); + assertTrue(Files.exists(dir.resolve("assets1/"))); + assertTrue(Files.exists(dir.resolve("assets1/").resolve("index.html"))); + assertTrue(Files.exists(dir.resolve("assets1/").resolve("img").resolve("Penguins.jpg"))); + assertTrue(Files.exists(dir.resolve("assets1/").resolve("js").resolve("main.js"))); + } @Test - public void directoryStreamBaseBucketFindDirectoryTest() throws IOException { - Path bucketPath = fileSystemAmazon.getPath(bucket); - String name = "01" + UUID.randomUUID().toString(); - final Path fileToFind = Files.createDirectory(bucketPath.resolve(name)); - - try (DirectoryStream dirStream = Files.newDirectoryStream(bucketPath)) { - boolean find = false; - for (Path path : dirStream) { - // only first level - assertEquals(bucketPath, path.getParent()); - if (path.equals(fileToFind)) { - find = true; - break; - } - } - assertTrue(find); - } - } + public void directoryStreamBaseBucketFindDirectoryTest() throws IOException { + Path bucketPath = fileSystemAmazon.getPath(bucket); + String name = "01" + UUID.randomUUID().toString(); + final Path fileToFind = Files.createDirectory(bucketPath.resolve(name)); + + try (DirectoryStream dirStream = Files.newDirectoryStream(bucketPath)) { + findFileInDirectoryStream(bucketPath, fileToFind, dirStream); + } + } @Test - public void directoryStreamBaseBucketFindFileTest() throws IOException { - Path bucketPath = fileSystemAmazon.getPath(bucket); - String name = "00" + UUID.randomUUID().toString(); - final Path fileToFind = Files.createFile(bucketPath.resolve(name)); - - try (DirectoryStream dirStream = Files.newDirectoryStream(bucketPath)) { - boolean find = false; - for (Path path : dirStream) { - // check parent at first level - assertEquals(bucketPath, path.getParent()); - if (path.equals(fileToFind)) { - find = true; - break; - } - } - assertTrue(find); - } - } + public void directoryStreamBaseBucketFindFileTest() throws IOException { + Path bucketPath = fileSystemAmazon.getPath(bucket); + String name = "00" + UUID.randomUUID().toString(); + final Path fileToFind = Files.createFile(bucketPath.resolve(name)); + + try (DirectoryStream dirStream = Files.newDirectoryStream(bucketPath)) { + findFileInDirectoryStream(bucketPath, fileToFind, dirStream); + } + } @Test - public void directoryStreamFirstDirTest() throws IOException { - Path dir = uploadDir(); - - try (DirectoryStream dirStream = Files.newDirectoryStream(dir)) { - int number = 0; - for (Path path : dirStream) { - number++; - // only first level - assertEquals(dir, path.getParent()); - assertEquals("assets1", path.getFileName().toString()); - } - - assertEquals(1, number); - } - } + public void directoryStreamFirstDirTest() throws IOException { + Path dir = uploadDir(); + + try (DirectoryStream dirStream = Files.newDirectoryStream(dir)) { + int number = 0; + for (Path path : dirStream) { + number++; + // only first level + assertEquals(dir, path.getParent()); + assertEquals("assets1", path.getFileName().toString()); + } + + assertEquals(1, number); + } + } @Test - public void virtualDirectoryStreamTest() throws IOException { - - String folder = UUID.randomUUID().toString(); - - String file1 = folder + "/file.html"; - String file2 = folder + "/file2.html"; - - Path dir = fileSystemAmazon.getPath(bucket, folder); - - S3Path s3Path = (S3Path) dir; - // upload file without paths - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentLength(0); - s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), file1, new ByteArrayInputStream(new byte[0]), metadata); - // another file without paths - ObjectMetadata metadata2 = new ObjectMetadata(); - metadata.setContentLength(0); - s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), file2, new ByteArrayInputStream(new byte[0]), metadata2); - - try (DirectoryStream dirStream = Files.newDirectoryStream(dir)) { - int number = 0; - boolean file1Find = false; - boolean file2Find = false; - for (Path path : dirStream) { - number++; - // solo recorre ficheros del primer nivel - assertEquals(dir, path.getParent()); - switch (path.getFileName().toString()) { - case "file.html": - file1Find = true; - break; - case "file2.html": - file2Find = true; - break; - default: - break; - } - - } - assertTrue(file1Find); - assertTrue(file2Find); - assertEquals(2, number); - } - } + public void virtualDirectoryStreamTest() throws IOException { + + String folder = UUID.randomUUID().toString(); + + String file1 = folder + "/file.html"; + String file2 = folder + "/file2.html"; + + Path dir = fileSystemAmazon.getPath(bucket, folder); + + S3Path s3Path = (S3Path) dir; + // upload file without paths + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(0); + s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), file1, new ByteArrayInputStream(new byte[0]), metadata); + // another file without paths + ObjectMetadata metadata2 = new ObjectMetadata(); + metadata.setContentLength(0); + s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), file2, new ByteArrayInputStream(new byte[0]), metadata2); + + try (DirectoryStream dirStream = Files.newDirectoryStream(dir)) { + int number = 0; + boolean file1Find = false; + boolean file2Find = false; + for (Path path : dirStream) { + number++; + // solo recorre ficheros del primer nivel + assertEquals(dir, path.getParent()); + switch (path.getFileName().toString()) { + case "file.html": + file1Find = true; + break; + case "file2.html": + file2Find = true; + break; + default: + break; + } + + } + assertTrue(file1Find); + assertTrue(file2Find); + assertEquals(2, number); + } + } @Test - public void virtualDirectoryStreamWithVirtualSubFolderTest() throws IOException { - String folder = UUID.randomUUID().toString(); - - String subfoler = folder + "/subfolder/file.html"; - String file2 = folder + "/file2.html"; - - Path dir = fileSystemAmazon.getPath(bucket, folder); - - S3Path s3Path = (S3Path) dir; - // upload without paths - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentLength(0); - s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), subfoler, new ByteArrayInputStream(new byte[0]), metadata); - // upload another file without paths - ObjectMetadata metadata2 = new ObjectMetadata(); - metadata.setContentLength(0); - s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), file2, new ByteArrayInputStream(new byte[0]), metadata2); - - try (DirectoryStream dirStream = Files.newDirectoryStream(dir)) { - int number = 0; - boolean subfolderFind = false; - boolean file2Find = false; - for (Path path : dirStream) { - number++; - // solo recorre ficheros del primer nivel - assertEquals(dir, path.getParent()); - switch (path.getFileName().toString()) { - case "subfolder": - subfolderFind = true; - break; - case "file2.html": - file2Find = true; - break; - default: - break; - } - - } - assertTrue(subfolderFind); - assertTrue(file2Find); - assertEquals(2, number); - } - } + public void virtualDirectoryStreamWithVirtualSubFolderTest() throws IOException { + String folder = UUID.randomUUID().toString(); + + String subfoler = folder + "/subfolder/file.html"; + String file2 = folder + "/file2.html"; + + Path dir = fileSystemAmazon.getPath(bucket, folder); + + S3Path s3Path = (S3Path) dir; + // upload without paths + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(0); + s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), subfoler, new ByteArrayInputStream(new byte[0]), metadata); + // upload another file without paths + ObjectMetadata metadata2 = new ObjectMetadata(); + metadata.setContentLength(0); + s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), file2, new ByteArrayInputStream(new byte[0]), metadata2); + + try (DirectoryStream dirStream = Files.newDirectoryStream(dir)) { + int number = 0; + boolean subfolderFind = false; + boolean file2Find = false; + for (Path path : dirStream) { + number++; + // solo recorre ficheros del primer nivel + assertEquals(dir, path.getParent()); + switch (path.getFileName().toString()) { + case "subfolder": + subfolderFind = true; + break; + case "file2.html": + file2Find = true; + break; + default: + break; + } + + } + assertTrue(subfolderFind); + assertTrue(file2Find); + assertEquals(2, number); + } + } @Test - public void deleteFullDirTest() throws IOException { - Path dir = uploadDir(); - Files.walkFileTree(dir, new SimpleFileVisitor() { + public void deleteFullDirTest() throws IOException { + Path dir = uploadDir(); + Files.walkFileTree(dir, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); @@ -329,30 +312,30 @@ public FileVisitResult postVisitDirectory(Path directory, IOException exc) throw throw exc; } }); - assertTrue(!Files.exists(dir)); - } + assertTrue(!Files.exists(dir)); + } @Test - public void copyUpload() throws IOException { - final String content = "sample content"; - Path result = uploadSingleFile(content); + public void copyUpload() throws IOException { + final String content = "sample content"; + Path result = uploadSingleFile(content); - assertTrue(Files.exists(result)); - assertArrayEquals(content.getBytes(), Files.readAllBytes(result)); - } + assertTrue(Files.exists(result)); + assertArrayEquals(content.getBytes(), Files.readAllBytes(result)); + } @Test - public void copyDownload() throws IOException { - Path result = uploadSingleFile(null); + public void copyDownload() throws IOException { + Path result = uploadSingleFile(null); - Path localResult = Files.createTempDirectory("temp-local-file"); - Path notExistLocalResult = localResult.resolve("result"); + Path localResult = Files.createTempDirectory("temp-local-file"); + Path notExistLocalResult = localResult.resolve("result"); - Files.copy(result, notExistLocalResult); + Files.copy(result, notExistLocalResult); - assertTrue(Files.exists(notExistLocalResult)); - assertArrayEquals(Files.readAllBytes(result), Files.readAllBytes(notExistLocalResult)); - } + assertTrue(Files.exists(notExistLocalResult)); + assertArrayEquals(Files.readAllBytes(result), Files.readAllBytes(notExistLocalResult)); + } @Test(expected = UnsupportedOperationException.class) public void moveFromDifferentProviders() throws IOException { @@ -380,110 +363,141 @@ public void move() throws IOException { } @Test - public void createFileWithFolderAndNotExistsFolders() { + public void createFileWithFolderAndNotExistsFolders() { - String fileWithFolders = UUID.randomUUID().toString() + "/folder2/file.html"; + String fileWithFolders = UUID.randomUUID().toString() + "/folder2/file.html"; - Path path = fileSystemAmazon.getPath(bucket, fileWithFolders.split("/")); + Path path = fileSystemAmazon.getPath(bucket, fileWithFolders.split("/")); - S3Path s3Path = (S3Path) path; - // upload file without paths - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentLength(0); - s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), fileWithFolders, new ByteArrayInputStream(new byte[0]), metadata); + S3Path s3Path = (S3Path) path; + // upload file without paths + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(0); + s3Path.getFileSystem().getClient().putObject(s3Path.getFileStore().name(), fileWithFolders, new ByteArrayInputStream(new byte[0]), metadata); - assertTrue(Files.exists(path)); - assertTrue(Files.exists(path.getParent())); - } + assertTrue(Files.exists(path)); + assertTrue(Files.exists(path.getParent())); + } @Test - public void amazonCopyDetectContentType() throws IOException { - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path htmlFile = Files.write(linux.getPath("/index.html"), "html file".getBytes()); + public void amazonCopyDetectContentType() throws IOException { + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path htmlFile = Files.write(linux.getPath("/index.html"), "html file".getBytes()); - Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + htmlFile.getFileName().toString()); - Files.copy(htmlFile, result); + Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + htmlFile.getFileName().toString()); + Files.copy(htmlFile, result); - S3Path resultS3 = (S3Path) result; - ObjectMetadata metadata = resultS3.getFileSystem().getClient().getObjectMetadata(resultS3.getFileStore().name(), resultS3.getKey()); - assertEquals("text/html", metadata.getContentType()); - } - } + S3Path resultS3 = (S3Path) result; + ObjectMetadata metadata = resultS3.getFileSystem().getClient().getObjectMetadata(resultS3.getFileStore().name(), resultS3.getKey()); + assertEquals("text/html", metadata.getContentType()); + } + } @Test - public void amazonCopyNotDetectContentTypeSetDefault() throws IOException { - final byte[] data = new byte[] { (byte) 0xe0, 0x4f, (byte) 0xd0, 0x20, (byte) 0xea, 0x3a, 0x69, 0x10, (byte) 0xa2, (byte) 0xd8, 0x08, 0x00, 0x2b, 0x30, 0x30, (byte) 0x9d }; - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path htmlFile = Files.write(linux.getPath("/index.adsadas"), data); + public void amazonCopyNotDetectContentTypeSetDefault() throws IOException { + final byte[] data = new byte[]{(byte) 0xe0, 0x4f, (byte) 0xd0, 0x20, (byte) 0xea, 0x3a, 0x69, 0x10, (byte) 0xa2, (byte) 0xd8, 0x08, 0x00, 0x2b, 0x30, 0x30, (byte) 0x9d}; + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path htmlFile = Files.write(linux.getPath("/index.adsadas"), data); - Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + htmlFile.getFileName().toString()); - Files.copy(htmlFile, result); + Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + htmlFile.getFileName().toString()); + Files.copy(htmlFile, result); - S3Path resultS3 = (S3Path) result; - ObjectMetadata metadata = resultS3.getFileSystem().getClient().getObjectMetadata(resultS3.getFileStore().name(), resultS3.getKey()); - assertEquals("application/octet-stream", metadata.getContentType()); - } - } + S3Path resultS3 = (S3Path) result; + ObjectMetadata metadata = resultS3.getFileSystem().getClient().getObjectMetadata(resultS3.getFileStore().name(), resultS3.getKey()); + assertEquals("application/octet-stream", metadata.getContentType()); + } + } @Test - public void amazonOutpuStreamDetectContentType() throws IOException { - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path htmlFile = Files.write(linux.getPath("/index.html"), "html file".getBytes()); - - Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + htmlFile.getFileName().toString()); - - try (OutputStream out = Files.newOutputStream(result)) { - // copied from Files.write - byte[] bytes = Files.readAllBytes(htmlFile); - int len = bytes.length; - int rem = len; - while (rem > 0) { - int n = Math.min(rem, 8192); - out.write(bytes, (len - rem), n); - rem -= n; - } - } - - S3Path resultS3 = (S3Path) result; - ObjectMetadata metadata = resultS3.getFileSystem().getClient().getObjectMetadata(resultS3.getFileStore().name(), resultS3.getKey()); - assertEquals("text/html", metadata.getContentType()); - } - } + public void amazonOutpuStreamDetectContentType() throws IOException { + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path htmlFile = Files.write(linux.getPath("/index.html"), "html file".getBytes()); + + Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + htmlFile.getFileName().toString()); + + try (OutputStream out = Files.newOutputStream(result)) { + // copied from Files.write + byte[] bytes = Files.readAllBytes(htmlFile); + int len = bytes.length; + int rem = len; + while (rem > 0) { + int n = Math.min(rem, 8192); + out.write(bytes, (len - rem), n); + rem -= n; + } + } + + S3Path resultS3 = (S3Path) result; + ObjectMetadata metadata = resultS3.getFileSystem().getClient().getObjectMetadata(resultS3.getFileStore().name(), resultS3.getKey()); + assertEquals("text/html", metadata.getContentType()); + } + } + + @Test + public void readAttributesFile() throws IOException { + final String content = "sample content"; + Path file = uploadSingleFile(content); + + BasicFileAttributes fileAttributes = Files.readAttributes(file, BasicFileAttributes.class); + assertNotNull(fileAttributes); + assertEquals(true, fileAttributes.isRegularFile()); + assertEquals(false, fileAttributes.isDirectory()); + assertEquals(false, fileAttributes.isSymbolicLink()); + assertEquals(false, fileAttributes.isOther()); + assertEquals(content.length(), fileAttributes.size()); + } @Test - public void readAttributesDirectory() throws IOException { - Path dir; - - final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path dirDynamicLocale = Files.createDirectories(linux.getPath("/lib").resolve("angular-dynamic-locale")); - Path assets = Files.createDirectories(linux.getPath("/lib").resolve("angular")); - Files.createFile(assets.resolve("angular-locale_es-es.min.js")); - Files.createFile(assets.resolve("angular.min.js")); - Files.createDirectory(assets.resolve("locales")); - Files.createFile(dirDynamicLocale.resolve("tmhDinamicLocale.min.js")); - dir = fileSystemAmazon.getPath(bucket, startPath); - Files.exists(assets); - Files.walkFileTree(assets.getParent(), new CopyDirVisitor(assets.getParent().getParent(), dir)); - } - - //dir = fileSystemAmazon.getPath("/upp-sources", "DES", "skeleton"); - - BasicFileAttributes fileAttributes = Files.readAttributes(dir.resolve("lib").resolve("angular"), BasicFileAttributes.class); - assertNotNull(fileAttributes); - assertEquals(true, fileAttributes.isDirectory()); - assertEquals(startPath + "lib/angular/", fileAttributes.fileKey()); - } + public void readAttributesString() throws IOException { + final String content = "sample content"; + Path file = uploadSingleFile(content); + + BasicFileAttributes fileAttributes = Files.readAttributes(file, BasicFileAttributes.class); + Map fileAttributesMap = Files.readAttributes(file, "*"); + assertNotNull(fileAttributes); + assertNotNull(fileAttributesMap); + assertEquals(fileAttributes.isRegularFile(), fileAttributesMap.get("isRegularFile")); + assertEquals(fileAttributes.isDirectory(), fileAttributesMap.get("isDirectory")); + assertEquals(fileAttributes.creationTime(), fileAttributesMap.get("creationTime")); + assertEquals(fileAttributes.lastModifiedTime(), fileAttributesMap.get("lastModifiedTime")); + assertEquals(9, fileAttributesMap.size()); + } + + @Test + public void readAttributesDirectory() throws IOException { + Path dir; + + final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path dirDynamicLocale = Files.createDirectories(linux.getPath("/lib").resolve("angular-dynamic-locale")); + Path assets = Files.createDirectories(linux.getPath("/lib").resolve("angular")); + Files.createFile(assets.resolve("angular-locale_es-es.min.js")); + Files.createFile(assets.resolve("angular.min.js")); + Files.createDirectory(assets.resolve("locales")); + Files.createFile(dirDynamicLocale.resolve("tmhDinamicLocale.min.js")); + dir = fileSystemAmazon.getPath(bucket, startPath); + Files.exists(assets); + Files.walkFileTree(assets.getParent(), new CopyDirVisitor(assets.getParent().getParent(), dir)); + } + + //dir = fileSystemAmazon.getPath("/upp-sources", "DES", "skeleton"); + + BasicFileAttributes fileAttributes = Files.readAttributes(dir.resolve("lib").resolve("angular"), BasicFileAttributes.class); + assertNotNull(fileAttributes); + assertEquals(true, fileAttributes.isDirectory()); + assertEquals(startPath + "lib/angular/", fileAttributes.fileKey()); + } + @Test - public void seekableCloseTwice() throws IOException { - Path file = createEmptyFile(); + public void seekableCloseTwice() throws IOException { + Path file = createEmptyFile(); - SeekableByteChannel seekableByteChannel = Files.newByteChannel(file); - seekableByteChannel.close(); - seekableByteChannel.close(); + SeekableByteChannel seekableByteChannel = Files.newByteChannel(file); + seekableByteChannel.close(); + seekableByteChannel.close(); - assertTrue(Files.exists(file)); - } + assertTrue(Files.exists(file)); + } @Test public void bucketIsDirectory() throws IOException { @@ -500,51 +514,64 @@ public void bucketIsDirectory() throws IOException { // helpers private Path createEmptyDir() throws IOException { - Path dir = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + "/"); + Path dir = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString() + "/"); - Files.createDirectory(dir); - return dir; - } + Files.createDirectory(dir); + return dir; + } - private Path createEmptyFile() throws IOException { - Path file = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); + private Path createEmptyFile() throws IOException { + Path file = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); - Files.createFile(file); - return file; - } + Files.createFile(file); + return file; + } - private Path uploadSingleFile(String content) throws IOException { - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + private Path uploadSingleFile(String content) throws IOException { + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - if (content != null) { - Files.write(linux.getPath("/index.html"), content.getBytes()); - } else { - Files.createFile(linux.getPath("/index.html")); - } + if (content != null) { + Files.write(linux.getPath("/index.html"), content.getBytes()); + } else { + Files.createFile(linux.getPath("/index.html")); + } - Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); + Path result = fileSystemAmazon.getPath(bucket, UUID.randomUUID().toString()); - Files.copy(linux.getPath("/index.html"), result); - return result; - } - } + Files.copy(linux.getPath("/index.html"), result); + return result; + } + } + + private Path uploadDir() throws IOException { + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - private Path uploadDir() throws IOException { - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path assets = Files.createDirectories(linux.getPath("/upload/assets1")); + Files.createFile(assets.resolve("index.html")); + Path img = Files.createDirectory(assets.resolve("img")); + Files.createFile(img.resolve("Penguins.jpg")); + Files.createDirectory(assets.resolve("js")); + Files.createFile(assets.resolve("js").resolve("main.js")); - Path assets = Files.createDirectories(linux.getPath("/upload/assets1")); - Files.createFile(assets.resolve("index.html")); - Path img = Files.createDirectory(assets.resolve("img")); - Files.createFile(img.resolve("Penguins.jpg")); - Files.createDirectory(assets.resolve("js")); - Files.createFile(assets.resolve("js").resolve("main.js")); + Path dir = fileSystemAmazon.getPath(bucket, "0000example" + UUID.randomUUID().toString() + "/"); - Path dir = fileSystemAmazon.getPath(bucket, "0000example" + UUID.randomUUID().toString() + "/"); + Files.exists(assets); - Files.exists(assets); + Files.walkFileTree(assets.getParent(), new CopyDirVisitor(assets.getParent(), dir)); + return dir; + } + } - Files.walkFileTree(assets.getParent(), new CopyDirVisitor(assets.getParent(), dir)); - return dir; - } - } + private void findFileInDirectoryStream(Path bucketPath, Path fileToFind, DirectoryStream dirStream) { + boolean find = false; + for (Path path : dirStream) { + // check parent at first level + assertEquals(bucketPath, path.getParent()); + if (path.equals(fileToFind)) { + find = true; + break; + } + } + assertTrue(find); + } } diff --git a/src/test/java/com/upplication/s3fs/IOUtilsTest.java b/src/test/java/com/upplication/s3fs/IOUtilsTest.java index b20f109..e1c12eb 100644 --- a/src/test/java/com/upplication/s3fs/IOUtilsTest.java +++ b/src/test/java/com/upplication/s3fs/IOUtilsTest.java @@ -8,10 +8,10 @@ * http://stackoverflow.com/questions/9700179/junit-testing-helper-class-with-only-static-methods */ public class IOUtilsTest { - @Test - public void just_to_silence_coverage() { - new IOUtils() { - // ignore this - }; - } + @Test + public void just_to_silence_coverage() { + new IOUtils() { + // ignore this + }; + } } diff --git a/src/test/java/com/upplication/s3fs/S3FileAttributesTest.java b/src/test/java/com/upplication/s3fs/S3FileAttributesTest.java index 8d15ee0..4a8bf65 100644 --- a/src/test/java/com/upplication/s3fs/S3FileAttributesTest.java +++ b/src/test/java/com/upplication/s3fs/S3FileAttributesTest.java @@ -8,39 +8,39 @@ import org.junit.Test; public class S3FileAttributesTest { - @Test - public void toStringPrintsBasicInfo() { - final String key = "a key"; - final FileTime fileTime = FileTime.from(100, TimeUnit.SECONDS); - final int size = 10; - final boolean isDirectory = true; - final boolean isRegularFile = true; - S3FileAttributes fileAttributes = new S3FileAttributes(key, fileTime, size, isDirectory, isRegularFile); - - String print = fileAttributes.toString(); - - assertTrue(print.contains(isRegularFile + "")); - assertTrue(print.contains(isDirectory + "")); - assertTrue(print.contains(size + "")); - assertTrue(print.contains(fileTime.toString())); - assertTrue(print.contains(key)); - } - - @Test - public void anotherToStringPrintsBasicInfo() { - final String key = "another complex key"; - final FileTime fileTime = FileTime.from(472931, TimeUnit.SECONDS); - final int size = 138713; - final boolean isDirectory = false; - final boolean isRegularFile = false; - S3FileAttributes fileAttributes = new S3FileAttributes(key, fileTime, size, isDirectory, isRegularFile); - - String print = fileAttributes.toString(); - - assertTrue(print.contains(isRegularFile + "")); - assertTrue(print.contains(isDirectory + "")); - assertTrue(print.contains(size + "")); - assertTrue(print.contains(fileTime.toString())); - assertTrue(print.contains(key)); - } + @Test + public void toStringPrintsBasicInfo() { + final String key = "a key"; + final FileTime fileTime = FileTime.from(100, TimeUnit.SECONDS); + final int size = 10; + final boolean isDirectory = true; + final boolean isRegularFile = true; + S3FileAttributes fileAttributes = new S3FileAttributes(key, fileTime, size, isDirectory, isRegularFile); + + String print = fileAttributes.toString(); + + assertTrue(print.contains(isRegularFile + "")); + assertTrue(print.contains(isDirectory + "")); + assertTrue(print.contains(size + "")); + assertTrue(print.contains(fileTime.toString())); + assertTrue(print.contains(key)); + } + + @Test + public void anotherToStringPrintsBasicInfo() { + final String key = "another complex key"; + final FileTime fileTime = FileTime.from(472931, TimeUnit.SECONDS); + final int size = 138713; + final boolean isDirectory = false; + final boolean isRegularFile = false; + S3FileAttributes fileAttributes = new S3FileAttributes(key, fileTime, size, isDirectory, isRegularFile); + + String print = fileAttributes.toString(); + + assertTrue(print.contains(isRegularFile + "")); + assertTrue(print.contains(isDirectory + "")); + assertTrue(print.contains(size + "")); + assertTrue(print.contains(fileTime.toString())); + assertTrue(print.contains(key)); + } } diff --git a/src/test/java/com/upplication/s3fs/S3FileStoreTest.java b/src/test/java/com/upplication/s3fs/S3FileStoreTest.java index 40de756..566068e 100644 --- a/src/test/java/com/upplication/s3fs/S3FileStoreTest.java +++ b/src/test/java/com/upplication/s3fs/S3FileStoreTest.java @@ -30,12 +30,12 @@ public class S3FileStoreTest extends S3UnitTestBase { - private S3FileSystem fileSystem; - private S3FileStore fileStore; + private S3FileSystem fileSystem; + private S3FileStore fileStore; - @Before - public void prepareFileStore() throws IOException { - Map env = ImmutableMap. builder() + @Before + public void prepareFileStore() throws IOException { + Map env = ImmutableMap.builder() .put(ACCESS_KEY, "access-mocked") .put(SECRET_KEY, "secret-mocked").build(); fileSystem = (S3FileSystem) FileSystems.newFileSystem(S3_GLOBAL_URI, env); @@ -45,74 +45,74 @@ public void prepareFileStore() throws IOException { client.bucket("bucket2").file("placeholder"); S3Path path = fileSystem.getPath("/bucket"); fileStore = path.getFileStore(); - } - - @Test - public void bucketConstructor() { - S3FileStore s3FileStore = new S3FileStore(fileSystem, "name"); - assertEquals("name", s3FileStore.name()); - assertEquals("Mock", s3FileStore.getOwner().getDisplayName()); - } - - @Test - public void nameConstructorAlreadyExists() { - S3FileStore s3FileStore = new S3FileStore(fileSystem, "bucket2"); - assertEquals("bucket2", s3FileStore.name()); - assertEquals("Mock", s3FileStore.getOwner().getDisplayName()); - } - - @Test - public void getFileStoreAttributeView() { - S3FileStoreAttributeView fileStoreAttributeView = fileStore.getFileStoreAttributeView(S3FileStoreAttributeView.class); - assertEquals("S3FileStoreAttributeView", fileStoreAttributeView.name()); - assertEquals("bucket", fileStoreAttributeView.getAttribute(AttrID.name.name())); - assertNotNull(fileStoreAttributeView.getAttribute(AttrID.creationDate.name())); - assertEquals("Mock", fileStoreAttributeView.getAttribute(AttrID.ownerDisplayName.name())); - assertEquals("1", fileStoreAttributeView.getAttribute(AttrID.ownerId.name())); - } - - @Test(expected = IllegalArgumentException.class) - public void getUnsupportedFileStoreAttributeView() { - fileStore.getFileStoreAttributeView(UnsupportedFileStoreAttributeView.class); - } - - @Test - public void getAttributes() throws IOException { - assertEquals("bucket", fileStore.getAttribute(AttrID.name.name())); - assertNotNull(fileStore.getAttribute(AttrID.creationDate.name())); - assertEquals("Mock", fileStore.getAttribute(AttrID.ownerDisplayName.name())); - assertEquals("1", fileStore.getAttribute(AttrID.ownerId.name())); - } - - @Test - public void getOwner() { - Owner owner = fileStore.getOwner(); - assertEquals("Mock", owner.getDisplayName()); - assertEquals("1", owner.getId()); - } - - @Test - public void getRootDirectory() { - S3Path rootDirectory = fileStore.getRootDirectory(); - assertEquals("bucket", rootDirectory.getFileName().toString()); - assertEquals("/bucket/", rootDirectory.toAbsolutePath().toString()); - assertEquals("s3://access-mocked@s3.amazonaws.com/bucket/", rootDirectory.toUri().toString()); - } - - @Test - public void getSpaces() throws IOException { - S3Path root = fileSystem.getPath("/newbucket"); - Files.createFile(root); - S3FileStore newFileStore = root.getFileStore(); - assertEquals("newbucket", newFileStore.name()); - assertEquals("S3Bucket", newFileStore.type()); - assertEquals(false, newFileStore.isReadOnly()); - assertEquals(Long.MAX_VALUE, newFileStore.getTotalSpace()); - assertEquals(Long.MAX_VALUE, newFileStore.getUsableSpace()); - assertEquals(Long.MAX_VALUE, newFileStore.getUnallocatedSpace()); - assertFalse(newFileStore.supportsFileAttributeView(ZipFileAttributeView.class)); - assertFalse(newFileStore.supportsFileAttributeView("zip")); - } + } + + @Test + public void bucketConstructor() { + S3FileStore s3FileStore = new S3FileStore(fileSystem, "name"); + assertEquals("name", s3FileStore.name()); + assertEquals("Mock", s3FileStore.getOwner().getDisplayName()); + } + + @Test + public void nameConstructorAlreadyExists() { + S3FileStore s3FileStore = new S3FileStore(fileSystem, "bucket2"); + assertEquals("bucket2", s3FileStore.name()); + assertEquals("Mock", s3FileStore.getOwner().getDisplayName()); + } + + @Test + public void getFileStoreAttributeView() { + S3FileStoreAttributeView fileStoreAttributeView = fileStore.getFileStoreAttributeView(S3FileStoreAttributeView.class); + assertEquals("S3FileStoreAttributeView", fileStoreAttributeView.name()); + assertEquals("bucket", fileStoreAttributeView.getAttribute(AttrID.name.name())); + assertNotNull(fileStoreAttributeView.getAttribute(AttrID.creationDate.name())); + assertEquals("Mock", fileStoreAttributeView.getAttribute(AttrID.ownerDisplayName.name())); + assertEquals("1", fileStoreAttributeView.getAttribute(AttrID.ownerId.name())); + } + + @Test(expected = IllegalArgumentException.class) + public void getUnsupportedFileStoreAttributeView() { + fileStore.getFileStoreAttributeView(UnsupportedFileStoreAttributeView.class); + } + + @Test + public void getAttributes() throws IOException { + assertEquals("bucket", fileStore.getAttribute(AttrID.name.name())); + assertNotNull(fileStore.getAttribute(AttrID.creationDate.name())); + assertEquals("Mock", fileStore.getAttribute(AttrID.ownerDisplayName.name())); + assertEquals("1", fileStore.getAttribute(AttrID.ownerId.name())); + } + + @Test + public void getOwner() { + Owner owner = fileStore.getOwner(); + assertEquals("Mock", owner.getDisplayName()); + assertEquals("1", owner.getId()); + } + + @Test + public void getRootDirectory() { + S3Path rootDirectory = fileStore.getRootDirectory(); + assertEquals("bucket", rootDirectory.getFileName().toString()); + assertEquals("/bucket/", rootDirectory.toAbsolutePath().toString()); + assertEquals("s3://access-mocked@s3.test.amazonaws.com/bucket/", rootDirectory.toUri().toString()); + } + + @Test + public void getSpaces() throws IOException { + S3Path root = fileSystem.getPath("/newbucket"); + Files.createFile(root); + S3FileStore newFileStore = root.getFileStore(); + assertEquals("newbucket", newFileStore.name()); + assertEquals("S3Bucket", newFileStore.type()); + assertEquals(false, newFileStore.isReadOnly()); + assertEquals(Long.MAX_VALUE, newFileStore.getTotalSpace()); + assertEquals(Long.MAX_VALUE, newFileStore.getUsableSpace()); + assertEquals(Long.MAX_VALUE, newFileStore.getUnallocatedSpace()); + assertFalse(newFileStore.supportsFileAttributeView(ZipFileAttributeView.class)); + assertFalse(newFileStore.supportsFileAttributeView("zip")); + } @Test public void comparable() throws IOException { @@ -150,6 +150,6 @@ public void comparable() throws IOException { } private Map buildFakeEnv() { - return ImmutableMap. builder().put(ACCESS_KEY, "access-key").put(SECRET_KEY, "secret-key").build(); + return ImmutableMap.builder().put(ACCESS_KEY, "access-key").put(SECRET_KEY, "secret-key").build(); } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/S3FileSystemProviderTest.java b/src/test/java/com/upplication/s3fs/S3FileSystemProviderTest.java index 94e76b4..8046749 100644 --- a/src/test/java/com/upplication/s3fs/S3FileSystemProviderTest.java +++ b/src/test/java/com/upplication/s3fs/S3FileSystemProviderTest.java @@ -43,21 +43,21 @@ public class S3FileSystemProviderTest extends S3UnitTestBase { - private S3FileSystemProvider s3fsProvider; + private S3FileSystemProvider s3fsProvider; - @Before - public void setup() { - s3fsProvider = spy(new S3FileSystemProvider()); + @Before + public void setup() { + s3fsProvider = spy(new S3FileSystemProvider()); doReturn(false).when(s3fsProvider).overloadPropertiesWithSystemEnv(any(Properties.class), anyString()); - doReturn(new Properties()).when(s3fsProvider).loadAmazonProperties(); - } + doReturn(new Properties()).when(s3fsProvider).loadAmazonProperties(); + } - @Test(expected = S3FileSystemConfigurationException.class) - public void missconfigure() { - Properties props = new Properties(); - props.setProperty(AMAZON_S3_FACTORY_CLASS, "com.upplication.s3fs.util.BrokenAmazonS3Factory"); - s3fsProvider.createFileSystem(S3_GLOBAL_URI, props); - } + @Test(expected = S3FileSystemConfigurationException.class) + public void missconfigure() { + Properties props = new Properties(); + props.setProperty(AMAZON_S3_FACTORY_CLASS, "com.upplication.s3fs.util.BrokenAmazonS3Factory"); + s3fsProvider.createFileSystem(S3_GLOBAL_URI, props); + } @Test public void newS3FileSystemWithEmptyHostAndUserInfo() throws IOException { @@ -71,45 +71,45 @@ public void newS3FileSystemWithEmptyHost() throws IOException { assertEquals("access-key:secret-key@" + Constants.S3_HOSTNAME, ((S3FileSystem) s3fs).getKey()); } - @Test - public void createsAuthenticatedByEnv() { - Map env = buildFakeEnv(); - FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, env); - assertNotNull(fileSystem); - verify(s3fsProvider).createFileSystem(eq(S3_GLOBAL_URI), eq(buildFakeProps((String) env.get(ACCESS_KEY), (String) env.get(SECRET_KEY)))); - } + @Test + public void createsAuthenticatedByEnv() { + Map env = buildFakeEnv(); + FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, env); + assertNotNull(fileSystem); + verify(s3fsProvider).createFileSystem(eq(S3_GLOBAL_URI), eq(buildFakeProps((String) env.get(ACCESS_KEY), (String) env.get(SECRET_KEY)))); + } - @Test - public void setEncodingByProperties() { - Properties props = new Properties(); - props.setProperty(SECRET_KEY, "better secret key"); - props.setProperty(ACCESS_KEY, "better access key"); - props.setProperty(CHARSET_KEY, "UTF-8"); - doReturn(props).when(s3fsProvider).loadAmazonProperties(); - URI uri = S3_GLOBAL_URI; + @Test + public void setEncodingByProperties() { + Properties props = new Properties(); + props.setProperty(SECRET_KEY, "better secret key"); + props.setProperty(ACCESS_KEY, "better access key"); + props.setProperty(CHARSET_KEY, "UTF-8"); + doReturn(props).when(s3fsProvider).loadAmazonProperties(); + URI uri = S3_GLOBAL_URI; - FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap. of()); - assertNotNull(fileSystem); + FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap.of()); + assertNotNull(fileSystem); - verify(s3fsProvider).createFileSystem(eq(uri), eq(buildFakeProps("better access key", "better secret key", "UTF-8"))); - } + verify(s3fsProvider).createFileSystem(eq(uri), eq(buildFakeProps("better access key", "better secret key", "UTF-8"))); + } - @Test - public void createAuthenticatedByProperties() { - Properties props = new Properties(); - props.setProperty(SECRET_KEY, "better secret key"); - props.setProperty(ACCESS_KEY, "better access key"); - doReturn(props).when(s3fsProvider).loadAmazonProperties(); - URI uri = S3_GLOBAL_URI; + @Test + public void createAuthenticatedByProperties() { + Properties props = new Properties(); + props.setProperty(SECRET_KEY, "better secret key"); + props.setProperty(ACCESS_KEY, "better access key"); + doReturn(props).when(s3fsProvider).loadAmazonProperties(); + URI uri = S3_GLOBAL_URI; - FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap. of()); - assertNotNull(fileSystem); + FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap.of()); + assertNotNull(fileSystem); - verify(s3fsProvider).createFileSystem(eq(uri), eq(buildFakeProps("better access key", "better secret key"))); - } + verify(s3fsProvider).createFileSystem(eq(uri), eq(buildFakeProps("better access key", "better secret key"))); + } - @Test - public void createAuthenticatedBySystemEnvironment() { + @Test + public void createAuthenticatedBySystemEnvironment() { final String accessKey = "better-access-key"; final String secretKey = "better-secret-key"; @@ -118,9 +118,9 @@ public void createAuthenticatedBySystemEnvironment() { doReturn(secretKey).when(s3fsProvider).systemGetEnv(SECRET_KEY); doCallRealMethod().when(s3fsProvider).overloadPropertiesWithSystemEnv(any(Properties.class), anyString()); - s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); - verify(s3fsProvider).createFileSystem(eq(S3_GLOBAL_URI), argThat(new ArgumentMatcher() { + verify(s3fsProvider).createFileSystem(eq(S3_GLOBAL_URI), argThat(new ArgumentMatcher() { @Override public boolean matches(Object argument) { Properties called = (Properties) argument; @@ -129,15 +129,15 @@ public boolean matches(Object argument) { return true; } })); - } + } - @Test - public void createsAnonymous() { - URI uri = S3_GLOBAL_URI; - FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap. of()); - assertNotNull(fileSystem); - verify(s3fsProvider).createFileSystem(eq(uri), eq(buildFakeProps(null, null))); - } + @Test + public void createsAnonymous() { + URI uri = S3_GLOBAL_URI; + FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap.of()); + assertNotNull(fileSystem); + verify(s3fsProvider).createFileSystem(eq(uri), eq(buildFakeProps(null, null))); + } @Test public void createWithDefaultEndpoint() { @@ -148,264 +148,264 @@ public void createWithDefaultEndpoint() { doReturn(props).when(s3fsProvider).loadAmazonProperties(); URI uri = URI.create("s3:///"); - FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap. of()); + FileSystem fileSystem = s3fsProvider.newFileSystem(uri, ImmutableMap.of()); assertNotNull(fileSystem); verify(s3fsProvider).createFileSystem(eq(uri), eq(buildFakeProps("better access key", "better secret key", "UTF-8"))); } - @Test(expected = IllegalArgumentException.class) - public void createWithOnlyAccessKey() { - Properties props = new Properties(); - props.setProperty(ACCESS_KEY, "better access key"); - doReturn(props).when(s3fsProvider).loadAmazonProperties(); - s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); - } - - @Test(expected = IllegalArgumentException.class) - public void createWithOnlySecretKey() { - Properties props = new Properties(); - props.setProperty(SECRET_KEY, "better secret key"); - doReturn(props).when(s3fsProvider).loadAmazonProperties(); - s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap. of()); - } - - @Test(expected = FileSystemAlreadyExistsException.class) - public void createFailsIfAlreadyCreated() { - FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap. of()); - assertNotNull(fileSystem); - s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap. of()); - } - - @Test(expected = IllegalArgumentException.class) - public void createWithWrongEnv() { - Map env = ImmutableMap. builder().put(ACCESS_KEY, 1234).put(SECRET_KEY, "secret key").build(); - FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, env); - assertNotNull(fileSystem); - s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); - } - - @Test - public void getFileSystem() { - FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); - assertNotNull(fileSystem); - fileSystem = s3fsProvider.getFileSystem(S3_GLOBAL_URI, ImmutableMap. of()); - assertNotNull(fileSystem); - FileSystem other = s3fsProvider.getFileSystem(S3_GLOBAL_URI); - assertSame(fileSystem, other); - } - - @Test - public void getUnknownFileSystem() { - FileSystem fileSystem = s3fsProvider.getFileSystem(URI.create("s3://endpoint20/bucket/path/to/file"), ImmutableMap. of()); - assertNotNull(fileSystem); - } - - @Test - public void getPathWithEmtpyEndpoint() throws IOException { - FileSystem fs = FileSystems.newFileSystem(URI.create("s3:///"), ImmutableMap. of()); - Path path = fs.provider().getPath(URI.create("s3:///bucket/path/to/file")); - - assertEquals(path, fs.getPath("/bucket/path/to/file")); - assertSame(path.getFileSystem(), fs); - } - - @Test - public void getPath() throws IOException { - - FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint1/"), null); - Path path = fs.provider().getPath(URI.create("s3://endpoint1/bucket/path/to/file")); - - assertEquals(path, fs.getPath("/bucket/path/to/file")); - assertSame(path.getFileSystem(), fs); - } - - @Test - public void getAnotherPath() throws IOException { - FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint1/"), ImmutableMap. of()); - Path path = fs.provider().getPath(URI.create("s3://endpoint1/bucket/path/to/file")); - - assertEquals(path, fs.getPath("/bucket/path/to/file")); - assertSame(path.getFileSystem(), fs); - } - - @Test(expected = IllegalArgumentException.class) - public void getPathWithEndpointAndWithoutBucket() throws IOException { - FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint1/"), null); - fs.provider().getPath(URI.create("s3://endpoint1//falta-bucket")); - } - - @Test(expected = IllegalArgumentException.class) - public void getPathWithDefaultEndpointAndWithoutBucket() throws IOException { - FileSystem fs = FileSystems.newFileSystem(URI.create("s3:///"), ImmutableMap. of()); - fs.provider().getPath(URI.create("s3:////falta-bucket")); - } - - @Test - public void closeFileSystemReturnNewFileSystem() throws IOException { - S3FileSystemProvider provider = new S3FileSystemProvider(); - Map env = buildFakeEnv(); - FileSystem fileSystem = provider.newFileSystem(S3_GLOBAL_URI, env); - assertNotNull(fileSystem); - fileSystem.close(); - FileSystem fileSystem2 = provider.newFileSystem(S3_GLOBAL_URI, env); - assertNotSame(fileSystem, fileSystem2); - } - - @Test(expected = FileSystemAlreadyExistsException.class) - public void createTwoFileSystemThrowError() { - S3FileSystemProvider provider = new S3FileSystemProvider(); - Map env = buildFakeEnv(); - FileSystem fileSystem = provider.newFileSystem(S3_GLOBAL_URI, env); - assertNotNull(fileSystem); - provider.newFileSystem(S3_GLOBAL_URI, env); - } - - // stream directory - - @Test - public void createStreamDirectoryReader() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file1"); - - // act - Path bucket = createNewS3FileSystem().getPath("/bucketA"); - // assert - assertNewDirectoryStream(bucket, "file1"); - } - - @Test - public void createAnotherStreamDirectoryReader() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file1", "file2"); - - // act - Path bucket = createNewS3FileSystem().getPath("/bucketA"); - - // assert - assertNewDirectoryStream(bucket, "file1", "file2"); - } - - @Test - public void createAnotherWithDirStreamDirectoryReader() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir1").file("file1"); - - // act - Path bucket = createNewS3FileSystem().getPath("/bucketA"); - - // assert - assertNewDirectoryStream(bucket, "file1", "dir1"); - } - - @Test - public void createStreamDirectoryFromDirectoryReader() throws IOException { - - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir", "dir/file2").file("dir/file1"); - // act - Path dir = createNewS3FileSystem().getPath("/bucketA", "dir"); - - // assert - assertNewDirectoryStream(dir, "file1", "file2"); - } - - - @Test(expected = UnsupportedOperationException.class) - public void removeIteratorStreamDirectoryReader() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir1").file("dir1/file1", "content".getBytes()); - - // act - Path bucket = createNewS3FileSystem().getPath("/bucketA"); - - // act - try (DirectoryStream dir = Files.newDirectoryStream(bucket)) { - dir.iterator().remove(); - } - - } - - @Test - public void list999Paths() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket bucketA = client.bucket("bucketA"); - final int count999 = 999; - for (int i = 0; i < count999; i++) { - bucketA.file(i + "file"); - } - Path bucket = createNewS3FileSystem().getPath("/bucketA"); - int count = 0; - try (DirectoryStream files = Files.newDirectoryStream(bucket)) { - Iterator iterator = files.iterator(); - while (iterator.hasNext()) { - iterator.next(); - count++; - } - } - assertEquals(count999, count); - } - - @Test - public void list1050Paths() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket bucketA = client.bucket("bucketA"); - final int count1050 = 1050; - for (int i = 0; i < count1050; i++) { - bucketA.file(i + "file"); - } - Path bucket = createNewS3FileSystem().getPath("/bucketA"); - int count = 0; - try (DirectoryStream files = Files.newDirectoryStream(bucket)) { - Iterator iterator = files.iterator(); - while (iterator.hasNext()) { - iterator.next(); - count++; - } - } - assertEquals(count1050, count); - } - - // newInputStream - - @Test - public void inputStreamFile() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file1", "content".getBytes()); - - Path file = createNewS3FileSystem().getPath("/bucketA/file1"); - try (InputStream inputStream = s3fsProvider.newInputStream(file)){ + @Test(expected = IllegalArgumentException.class) + public void createWithOnlyAccessKey() { + Properties props = new Properties(); + props.setProperty(ACCESS_KEY, "better access key"); + doReturn(props).when(s3fsProvider).loadAmazonProperties(); + s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + } + + @Test(expected = IllegalArgumentException.class) + public void createWithOnlySecretKey() { + Properties props = new Properties(); + props.setProperty(SECRET_KEY, "better secret key"); + doReturn(props).when(s3fsProvider).loadAmazonProperties(); + s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + } + + @Test(expected = FileSystemAlreadyExistsException.class) + public void createFailsIfAlreadyCreated() { + FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + assertNotNull(fileSystem); + s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + } + + @Test(expected = IllegalArgumentException.class) + public void createWithWrongEnv() { + Map env = ImmutableMap.builder().put(ACCESS_KEY, 1234).put(SECRET_KEY, "secret key").build(); + FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, env); + assertNotNull(fileSystem); + s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + } + + @Test + public void getFileSystem() { + FileSystem fileSystem = s3fsProvider.newFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + assertNotNull(fileSystem); + fileSystem = s3fsProvider.getFileSystem(S3_GLOBAL_URI, ImmutableMap.of()); + assertNotNull(fileSystem); + FileSystem other = s3fsProvider.getFileSystem(S3_GLOBAL_URI); + assertSame(fileSystem, other); + } + + @Test + public void getUnknownFileSystem() { + FileSystem fileSystem = s3fsProvider.getFileSystem(URI.create("s3://endpoint20/bucket/path/to/file"), ImmutableMap.of()); + assertNotNull(fileSystem); + } + + @Test + public void getPathWithEmtpyEndpoint() throws IOException { + FileSystem fs = FileSystems.newFileSystem(URI.create("s3:///"), ImmutableMap.of()); + Path path = fs.provider().getPath(URI.create("s3:///bucket/path/to/file")); + + assertEquals(path, fs.getPath("/bucket/path/to/file")); + assertSame(path.getFileSystem(), fs); + } + + @Test + public void getPath() throws IOException { + + FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint1/"), null); + Path path = fs.provider().getPath(URI.create("s3://endpoint1/bucket/path/to/file")); + + assertEquals(path, fs.getPath("/bucket/path/to/file")); + assertSame(path.getFileSystem(), fs); + } + + @Test + public void getAnotherPath() throws IOException { + FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint1/"), ImmutableMap.of()); + Path path = fs.provider().getPath(URI.create("s3://endpoint1/bucket/path/to/file")); + + assertEquals(path, fs.getPath("/bucket/path/to/file")); + assertSame(path.getFileSystem(), fs); + } + + @Test(expected = IllegalArgumentException.class) + public void getPathWithEndpointAndWithoutBucket() throws IOException { + FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint1/"), null); + fs.provider().getPath(URI.create("s3://endpoint1//falta-bucket")); + } + + @Test(expected = IllegalArgumentException.class) + public void getPathWithDefaultEndpointAndWithoutBucket() throws IOException { + FileSystem fs = FileSystems.newFileSystem(URI.create("s3:///"), ImmutableMap.of()); + fs.provider().getPath(URI.create("s3:////falta-bucket")); + } + + @Test + public void closeFileSystemReturnNewFileSystem() throws IOException { + S3FileSystemProvider provider = new S3FileSystemProvider(); + Map env = buildFakeEnv(); + FileSystem fileSystem = provider.newFileSystem(S3_GLOBAL_URI, env); + assertNotNull(fileSystem); + fileSystem.close(); + FileSystem fileSystem2 = provider.newFileSystem(S3_GLOBAL_URI, env); + assertNotSame(fileSystem, fileSystem2); + } + + @Test(expected = FileSystemAlreadyExistsException.class) + public void createTwoFileSystemThrowError() { + S3FileSystemProvider provider = new S3FileSystemProvider(); + Map env = buildFakeEnv(); + FileSystem fileSystem = provider.newFileSystem(S3_GLOBAL_URI, env); + assertNotNull(fileSystem); + provider.newFileSystem(S3_GLOBAL_URI, env); + } + + // stream directory + + @Test + public void createStreamDirectoryReader() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file1"); + + // act + Path bucket = createNewS3FileSystem().getPath("/bucketA"); + // assert + assertNewDirectoryStream(bucket, "file1"); + } + + @Test + public void createAnotherStreamDirectoryReader() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file1", "file2"); + + // act + Path bucket = createNewS3FileSystem().getPath("/bucketA"); + + // assert + assertNewDirectoryStream(bucket, "file1", "file2"); + } + + @Test + public void createAnotherWithDirStreamDirectoryReader() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir1").file("file1"); + + // act + Path bucket = createNewS3FileSystem().getPath("/bucketA"); + + // assert + assertNewDirectoryStream(bucket, "file1", "dir1"); + } + + @Test + public void createStreamDirectoryFromDirectoryReader() throws IOException { + + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir", "dir/file2").file("dir/file1"); + // act + Path dir = createNewS3FileSystem().getPath("/bucketA", "dir"); + + // assert + assertNewDirectoryStream(dir, "file1", "file2"); + } + + + @Test(expected = UnsupportedOperationException.class) + public void removeIteratorStreamDirectoryReader() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir1").file("dir1/file1", "content".getBytes()); + + // act + Path bucket = createNewS3FileSystem().getPath("/bucketA"); + + // act + try (DirectoryStream dir = Files.newDirectoryStream(bucket)) { + dir.iterator().remove(); + } + + } + + @Test + public void list999Paths() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket bucketA = client.bucket("bucketA"); + final int count999 = 999; + for (int i = 0; i < count999; i++) { + bucketA.file(i + "file"); + } + Path bucket = createNewS3FileSystem().getPath("/bucketA"); + int count = 0; + try (DirectoryStream files = Files.newDirectoryStream(bucket)) { + Iterator iterator = files.iterator(); + while (iterator.hasNext()) { + iterator.next(); + count++; + } + } + assertEquals(count999, count); + } + + @Test + public void list1050Paths() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket bucketA = client.bucket("bucketA"); + final int count1050 = 1050; + for (int i = 0; i < count1050; i++) { + bucketA.file(i + "file"); + } + Path bucket = createNewS3FileSystem().getPath("/bucketA"); + int count = 0; + try (DirectoryStream files = Files.newDirectoryStream(bucket)) { + Iterator iterator = files.iterator(); + while (iterator.hasNext()) { + iterator.next(); + count++; + } + } + assertEquals(count1050, count); + } + + // newInputStream + + @Test + public void inputStreamFile() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file1", "content".getBytes()); + + Path file = createNewS3FileSystem().getPath("/bucketA/file1"); + try (InputStream inputStream = s3fsProvider.newInputStream(file)) { byte[] buffer = IOUtils.toByteArray(inputStream); // check assertArrayEquals("content".getBytes(), buffer); } - } + } - @Test - public void anotherInputStreamFile() throws IOException { - String res = "another content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1", res.getBytes()); - // act - Path file = createNewS3FileSystem().getPath("/bucketA/dir/file1"); + @Test + public void anotherInputStreamFile() throws IOException { + String res = "another content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1", res.getBytes()); + // act + Path file = createNewS3FileSystem().getPath("/bucketA/dir/file1"); - try (InputStream inputStream = s3fsProvider.newInputStream(file)){ + try (InputStream inputStream = s3fsProvider.newInputStream(file)) { byte[] buffer = IOUtils.toByteArray(inputStream); // check assertArrayEquals(res.getBytes(), buffer); } - } + } @Test(expected = NoSuchFileException.class) public void newInputStreamFileNotExists() throws IOException { @@ -415,37 +415,37 @@ public void newInputStreamFileNotExists() throws IOException { // act S3FileSystem fileSystem = createNewS3FileSystem(); Path file = fileSystem.getPath("/bucketA/dir/file1"); - try (InputStream inputStream = s3fsProvider.newInputStream(file)){ + try (InputStream inputStream = s3fsProvider.newInputStream(file)) { fail("file not exists"); } } - @Test(expected = IOException.class) - public void inputStreamDirectory() throws IOException { - // fixtures - Path result = getS3Directory(); - // act - s3fsProvider.newInputStream(result); - } + @Test(expected = IOException.class) + public void inputStreamDirectory() throws IOException { + // fixtures + Path result = getS3Directory(); + // act + s3fsProvider.newInputStream(result); + } - // newOutputStream + // newOutputStream - @Test - public void outputStreamWithCreateNew() throws IOException { - Path base = getS3Directory(); + @Test + public void outputStreamWithCreateNew() throws IOException { + Path base = getS3Directory(); - Path file = base.resolve("file1"); - final String content = "sample content"; + Path file = base.resolve("file1"); + final String content = "sample content"; - try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE_NEW)) { - stream.write(content.getBytes()); - stream.flush(); - } - // get the input - byte[] buffer = Files.readAllBytes(file); - // check - assertArrayEquals(content.getBytes(), buffer); - } + try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE_NEW)) { + stream.write(content.getBytes()); + stream.flush(); + } + // get the input + byte[] buffer = Files.readAllBytes(file); + // check + assertArrayEquals(content.getBytes(), buffer); + } @Test public void outputStreamWithTruncate() throws IOException { @@ -470,713 +470,713 @@ public void outputStreamWithTruncate() throws IOException { assertArrayEquals(res.getBytes(), buffer); } - @Test(expected = FileAlreadyExistsException.class) - public void outputStreamWithCreateNewAndFileExists() throws IOException { - Path base = getS3Directory(); - Path file = Files.createFile(base.resolve("file1")); - s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE_NEW); - } - - @Test - public void outputStreamWithCreateAndFileExists() throws IOException { - Path base = getS3Directory(); - - Path file = base.resolve("file1"); - Files.createFile(file); - - final String content = "sample content"; - - try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE)) { - stream.write(content.getBytes()); - stream.flush(); - stream.close(); - } - // get the input - byte[] buffer = Files.readAllBytes(file); - // check - assertArrayEquals(content.getBytes(), buffer); - } - - @Test - public void outputStreamWithCreateAndFileNotExists() throws IOException { - Path base = getS3Directory(); - - Path file = base.resolve("file1"); - - try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE)) { - stream.write("sample content".getBytes()); - stream.flush(); - } - // get the input - byte[] buffer = Files.readAllBytes(file); - // check - assertArrayEquals("sample content".getBytes(), buffer); - } - - @Test - public void anotherOutputStream() throws IOException { - Path base = getS3Directory(); - final String content = "heyyyyyy"; - Path file = base.resolve("file1"); - - try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE_NEW)) { - stream.write(content.getBytes()); - stream.flush(); - } - // get the input - byte[] buffer = Files.readAllBytes(file); - // check - assertArrayEquals(content.getBytes(), buffer); - } - - // seekable - - @Test - public void seekable() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", "".getBytes()); - - Path base = createNewS3FileSystem().getPath("/bucketA", "dir"); - - final String content = "content"; - - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { - ByteBuffer buffer = ByteBuffer.wrap(content.getBytes()); - seekable.write(buffer); - ByteBuffer bufferRead = ByteBuffer.allocate(7); - seekable.position(0); - seekable.read(bufferRead); - - assertArrayEquals(bufferRead.array(), buffer.array()); - seekable.close(); - } - - assertArrayEquals(content.getBytes(), Files.readAllBytes(base.resolve("file"))); - } - - @Test - public void seekableSize() throws IOException { - final String content = "content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { - long size = seekable.size(); - assertEquals(content.length(), size); - } - } - - @Test - public void seekableAnotherSize() throws IOException { - final String content = "content-more-large"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { - long size = seekable.size(); - assertEquals(content.length(), size); - } - } - - @Test - public void seekablePosition() throws IOException { - final String content = "content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { - long position = seekable.position(); - assertEquals(0, position); - - seekable.position(10); - long position2 = seekable.position(); - assertEquals(10, position2); - } - } - - @Test - public void seekablePositionRead() throws IOException { - final String content = "content-more-larger"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - ByteBuffer copy = ByteBuffer.allocate(3); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.READ))) { - long position = seekable.position(); - assertEquals(0, position); - - seekable.read(copy); - long position2 = seekable.position(); - assertEquals(3, position2); - } - } - - @Test - public void seekablePositionWrite() throws IOException { - final String content = "content-more-larger"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - ByteBuffer copy = ByteBuffer.allocate(5); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE))) { - long position = seekable.position(); - assertEquals(0, position); - - seekable.write(copy); - long position2 = seekable.position(); - assertEquals(5, position2); - } - } - - @Test - public void seekableIsOpen() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file"); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE))) { - assertTrue(seekable.isOpen()); - } - SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.READ)); - assertTrue(seekable.isOpen()); - seekable.close(); - assertTrue(!seekable.isOpen()); - } - - @Test - public void seekableRead() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - final String content = "content"; - Path file = Files.write(base.resolve("file"), content.getBytes()); - ByteBuffer bufferRead = ByteBuffer.allocate(7); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.READ))) { - seekable.position(0); - seekable.read(bufferRead); - } - assertArrayEquals(bufferRead.array(), content.getBytes()); - assertArrayEquals(content.getBytes(), Files.readAllBytes(base.resolve("file"))); - } - - @Test - public void seekableReadPartialContent() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - final String content = "content"; - Path file = Files.write(base.resolve("file"), content.getBytes()); - ByteBuffer bufferRead = ByteBuffer.allocate(4); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.READ))) { - seekable.position(3); - seekable.read(bufferRead); - } - assertArrayEquals(bufferRead.array(), "tent".getBytes()); - assertArrayEquals("content".getBytes(), Files.readAllBytes(base.resolve("file"))); - } - - @Test - public void seekableTruncate() throws IOException { - final String content = "content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { - // discard all content except the first c. - seekable.truncate(1); - } - assertArrayEquals("c".getBytes(), Files.readAllBytes(file)); - } - - @Test - public void seekableAnotherTruncate() throws IOException { - final String content = "content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { - // discard all content except the first three chars 'con' - seekable.truncate(3); - } - assertArrayEquals("con".getBytes(), Files.readAllBytes(file)); - } - - @Test - public void seekableruncateGreatherThanSize() throws IOException { - final String content = "content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); - - Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { - seekable.truncate(10); - } - assertArrayEquals(content.getBytes(), Files.readAllBytes(file)); - } - - @Test - public void seekableCreateEmpty() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - Path file = base.resolve("file"); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.CREATE))) { - // - } - assertTrue(Files.exists(file)); - assertArrayEquals("".getBytes(), Files.readAllBytes(file)); - } - - @Test - public void seekableDeleteOnClose() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - Path file = Files.createFile(base.resolve("file")); - try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.DELETE_ON_CLOSE))) { - seekable.close(); - } - assertTrue(Files.notExists(file)); - } - - @Test - public void seekableCloseTwice() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - Path file = Files.createFile(base.resolve("file")); - SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.noneOf(StandardOpenOption.class)); - seekable.close(); - seekable.close(); - assertTrue(Files.exists(file)); - } - - @Test - public void createDirectory() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA"); - - // act - Path base = createNewS3FileSystem().getPath("/bucketA/dir"); - Files.createDirectory(base); - // assert - assertTrue(Files.exists(base)); - assertTrue(Files.isDirectory(base)); - assertTrue(Files.exists(base)); - } + @Test(expected = FileAlreadyExistsException.class) + public void outputStreamWithCreateNewAndFileExists() throws IOException { + Path base = getS3Directory(); + Path file = Files.createFile(base.resolve("file1")); + s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE_NEW); + } + + @Test + public void outputStreamWithCreateAndFileExists() throws IOException { + Path base = getS3Directory(); + + Path file = base.resolve("file1"); + Files.createFile(file); + final String content = "sample content"; + + try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE)) { + stream.write(content.getBytes()); + stream.flush(); + stream.close(); + } + // get the input + byte[] buffer = Files.readAllBytes(file); + // check + assertArrayEquals(content.getBytes(), buffer); + } @Test - public void createDirectoryInNewBucket() throws IOException { - S3Path root = createNewS3FileSystem().getPath("/newer-bucket"); - Path resolve = root.resolve("folder"); - Path path = Files.createDirectories(resolve); - assertEquals("/newer-bucket/folder", path.toAbsolutePath().toString()); - // assert - assertTrue(Files.exists(root)); - assertTrue(Files.isDirectory(root)); - assertTrue(Files.exists(root)); - assertTrue(Files.exists(resolve)); - assertTrue(Files.isDirectory(resolve)); - assertTrue(Files.exists(resolve)); + public void outputStreamWithCreateAndFileNotExists() throws IOException { + Path base = getS3Directory(); + + Path file = base.resolve("file1"); + + try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE)) { + stream.write("sample content".getBytes()); + stream.flush(); + } + // get the input + byte[] buffer = Files.readAllBytes(file); + // check + assertArrayEquals("sample content".getBytes(), buffer); } @Test - public void createDirectoryWithSpace() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA"); + public void anotherOutputStream() throws IOException { + Path base = getS3Directory(); + final String content = "heyyyyyy"; + Path file = base.resolve("file1"); - // act - Path base = createNewS3FileSystem().getPath("/bucketA/dir with space/another space"); - Files.createDirectories(base); - // assert - assertTrue(Files.exists(base)); - assertTrue(Files.isDirectory(base)); - // parent - assertTrue(Files.exists(base.getParent())); - assertTrue(Files.isDirectory(base.getParent())); + try (OutputStream stream = s3fsProvider.newOutputStream(file, StandardOpenOption.CREATE_NEW)) { + stream.write(content.getBytes()); + stream.flush(); + } + // get the input + byte[] buffer = Files.readAllBytes(file); + // check + assertArrayEquals(content.getBytes(), buffer); } - @Test - public void deleteFile() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file"); - // act - Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); - s3fsProvider.delete(file); - // assert - assertTrue(Files.notExists(file)); - } - - @Test - public void deleteEmptyDirectory() throws IOException { - Path base = getS3Directory(); - s3fsProvider.delete(base); - // assert - assertTrue(Files.notExists(base)); - } - - @Test(expected = DirectoryNotEmptyException.class) - public void deleteDirectoryWithEntries() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file"); - - Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); - s3fsProvider.delete(file.getParent()); - } - - @Test(expected = NoSuchFileException.class) - public void deleteFileNotExists() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); - s3fsProvider.delete(file); - } - - // copy - - @Test - public void copy() throws IOException { - final String content = "content-file-1"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir", "dir2").file("dir/file1", content.getBytes()); - - // act - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA/dir/file1"); - Path fileDest = fs.getPath("/bucketA", "dir2", "file2"); - s3fsProvider.copy(file, fileDest, StandardCopyOption.REPLACE_EXISTING); - // assert - assertTrue(Files.exists(fileDest)); - assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); - } - - @Test - public void copySameFile() throws IOException { - final String content = "sample-content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()); - // act - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA", "dir", "file1"); - Path fileDest = fs.getPath("/bucketA", "dir", "file1"); - s3fsProvider.copy(file, fileDest); - // assert - assertTrue(Files.exists(fileDest)); - assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); - assertEquals(file, fileDest); - } - - @Test - public void copyAlreadyExistsWithReplace() throws IOException { - final String content = "sample-content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()).file("dir/file2"); - // act - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA", "dir", "file1"); - Path fileDest = fs.getPath("/bucketA", "dir", "file2"); - s3fsProvider.copy(file, fileDest, StandardCopyOption.REPLACE_EXISTING); - // assert - assertTrue(Files.exists(fileDest)); - assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); - } - - @Test(expected = FileAlreadyExistsException.class) - public void copyAlreadyExists() throws IOException { - final String content = "sample-content"; - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()).file("dir/file2", content.getBytes()); - // act - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA", "dir", "file1"); - Path fileDest = fs.getPath("/bucketA", "dir", "file2"); - s3fsProvider.copy(file, fileDest); - } - - @Test - public void move() throws IOException { - // fixtures - final String content = "sample-content"; - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir","dir2").file("dir/file1", content.getBytes()); - // act - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA/dir/file1"); - Path fileDest = fs.getPath("/bucketA", "dir2", "file2"); - s3fsProvider.move(file, fileDest); - // assert - assertTrue(Files.exists(fileDest)); - assertTrue(Files.notExists(file)); - assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); - } + // seekable @Test - public void moveWithReplaceExisting() throws IOException { + public void seekable() throws IOException { // fixtures - final String content = "sample-content"; AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir") - .file("dir/file1", content.getBytes()) - .file("dir/file2", "different-content".getBytes()); - // act - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA/dir/file1"); - Path fileDest = fs.getPath("/bucketA", "dir", "file2"); - s3fsProvider.move(file, fileDest, StandardCopyOption.REPLACE_EXISTING); - // assert - assertTrue(Files.exists(fileDest)); - assertTrue(Files.notExists(file)); - assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); + client.bucket("bucketA").dir("dir").file("dir/file", "".getBytes()); + + Path base = createNewS3FileSystem().getPath("/bucketA", "dir"); + + final String content = "content"; + + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { + ByteBuffer buffer = ByteBuffer.wrap(content.getBytes()); + seekable.write(buffer); + ByteBuffer bufferRead = ByteBuffer.allocate(7); + seekable.position(0); + seekable.read(bufferRead); + + assertArrayEquals(bufferRead.array(), buffer.array()); + seekable.close(); + } + + assertArrayEquals(content.getBytes(), Files.readAllBytes(base.resolve("file"))); } - @Test(expected = FileAlreadyExistsException.class) - public void moveWithoutReplaceExisting() throws IOException { + @Test + public void seekableSize() throws IOException { + final String content = "content"; // fixtures - final String content = "sample-content"; AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir") - .file("dir/file1", content.getBytes()) - .file("dir/file2", "different-content".getBytes()); - // act - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA/dir/file1"); - Path fileDest = fs.getPath("/bucketA", "dir", "file2"); - s3fsProvider.move(file, fileDest); + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { + long size = seekable.size(); + assertEquals(content.length(), size); + } } - @Test(expected = AtomicMoveNotSupportedException.class) - public void moveWithAtomicOption() throws IOException { + @Test + public void seekableAnotherSize() throws IOException { + final String content = "content-more-large"; // fixtures - final String content = "sample-content"; AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir", "dir2").file("dir/file1", content.getBytes()); - // act + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { + long size = seekable.size(); + assertEquals(content.length(), size); + } + } + + @Test + public void seekablePosition() throws IOException { + final String content = "content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { + long position = seekable.position(); + assertEquals(0, position); + + seekable.position(10); + long position2 = seekable.position(); + assertEquals(10, position2); + } + } + + @Test + public void seekablePositionRead() throws IOException { + final String content = "content-more-larger"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + ByteBuffer copy = ByteBuffer.allocate(3); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.READ))) { + long position = seekable.position(); + assertEquals(0, position); + + seekable.read(copy); + long position2 = seekable.position(); + assertEquals(3, position2); + } + } + + @Test + public void seekablePositionWrite() throws IOException { + final String content = "content-more-larger"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + ByteBuffer copy = ByteBuffer.allocate(5); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE))) { + long position = seekable.position(); + assertEquals(0, position); + + seekable.write(copy); + long position2 = seekable.position(); + assertEquals(5, position2); + } + } + + @Test + public void seekableIsOpen() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file"); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.WRITE))) { + assertTrue(seekable.isOpen()); + } + SeekableByteChannel seekable = s3fsProvider.newByteChannel(base.resolve("file"), EnumSet.of(StandardOpenOption.READ)); + assertTrue(seekable.isOpen()); + seekable.close(); + assertTrue(!seekable.isOpen()); + } + + @Test + public void seekableRead() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + final String content = "content"; + Path file = Files.write(base.resolve("file"), content.getBytes()); + ByteBuffer bufferRead = ByteBuffer.allocate(7); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.READ))) { + seekable.position(0); + seekable.read(bufferRead); + } + assertArrayEquals(bufferRead.array(), content.getBytes()); + assertArrayEquals(content.getBytes(), Files.readAllBytes(base.resolve("file"))); + } + + @Test + public void seekableReadPartialContent() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + final String content = "content"; + Path file = Files.write(base.resolve("file"), content.getBytes()); + ByteBuffer bufferRead = ByteBuffer.allocate(4); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.READ))) { + seekable.position(3); + seekable.read(bufferRead); + } + assertArrayEquals(bufferRead.array(), "tent".getBytes()); + assertArrayEquals("content".getBytes(), Files.readAllBytes(base.resolve("file"))); + } + + @Test + public void seekableTruncate() throws IOException { + final String content = "content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { + // discard all content except the first c. + seekable.truncate(1); + } + assertArrayEquals("c".getBytes(), Files.readAllBytes(file)); + } + + @Test + public void seekableAnotherTruncate() throws IOException { + final String content = "content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { + // discard all content except the first three chars 'con' + seekable.truncate(3); + } + assertArrayEquals("con".getBytes(), Files.readAllBytes(file)); + } + + @Test + public void seekableruncateGreatherThanSize() throws IOException { + final String content = "content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file", content.getBytes()); + + Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ))) { + seekable.truncate(10); + } + assertArrayEquals(content.getBytes(), Files.readAllBytes(file)); + } + + @Test + public void seekableCreateEmpty() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + Path file = base.resolve("file"); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.CREATE))) { + // + } + assertTrue(Files.exists(file)); + assertArrayEquals("".getBytes(), Files.readAllBytes(file)); + } + + @Test + public void seekableDeleteOnClose() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + Path file = Files.createFile(base.resolve("file")); + try (SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.of(StandardOpenOption.DELETE_ON_CLOSE))) { + seekable.close(); + } + assertTrue(Files.notExists(file)); + } + + @Test + public void seekableCloseTwice() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + Path file = Files.createFile(base.resolve("file")); + SeekableByteChannel seekable = s3fsProvider.newByteChannel(file, EnumSet.noneOf(StandardOpenOption.class)); + seekable.close(); + seekable.close(); + assertTrue(Files.exists(file)); + } + + @Test + public void createDirectory() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA"); + + // act + Path base = createNewS3FileSystem().getPath("/bucketA/dir"); + Files.createDirectory(base); + // assert + assertTrue(Files.exists(base)); + assertTrue(Files.isDirectory(base)); + assertTrue(Files.exists(base)); + } + + + @Test + public void createDirectoryInNewBucket() throws IOException { + S3Path root = createNewS3FileSystem().getPath("/newer-bucket"); + Path resolve = root.resolve("folder"); + Path path = Files.createDirectories(resolve); + assertEquals("/newer-bucket/folder", path.toAbsolutePath().toString()); + // assert + assertTrue(Files.exists(root)); + assertTrue(Files.isDirectory(root)); + assertTrue(Files.exists(root)); + assertTrue(Files.exists(resolve)); + assertTrue(Files.isDirectory(resolve)); + assertTrue(Files.exists(resolve)); + } + + @Test + public void createDirectoryWithSpace() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA"); + + // act + Path base = createNewS3FileSystem().getPath("/bucketA/dir with space/another space"); + Files.createDirectories(base); + // assert + assertTrue(Files.exists(base)); + assertTrue(Files.isDirectory(base)); + // parent + assertTrue(Files.exists(base.getParent())); + assertTrue(Files.isDirectory(base.getParent())); + } + + @Test + public void deleteFile() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file"); + // act + Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); + s3fsProvider.delete(file); + // assert + assertTrue(Files.notExists(file)); + } + + @Test + public void deleteEmptyDirectory() throws IOException { + Path base = getS3Directory(); + s3fsProvider.delete(base); + // assert + assertTrue(Files.notExists(base)); + } + + @Test(expected = DirectoryNotEmptyException.class) + public void deleteDirectoryWithEntries() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file"); + + Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); + s3fsProvider.delete(file.getParent()); + } + + @Test(expected = NoSuchFileException.class) + public void deleteFileNotExists() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + Path file = createNewS3FileSystem().getPath("/bucketA/dir/file"); + s3fsProvider.delete(file); + } + + // copy + + @Test + public void copy() throws IOException { + final String content = "content-file-1"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir", "dir2").file("dir/file1", content.getBytes()); + + // act + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file1"); + Path fileDest = fs.getPath("/bucketA", "dir2", "file2"); + s3fsProvider.copy(file, fileDest, StandardCopyOption.REPLACE_EXISTING); + // assert + assertTrue(Files.exists(fileDest)); + assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); + } + + @Test + public void copySameFile() throws IOException { + final String content = "sample-content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()); + // act + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA", "dir", "file1"); + Path fileDest = fs.getPath("/bucketA", "dir", "file1"); + s3fsProvider.copy(file, fileDest); + // assert + assertTrue(Files.exists(fileDest)); + assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); + assertEquals(file, fileDest); + } + + @Test + public void copyAlreadyExistsWithReplace() throws IOException { + final String content = "sample-content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()).file("dir/file2"); + // act + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA", "dir", "file1"); + Path fileDest = fs.getPath("/bucketA", "dir", "file2"); + s3fsProvider.copy(file, fileDest, StandardCopyOption.REPLACE_EXISTING); + // assert + assertTrue(Files.exists(fileDest)); + assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); + } + + @Test(expected = FileAlreadyExistsException.class) + public void copyAlreadyExists() throws IOException { + final String content = "sample-content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()).file("dir/file2", content.getBytes()); + // act + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA", "dir", "file1"); + Path fileDest = fs.getPath("/bucketA", "dir", "file2"); + s3fsProvider.copy(file, fileDest); + } + + @Test + public void move() throws IOException { + // fixtures + final String content = "sample-content"; + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir", "dir2").file("dir/file1", content.getBytes()); + // act + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file1"); + Path fileDest = fs.getPath("/bucketA", "dir2", "file2"); + s3fsProvider.move(file, fileDest); + // assert + assertTrue(Files.exists(fileDest)); + assertTrue(Files.notExists(file)); + assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); + } + + @Test + public void moveWithReplaceExisting() throws IOException { + // fixtures + final String content = "sample-content"; + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir") + .file("dir/file1", content.getBytes()) + .file("dir/file2", "different-content".getBytes()); + // act + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file1"); + Path fileDest = fs.getPath("/bucketA", "dir", "file2"); + s3fsProvider.move(file, fileDest, StandardCopyOption.REPLACE_EXISTING); + // assert + assertTrue(Files.exists(fileDest)); + assertTrue(Files.notExists(file)); + assertArrayEquals(content.getBytes(), Files.readAllBytes(fileDest)); + } + + @Test(expected = FileAlreadyExistsException.class) + public void moveWithoutReplaceExisting() throws IOException { + // fixtures + final String content = "sample-content"; + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir") + .file("dir/file1", content.getBytes()) + .file("dir/file2", "different-content".getBytes()); + // act + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file1"); + Path fileDest = fs.getPath("/bucketA", "dir", "file2"); + s3fsProvider.move(file, fileDest); + } + + @Test(expected = AtomicMoveNotSupportedException.class) + public void moveWithAtomicOption() throws IOException { + // fixtures + final String content = "sample-content"; + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir", "dir2").file("dir/file1", content.getBytes()); + // act FileSystem fs = createNewS3FileSystem(); Path file = fs.getPath("/bucketA/dir/file1"); Path fileDest = fs.getPath("/bucketA", "dir2", "file2"); s3fsProvider.move(file, fileDest, StandardCopyOption.ATOMIC_MOVE); } - @Test - public void isSameFileTrue() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1"); - // act - FileSystem fs = createNewS3FileSystem(); - Path file1 = fs.getPath("/bucketA/dir/file1"); - Path fileCopy = fs.getPath("/bucketA/dir/file1"); - // assert - assertTrue(s3fsProvider.isSameFile(file1, fileCopy)); - } - - @Test - public void isSameFileFalse() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir", "dir2").file("dir/file1", "dir2/file13"); - // act - FileSystem fs = createNewS3FileSystem(); - Path file1 = fs.getPath("/bucketA/dir/file1"); - Path fileCopy = fs.getPath("/bucketA/dir2/file2"); - // assert - assertTrue(!s3fsProvider.isSameFile(file1, fileCopy)); - } - - // isHidden - - @Test - public void isHidden() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1"); - // act - Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file1"); - // assert - assertTrue(!s3fsProvider.isHidden(file1)); - } - - // getFileStore - - @Test(expected = UnsupportedOperationException.class) - public void getFileStore() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1"); - - // act - Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file1"); - // assert - s3fsProvider.getFileStore(file1); - } - - // getFileAttributeView - - @Test(expected = UnsupportedOperationException.class) - public void getFileAttributeView() { - s3fsProvider.getFileAttributeView(null, null); - } - - // readAttributes - - @Test - public void readAttributesFileEmpty() throws IOException { - // fixtures - final String content = ""; - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()); - - Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file1"); - - BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(file1, BasicFileAttributes.class); - - assertNotNull(fileAttributes); - assertEquals(false, fileAttributes.isDirectory()); - assertEquals(true, fileAttributes.isRegularFile()); - assertEquals(false, fileAttributes.isSymbolicLink()); - assertEquals(false, fileAttributes.isOther()); - assertEquals(0L, fileAttributes.size()); - } - - @Test - public void readAttributesFile() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket mocket = client.bucket("bucketA").dir("dir"); - - final String content = "sample"; - Path memoryFile = Files.write(mocket.resolve("dir/file"), content.getBytes()); - - BasicFileAttributes expectedAttributes = Files.readAttributes(memoryFile, BasicFileAttributes.class); - - FileSystem fs = createNewS3FileSystem(); - Path file = fs.getPath("/bucketA/dir/file"); - - BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(file, BasicFileAttributes.class); - - assertNotNull(fileAttributes); - assertEquals(false, fileAttributes.isDirectory()); - assertEquals(true, fileAttributes.isRegularFile()); - assertEquals(false, fileAttributes.isSymbolicLink()); - assertEquals(false, fileAttributes.isOther()); - assertEquals(content.getBytes().length, fileAttributes.size()); - assertEquals("dir/file", fileAttributes.fileKey()); - assertEquals(expectedAttributes.lastModifiedTime(), fileAttributes.lastModifiedTime()); - // TODO: creation and access are the same that last modified time - assertEquals(fileAttributes.lastModifiedTime(), fileAttributes.creationTime()); - assertEquals(fileAttributes.lastModifiedTime(), fileAttributes.lastAccessTime()); - } - - @Test - public void readAttributesDirectory() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket mocket = client.bucket("bucketA").dir("dir"); - Path memoryDir = mocket.resolve("dir/"); - - BasicFileAttributes expectedAttributes = Files.readAttributes(memoryDir, BasicFileAttributes.class); - - FileSystem fs = createNewS3FileSystem(); - Path dir = fs.getPath("/bucketA/dir"); - - BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(dir, BasicFileAttributes.class); - - assertNotNull(fileAttributes); - assertEquals(true, fileAttributes.isDirectory()); - assertEquals(false, fileAttributes.isRegularFile()); - assertEquals(false, fileAttributes.isSymbolicLink()); - assertEquals(false, fileAttributes.isOther()); - assertEquals(0L, fileAttributes.size()); - assertEquals("dir/", fileAttributes.fileKey()); - assertEquals(expectedAttributes.lastModifiedTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); - assertEquals(expectedAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.creationTime().to(TimeUnit.SECONDS)); - assertEquals(expectedAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastAccessTime().to(TimeUnit.SECONDS)); - // TODO: creation and access are the same that last modified time - assertEquals(fileAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); - assertEquals(fileAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); - } - - @Test - public void readAnotherAttributesDirectory() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/dir", "content".getBytes()); - - FileSystem fs = createNewS3FileSystem(); - Path dir = fs.getPath("/bucketA/dir"); - - BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(dir, BasicFileAttributes.class); - assertNotNull(fileAttributes); - assertEquals(true, fileAttributes.isDirectory()); - } - - @Test - public void readAttributesDirectoryNotExistsAtAmazon() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket mocket = client.bucket("bucketA").dir("dir", "dir/dir2"); - Path memoryDir = mocket.resolve("dir/dir2/"); - - BasicFileAttributes expectedAttributes = Files.readAttributes(memoryDir, BasicFileAttributes.class); - - FileSystem fs = createNewS3FileSystem(); - Path dir = fs.getPath("/bucketA/dir"); - - BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(dir, BasicFileAttributes.class); - - assertNotNull(fileAttributes); - assertEquals(true, fileAttributes.isDirectory()); - assertEquals(false, fileAttributes.isRegularFile()); - assertEquals(false, fileAttributes.isSymbolicLink()); - assertEquals(false, fileAttributes.isOther()); - assertEquals(0L, fileAttributes.size()); - assertEquals("dir/", fileAttributes.fileKey()); - assertEquals(expectedAttributes.lastModifiedTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); - assertEquals(expectedAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.creationTime().to(TimeUnit.SECONDS)); - assertEquals(expectedAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastAccessTime().to(TimeUnit.SECONDS)); - // TODO: creation and access are the same that last modified time - assertEquals(fileAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); - assertEquals(fileAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); - } + @Test + public void isSameFileTrue() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1"); + // act + FileSystem fs = createNewS3FileSystem(); + Path file1 = fs.getPath("/bucketA/dir/file1"); + Path fileCopy = fs.getPath("/bucketA/dir/file1"); + // assert + assertTrue(s3fsProvider.isSameFile(file1, fileCopy)); + } + + @Test + public void isSameFileFalse() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir", "dir2").file("dir/file1", "dir2/file13"); + // act + FileSystem fs = createNewS3FileSystem(); + Path file1 = fs.getPath("/bucketA/dir/file1"); + Path fileCopy = fs.getPath("/bucketA/dir2/file2"); + // assert + assertTrue(!s3fsProvider.isSameFile(file1, fileCopy)); + } + + // isHidden + + @Test + public void isHidden() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1"); + // act + Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file1"); + // assert + assertTrue(!s3fsProvider.isHidden(file1)); + } + + // getFileStore + + @Test(expected = UnsupportedOperationException.class) + public void getFileStore() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1"); + + // act + Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file1"); + // assert + s3fsProvider.getFileStore(file1); + } + + // getFileAttributeView + + @Test(expected = UnsupportedOperationException.class) + public void getFileAttributeView() { + s3fsProvider.getFileAttributeView(null, null); + } + + // readAttributes + + @Test + public void readAttributesFileEmpty() throws IOException { + // fixtures + final String content = ""; + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1", content.getBytes()); + + Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file1"); + + BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(file1, BasicFileAttributes.class); + + assertNotNull(fileAttributes); + assertEquals(false, fileAttributes.isDirectory()); + assertEquals(true, fileAttributes.isRegularFile()); + assertEquals(false, fileAttributes.isSymbolicLink()); + assertEquals(false, fileAttributes.isOther()); + assertEquals(0L, fileAttributes.size()); + } + + @Test + public void readAttributesFile() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket mocket = client.bucket("bucketA").dir("dir"); + + final String content = "sample"; + Path memoryFile = Files.write(mocket.resolve("dir/file"), content.getBytes()); + + BasicFileAttributes expectedAttributes = Files.readAttributes(memoryFile, BasicFileAttributes.class); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(file, BasicFileAttributes.class); + + assertNotNull(fileAttributes); + assertEquals(false, fileAttributes.isDirectory()); + assertEquals(true, fileAttributes.isRegularFile()); + assertEquals(false, fileAttributes.isSymbolicLink()); + assertEquals(false, fileAttributes.isOther()); + assertEquals(content.getBytes().length, fileAttributes.size()); + assertEquals("dir/file", fileAttributes.fileKey()); + assertEquals(expectedAttributes.lastModifiedTime(), fileAttributes.lastModifiedTime()); + // TODO: creation and access are the same that last modified time + assertEquals(fileAttributes.lastModifiedTime(), fileAttributes.creationTime()); + assertEquals(fileAttributes.lastModifiedTime(), fileAttributes.lastAccessTime()); + } + + @Test + public void readAttributesDirectory() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket mocket = client.bucket("bucketA").dir("dir"); + Path memoryDir = mocket.resolve("dir/"); + + BasicFileAttributes expectedAttributes = Files.readAttributes(memoryDir, BasicFileAttributes.class); + + FileSystem fs = createNewS3FileSystem(); + Path dir = fs.getPath("/bucketA/dir"); + + BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(dir, BasicFileAttributes.class); + + assertNotNull(fileAttributes); + assertEquals(true, fileAttributes.isDirectory()); + assertEquals(false, fileAttributes.isRegularFile()); + assertEquals(false, fileAttributes.isSymbolicLink()); + assertEquals(false, fileAttributes.isOther()); + assertEquals(0L, fileAttributes.size()); + assertEquals("dir/", fileAttributes.fileKey()); + assertEquals(expectedAttributes.lastModifiedTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); + assertEquals(expectedAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.creationTime().to(TimeUnit.SECONDS)); + assertEquals(expectedAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastAccessTime().to(TimeUnit.SECONDS)); + // TODO: creation and access are the same that last modified time + assertEquals(fileAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); + assertEquals(fileAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); + } + + @Test + public void readAnotherAttributesDirectory() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/dir", "content".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path dir = fs.getPath("/bucketA/dir"); + + BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(dir, BasicFileAttributes.class); + assertNotNull(fileAttributes); + assertEquals(true, fileAttributes.isDirectory()); + } + + @Test + public void readAttributesDirectoryNotExistsAtAmazon() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket mocket = client.bucket("bucketA").dir("dir", "dir/dir2"); + Path memoryDir = mocket.resolve("dir/dir2/"); + + BasicFileAttributes expectedAttributes = Files.readAttributes(memoryDir, BasicFileAttributes.class); + + FileSystem fs = createNewS3FileSystem(); + Path dir = fs.getPath("/bucketA/dir"); + + BasicFileAttributes fileAttributes = s3fsProvider.readAttributes(dir, BasicFileAttributes.class); + + assertNotNull(fileAttributes); + assertEquals(true, fileAttributes.isDirectory()); + assertEquals(false, fileAttributes.isRegularFile()); + assertEquals(false, fileAttributes.isSymbolicLink()); + assertEquals(false, fileAttributes.isOther()); + assertEquals(0L, fileAttributes.size()); + assertEquals("dir/", fileAttributes.fileKey()); + assertEquals(expectedAttributes.lastModifiedTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); + assertEquals(expectedAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.creationTime().to(TimeUnit.SECONDS)); + assertEquals(expectedAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastAccessTime().to(TimeUnit.SECONDS)); + // TODO: creation and access are the same that last modified time + assertEquals(fileAttributes.creationTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); + assertEquals(fileAttributes.lastAccessTime().to(TimeUnit.SECONDS), fileAttributes.lastModifiedTime().to(TimeUnit.SECONDS)); + } @Test public void readAttributesRegenerateCacheWhenNotExists() throws IOException { @@ -1197,184 +1197,306 @@ public void readAttributesRegenerateCacheWhenNotExists() throws IOException { assertNotNull(((S3Path) file1).getFileAttributes()); } - @Test(expected = NoSuchFileException.class) - public void readAttributesFileNotExists() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - FileSystem fs = createNewS3FileSystem(); - Path file1 = fs.getPath("/bucketA/dir/file1"); - - s3fsProvider.readAttributes(file1, BasicFileAttributes.class); - } - - @Test(expected = NoSuchFileException.class) - public void readAttributesFileNotExistsButExistsAnotherThatContainsTheKey() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1hola", "content".getBytes()); - - FileSystem fs = createNewS3FileSystem(); - Path file1 = fs.getPath("/bucketA/dir/file1"); - - s3fsProvider.readAttributes(file1, BasicFileAttributes.class); - } - - @Test(expected = UnsupportedOperationException.class) - public void readAttributesNotAcceptedSubclass() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - FileSystem fs = createNewS3FileSystem(); - Path dir = fs.getPath("/bucketA/dir"); - s3fsProvider.readAttributes(dir, DosFileAttributes.class); - } - - @Test(expected = UnsupportedOperationException.class) - public void readAttributesString() throws IOException { - s3fsProvider.readAttributes(null, ""); - } - - // setAttribute - - @Test(expected = UnsupportedOperationException.class) - public void readAttributesObject() throws IOException { - s3fsProvider.setAttribute(null, "", new Object()); - } - - // check access - - @Test - public void checkAccessRead() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file"); - - FileSystem fs = createNewS3FileSystem(); - Path file1 = fs.getPath("/bucketA/dir/file"); - s3fsProvider.checkAccess(file1, AccessMode.READ); - } - - @Test(expected = AccessDeniedException.class) - public void checkAccessReadWithoutPermission() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - FileSystem fs = createNewS3FileSystem(); - Path file1 = fs.getPath("/bucketA/dir"); - s3fsProvider.checkAccess(file1, AccessMode.READ); - } - - @Test - public void checkAccessWrite() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file"); - - S3FileSystem fs = createNewS3FileSystem(); - S3Path file1 = fs.getPath("/bucketA/dir/file"); - //S3AccessControlList acl = file1.getFileStore().getAccessControlList(file1); - //assertEquals("dir/file", acl.getKey()); - s3fsProvider.checkAccess(file1, AccessMode.WRITE); - } - - @Test(expected = AccessDeniedException.class) - public void checkAccessWriteDifferentUser() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/readOnly"); - // return empty list - doReturn(client.createReadOnly(new Owner("2", "Read Only"))).when(client).getObjectAcl("bucketA", "dir/readOnly"); - - S3FileSystem fs = createNewS3FileSystem(); - S3Path file1 = fs.getPath("/bucketA/dir/readOnly"); - s3fsProvider.checkAccess(file1, AccessMode.WRITE); - } - - @Test(expected = AccessDeniedException.class) - public void checkAccessWriteWithoutPermission() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - // return empty list - doReturn(new AccessControlList()).when(client).getObjectAcl("bucketA", "dir/"); - - Path file1 = createNewS3FileSystem().getPath("/bucketA/dir"); - s3fsProvider.checkAccess(file1, AccessMode.WRITE); - } - - @Test(expected = AccessDeniedException.class) - public void checkAccessExecute() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file"); - - Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file"); - - s3fsProvider.checkAccess(file1, AccessMode.EXECUTE); - } - - private Map buildFakeEnv() { - return ImmutableMap. builder().put(ACCESS_KEY, "access key").put(SECRET_KEY, "secret key").build(); - } - - private Properties buildFakeProps(String access_key, String secret_key, String encoding) { - Properties props = buildFakeProps(access_key, secret_key); - props.setProperty(CHARSET_KEY, encoding); - return props; - } - - private Properties buildFakeProps(String access_key, String secret_key) { - Properties props = new Properties(); - props.setProperty(AMAZON_S3_FACTORY_CLASS, "com.upplication.s3fs.util.AmazonS3MockFactory"); - if (access_key != null) - props.setProperty(ACCESS_KEY, access_key); - if (secret_key != null) - props.setProperty(SECRET_KEY, secret_key); - return props; - } - - private void assertNewDirectoryStream(Path base, final String... files) throws IOException { - try (DirectoryStream dir = Files.newDirectoryStream(base)) { - assertNotNull(dir); - assertNotNull(dir.iterator()); - assertTrue(dir.iterator().hasNext()); - - Set filesNamesExpected = new HashSet<>(Arrays.asList(files)); - Set filesNamesActual = new HashSet<>(); - - for (Path path : dir) { - String fileName = path.getFileName().toString(); - filesNamesActual.add(fileName); - } - - assertEquals(filesNamesExpected, filesNamesActual); - } - } - - private Path getS3Directory() throws IOException { - // fixtures - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - return s3fsProvider.newFileSystem(URI.create("s3://endpoint1/"), buildFakeEnv()).getPath("/bucketA/dir"); - } - - /** - * create a new file system for s3 scheme with fake credentials - * and global endpoint - * @return FileSystem - * @throws IOException - */ - private S3FileSystem createNewS3FileSystem() throws IOException { + @Test(expected = NoSuchFileException.class) + public void readAttributesFileNotExists() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + FileSystem fs = createNewS3FileSystem(); + Path file1 = fs.getPath("/bucketA/dir/file1"); + + s3fsProvider.readAttributes(file1, BasicFileAttributes.class); + } + + @Test(expected = NoSuchFileException.class) + public void readAttributesFileNotExistsButExistsAnotherThatContainsTheKey() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1hola", "content".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file1 = fs.getPath("/bucketA/dir/file1"); + + s3fsProvider.readAttributes(file1, BasicFileAttributes.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void readAttributesNotAcceptedSubclass() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + FileSystem fs = createNewS3FileSystem(); + Path dir = fs.getPath("/bucketA/dir"); + s3fsProvider.readAttributes(dir, DosFileAttributes.class); + } + + @Test + public void readAttributesAll() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + final String content = "sample"; + Path memoryFile = Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), content.getBytes()); + + BasicFileAttributes expectedAttributes = Files.readAttributes(memoryFile, BasicFileAttributes.class); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + Map fileAttributes = s3fsProvider.readAttributes(file, "*"); + + assertNotNull(fileAttributes); + assertEquals(false, fileAttributes.get("isDirectory")); + assertEquals(true, fileAttributes.get("isRegularFile")); + assertEquals(false, fileAttributes.get("isSymbolicLink")); + assertEquals(false, fileAttributes.get("isOther")); + assertEquals((long) content.getBytes().length, fileAttributes.get("size")); + assertEquals("dir/file", fileAttributes.get("fileKey")); + assertEquals(expectedAttributes.lastModifiedTime(), fileAttributes.get("lastModifiedTime")); + assertEquals(expectedAttributes.lastModifiedTime(), fileAttributes.get("creationTime")); + assertEquals(expectedAttributes.lastModifiedTime(), fileAttributes.get("lastAccessTime")); + } + + @Test + public void readAttributesAllBasic() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), "sample".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + Map fileAttributes = s3fsProvider.readAttributes(file, "basic:*"); + Map fileAttributes2 = s3fsProvider.readAttributes(file, "*"); + + assertArrayEquals(fileAttributes.values().toArray(new Object[]{}), + fileAttributes2.values().toArray(new Object[]{})); + assertArrayEquals(fileAttributes.keySet().toArray(new String[]{}), + fileAttributes2.keySet().toArray(new String[]{})); + } + + @Test + public void readAttributesPartial() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), "sample".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + Map fileAttributes = s3fsProvider.readAttributes(file, "isDirectory,isRegularFile"); + + assertNotNull(fileAttributes); + assertEquals(false, fileAttributes.get("isDirectory")); + assertEquals(true, fileAttributes.get("isRegularFile")); + assertEquals(2, fileAttributes.size()); + } + + @Test + public void readAttributesPartialBasic() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), "sample".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + Map fileAttributes = s3fsProvider.readAttributes(file, "basic:isOther,basic:creationTime"); + Map fileAttributes2 = s3fsProvider.readAttributes(file, "isOther,creationTime"); + + assertArrayEquals(fileAttributes.values().toArray(new Object[]{}), + fileAttributes2.values().toArray(new Object[]{})); + assertArrayEquals(fileAttributes.keySet().toArray(new String[]{}), + fileAttributes2.keySet().toArray(new String[]{})); + } + + @Test(expected = IllegalArgumentException.class) + public void readAttributesNullAttrs() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), "sample".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + s3fsProvider.readAttributes(file, (String) null); + } + + @Test(expected = UnsupportedOperationException.class) + public void readAttributesPosixNotSupported() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), "sample".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + s3fsProvider.readAttributes(file, "posix:*"); + } + + @Test(expected = UnsupportedOperationException.class) + public void readAttributesDosNotSupported() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), "sample".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + s3fsProvider.readAttributes(file, "dos:*"); + } + + @Test(expected = UnsupportedOperationException.class) + public void readAttributesUnknowNotSupported() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + Files.write(client.bucket("bucketA").dir("dir").resolve("dir/file"), "sample".getBytes()); + + FileSystem fs = createNewS3FileSystem(); + Path file = fs.getPath("/bucketA/dir/file"); + + s3fsProvider.readAttributes(file, "lelel:*"); + } + + // setAttribute + + @Test(expected = UnsupportedOperationException.class) + public void readAttributesObject() throws IOException { + s3fsProvider.setAttribute(null, "", new Object()); + } + + // check access + + @Test + public void checkAccessRead() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file"); + + FileSystem fs = createNewS3FileSystem(); + Path file1 = fs.getPath("/bucketA/dir/file"); + s3fsProvider.checkAccess(file1, AccessMode.READ); + } + + @Test(expected = AccessDeniedException.class) + public void checkAccessReadWithoutPermission() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + FileSystem fs = createNewS3FileSystem(); + Path file1 = fs.getPath("/bucketA/dir"); + s3fsProvider.checkAccess(file1, AccessMode.READ); + } + + @Test + public void checkAccessWrite() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file"); + + S3FileSystem fs = createNewS3FileSystem(); + S3Path file1 = fs.getPath("/bucketA/dir/file"); + //S3AccessControlList acl = file1.getFileStore().getAccessControlList(file1); + //assertEquals("dir/file", acl.getKey()); + s3fsProvider.checkAccess(file1, AccessMode.WRITE); + } + + @Test(expected = AccessDeniedException.class) + public void checkAccessWriteDifferentUser() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/readOnly"); + // return empty list + doReturn(client.createReadOnly(new Owner("2", "Read Only"))).when(client).getObjectAcl("bucketA", "dir/readOnly"); + + S3FileSystem fs = createNewS3FileSystem(); + S3Path file1 = fs.getPath("/bucketA/dir/readOnly"); + s3fsProvider.checkAccess(file1, AccessMode.WRITE); + } + + @Test(expected = AccessDeniedException.class) + public void checkAccessWriteWithoutPermission() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + // return empty list + doReturn(new AccessControlList()).when(client).getObjectAcl("bucketA", "dir/"); + + Path file1 = createNewS3FileSystem().getPath("/bucketA/dir"); + s3fsProvider.checkAccess(file1, AccessMode.WRITE); + } + + @Test(expected = AccessDeniedException.class) + public void checkAccessExecute() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file"); + + Path file1 = createNewS3FileSystem().getPath("/bucketA/dir/file"); + + s3fsProvider.checkAccess(file1, AccessMode.EXECUTE); + } + + private Map buildFakeEnv() { + return ImmutableMap.builder().put(ACCESS_KEY, "access key").put(SECRET_KEY, "secret key").build(); + } + + private Properties buildFakeProps(String access_key, String secret_key, String encoding) { + Properties props = buildFakeProps(access_key, secret_key); + props.setProperty(CHARSET_KEY, encoding); + return props; + } + + private Properties buildFakeProps(String access_key, String secret_key) { + Properties props = new Properties(); + props.setProperty(AMAZON_S3_FACTORY_CLASS, "com.upplication.s3fs.util.AmazonS3MockFactory"); + if (access_key != null) + props.setProperty(ACCESS_KEY, access_key); + if (secret_key != null) + props.setProperty(SECRET_KEY, secret_key); + return props; + } + + private void assertNewDirectoryStream(Path base, final String... files) throws IOException { + try (DirectoryStream dir = Files.newDirectoryStream(base)) { + assertNotNull(dir); + assertNotNull(dir.iterator()); + assertTrue(dir.iterator().hasNext()); + + Set filesNamesExpected = new HashSet<>(Arrays.asList(files)); + Set filesNamesActual = new HashSet<>(); + + for (Path path : dir) { + String fileName = path.getFileName().toString(); + filesNamesActual.add(fileName); + } + + assertEquals(filesNamesExpected, filesNamesActual); + } + } + + private Path getS3Directory() throws IOException { + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + return s3fsProvider.newFileSystem(URI.create("s3://endpoint1/"), buildFakeEnv()).getPath("/bucketA/dir"); + } + + /** + * create a new file system for s3 scheme with fake credentials + * and global endpoint + * + * @return FileSystem + * @throws IOException + */ + private S3FileSystem createNewS3FileSystem() throws IOException { try { return s3fsProvider.getFileSystem(S3_GLOBAL_URI); - } - catch (FileSystemNotFoundException e){ + } catch (FileSystemNotFoundException e) { return (S3FileSystem) FileSystems.newFileSystem(S3_GLOBAL_URI, null); } - } + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/S3FileSystemTest.java b/src/test/java/com/upplication/s3fs/S3FileSystemTest.java index 82d4215..9b6c1d9 100644 --- a/src/test/java/com/upplication/s3fs/S3FileSystemTest.java +++ b/src/test/java/com/upplication/s3fs/S3FileSystemTest.java @@ -28,278 +28,278 @@ import com.upplication.s3fs.util.AmazonS3MockFactory; public class S3FileSystemTest extends S3UnitTestBase { - private FileSystem fs; - - @Before - public void setup() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA"); - client.bucket("bucketB"); - fs = FileSystems.newFileSystem(S3_GLOBAL_URI, null); - } - - @Test - public void getPathFirst() { - assertEquals(fs.getPath("/bucket"), fs.getPath("/bucket")); - assertEquals(fs.getPath("file"), fs.getPath("file")); - } - - @Test - public void getPathFirstWithMultiplesPaths() { - assertEquals(fs.getPath("/bucket/path/to/file"), fs.getPath("/bucket/path/to/file")); - assertNotEquals(fs.getPath("/bucket/path/other/file"), fs.getPath("/bucket/path/to/file")); - - assertEquals(fs.getPath("dir/path/to/file"), fs.getPath("dir/path/to/file")); - assertNotEquals(fs.getPath("dir/path/other/file"), fs.getPath("dir/path/to/file")); - } - - @Test - public void getPathFirstAndMore() { - Path actualAbsolute = fs.getPath("/bucket", "dir", "file"); - assertEquals(fs.getPath("/bucket", "dir", "file"), actualAbsolute); - assertEquals(fs.getPath("/bucket/dir/file"), actualAbsolute); - - Path actualRelative = fs.getPath("dir", "dir", "file"); - assertEquals(fs.getPath("dir", "dir", "file"), actualRelative); - assertEquals(fs.getPath("dir/dir/file"), actualRelative); - } - - @Test - public void getPathFirstAndMoreWithMultiplesPaths() { - Path actual = fs.getPath("/bucket", "dir/file"); - assertEquals(fs.getPath("/bucket", "dir/file"), actual); - assertEquals(fs.getPath("/bucket/dir/file"), actual); - assertEquals(fs.getPath("/bucket", "dir", "file"), actual); - } - - @Test - public void getPathFirstWithMultiplesPathsAndMoreWithMultiplesPaths() { - Path actual = fs.getPath("/bucket/dir", "dir/file"); - assertEquals(fs.getPath("/bucket/dir", "dir/file"), actual); - assertEquals(fs.getPath("/bucket/dir/dir/file"), actual); - assertEquals(fs.getPath("/bucket", "dir", "dir", "file"), actual); - assertEquals(fs.getPath("/bucket/dir/dir", "file"), actual); - } - - @Test - public void getPathRelativeAndAbsoulte() { - assertNotEquals(fs.getPath("/bucket"), fs.getPath("bucket")); - assertNotEquals(fs.getPath("/bucket/dir"), fs.getPath("bucket/dir")); - assertNotEquals(fs.getPath("/bucket", "dir"), fs.getPath("bucket", "dir")); - assertNotEquals(fs.getPath("/bucket/dir", "dir"), fs.getPath("bucket/dir", "dir")); - assertNotEquals(fs.getPath("/bucket", "dir/file"), fs.getPath("bucket", "dir/file")); - assertNotEquals(fs.getPath("/bucket/dir", "dir/file"), fs.getPath("bucket/dir", "dir/file")); - } - - @Test - public void duplicatedSlashesAreDeleted() { - Path actualFirst = fs.getPath("/bucket//file"); - assertEquals(fs.getPath("/bucket/file"), actualFirst); - assertEquals(fs.getPath("/bucket", "file"), actualFirst); - - Path actualFirstAndMore = fs.getPath("/bucket//dir", "dir//file"); - assertEquals(fs.getPath("/bucket/dir/dir/file"), actualFirstAndMore); - assertEquals(fs.getPath("/bucket", "dir/dir/file"), actualFirstAndMore); - assertEquals(fs.getPath("/bucket/dir", "dir/file"), actualFirstAndMore); - assertEquals(fs.getPath("/bucket/dir/dir", "file"), actualFirstAndMore); - } - - @Test - public void readOnlyAlwaysFalse() { - assertTrue(!fs.isReadOnly()); - } - - @Test - public void getSeparatorSlash() { - assertEquals("/", fs.getSeparator()); - assertEquals("/", S3Path.PATH_SEPARATOR); - } - - @Test(expected = UnsupportedOperationException.class) - public void getPathMatcherThrowException() { - fs.getPathMatcher(""); - } - - @Test(expected = UnsupportedOperationException.class) - public void getUserPrincipalLookupServiceThrowException() { - fs.getUserPrincipalLookupService(); - } - - @Test(expected = UnsupportedOperationException.class) - public void newWatchServiceThrowException() throws Exception { - fs.newWatchService(); - } - - @Test(expected = IllegalArgumentException.class) - public void getPathWithoutBucket() { - fs.getPath("//path/to/file"); - } - - @Test - public void getFileStores() { - Iterable result = fs.getFileStores(); - assertNotNull(result); - Iterator iterator = result.iterator(); - assertNotNull(iterator); - assertTrue(iterator.hasNext()); - assertNotNull(iterator.next()); - } - - @Test - public void getRootDirectoriesReturnBuckets() { - - Iterable paths = fs.getRootDirectories(); - - assertNotNull(paths); - - int size = 0; - boolean bucketNameA = false; - boolean bucketNameB = false; - - for (Path path : paths) { - String name = path.getFileName().toString(); - if (name.equals("bucketA")) { - bucketNameA = true; - } else if (name.equals("bucketB")) { - bucketNameB = true; - } - size++; - } - - assertEquals(2, size); - assertTrue(bucketNameA); - assertTrue(bucketNameB); - } - - @Test - public void supportedFileAttributeViewsReturnBasic() { - Set operations = fs.supportedFileAttributeViews(); - - assertNotNull(operations); - assertTrue(!operations.isEmpty()); - - for (String operation : operations) { - assertEquals("basic", operation); - } - } - - @Test - public void getRootDirectories() { - fs.getRootDirectories(); - } - - @Test - public void close() throws IOException { - assertTrue(fs.isOpen()); - fs.close(); - assertTrue(!fs.isOpen()); - } - - private static void assertNotEquals(Object a, Object b) { - assertTrue(a + " are not equal to: " + b, !a.equals(b)); - } - - @Test - public void comparables() throws IOException { + private FileSystem fs; + + @Before + public void setup() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA"); + client.bucket("bucketB"); + fs = FileSystems.newFileSystem(S3_GLOBAL_URI, null); + } + + @Test + public void getPathFirst() { + assertEquals(fs.getPath("/bucket"), fs.getPath("/bucket")); + assertEquals(fs.getPath("file"), fs.getPath("file")); + } + + @Test + public void getPathFirstWithMultiplesPaths() { + assertEquals(fs.getPath("/bucket/path/to/file"), fs.getPath("/bucket/path/to/file")); + assertNotEquals(fs.getPath("/bucket/path/other/file"), fs.getPath("/bucket/path/to/file")); + + assertEquals(fs.getPath("dir/path/to/file"), fs.getPath("dir/path/to/file")); + assertNotEquals(fs.getPath("dir/path/other/file"), fs.getPath("dir/path/to/file")); + } + + @Test + public void getPathFirstAndMore() { + Path actualAbsolute = fs.getPath("/bucket", "dir", "file"); + assertEquals(fs.getPath("/bucket", "dir", "file"), actualAbsolute); + assertEquals(fs.getPath("/bucket/dir/file"), actualAbsolute); + + Path actualRelative = fs.getPath("dir", "dir", "file"); + assertEquals(fs.getPath("dir", "dir", "file"), actualRelative); + assertEquals(fs.getPath("dir/dir/file"), actualRelative); + } + + @Test + public void getPathFirstAndMoreWithMultiplesPaths() { + Path actual = fs.getPath("/bucket", "dir/file"); + assertEquals(fs.getPath("/bucket", "dir/file"), actual); + assertEquals(fs.getPath("/bucket/dir/file"), actual); + assertEquals(fs.getPath("/bucket", "dir", "file"), actual); + } + + @Test + public void getPathFirstWithMultiplesPathsAndMoreWithMultiplesPaths() { + Path actual = fs.getPath("/bucket/dir", "dir/file"); + assertEquals(fs.getPath("/bucket/dir", "dir/file"), actual); + assertEquals(fs.getPath("/bucket/dir/dir/file"), actual); + assertEquals(fs.getPath("/bucket", "dir", "dir", "file"), actual); + assertEquals(fs.getPath("/bucket/dir/dir", "file"), actual); + } + + @Test + public void getPathRelativeAndAbsoulte() { + assertNotEquals(fs.getPath("/bucket"), fs.getPath("bucket")); + assertNotEquals(fs.getPath("/bucket/dir"), fs.getPath("bucket/dir")); + assertNotEquals(fs.getPath("/bucket", "dir"), fs.getPath("bucket", "dir")); + assertNotEquals(fs.getPath("/bucket/dir", "dir"), fs.getPath("bucket/dir", "dir")); + assertNotEquals(fs.getPath("/bucket", "dir/file"), fs.getPath("bucket", "dir/file")); + assertNotEquals(fs.getPath("/bucket/dir", "dir/file"), fs.getPath("bucket/dir", "dir/file")); + } + + @Test + public void duplicatedSlashesAreDeleted() { + Path actualFirst = fs.getPath("/bucket//file"); + assertEquals(fs.getPath("/bucket/file"), actualFirst); + assertEquals(fs.getPath("/bucket", "file"), actualFirst); + + Path actualFirstAndMore = fs.getPath("/bucket//dir", "dir//file"); + assertEquals(fs.getPath("/bucket/dir/dir/file"), actualFirstAndMore); + assertEquals(fs.getPath("/bucket", "dir/dir/file"), actualFirstAndMore); + assertEquals(fs.getPath("/bucket/dir", "dir/file"), actualFirstAndMore); + assertEquals(fs.getPath("/bucket/dir/dir", "file"), actualFirstAndMore); + } + + @Test + public void readOnlyAlwaysFalse() { + assertTrue(!fs.isReadOnly()); + } + + @Test + public void getSeparatorSlash() { + assertEquals("/", fs.getSeparator()); + assertEquals("/", S3Path.PATH_SEPARATOR); + } + + @Test(expected = UnsupportedOperationException.class) + public void getPathMatcherThrowException() { + fs.getPathMatcher(""); + } + + @Test(expected = UnsupportedOperationException.class) + public void getUserPrincipalLookupServiceThrowException() { + fs.getUserPrincipalLookupService(); + } + + @Test(expected = UnsupportedOperationException.class) + public void newWatchServiceThrowException() throws Exception { + fs.newWatchService(); + } + + @Test(expected = IllegalArgumentException.class) + public void getPathWithoutBucket() { + fs.getPath("//path/to/file"); + } + + @Test + public void getFileStores() { + Iterable result = fs.getFileStores(); + assertNotNull(result); + Iterator iterator = result.iterator(); + assertNotNull(iterator); + assertTrue(iterator.hasNext()); + assertNotNull(iterator.next()); + } + + @Test + public void getRootDirectoriesReturnBuckets() { + + Iterable paths = fs.getRootDirectories(); + + assertNotNull(paths); + + int size = 0; + boolean bucketNameA = false; + boolean bucketNameB = false; + + for (Path path : paths) { + String name = path.getFileName().toString(); + if (name.equals("bucketA")) { + bucketNameA = true; + } else if (name.equals("bucketB")) { + bucketNameB = true; + } + size++; + } + + assertEquals(2, size); + assertTrue(bucketNameA); + assertTrue(bucketNameB); + } + + @Test + public void supportedFileAttributeViewsReturnBasic() { + Set operations = fs.supportedFileAttributeViews(); + + assertNotNull(operations); + assertTrue(!operations.isEmpty()); + + for (String operation : operations) { + assertEquals("basic", operation); + } + } + + @Test + public void getRootDirectories() { + fs.getRootDirectories(); + } + + @Test + public void close() throws IOException { + assertTrue(fs.isOpen()); + fs.close(); + assertTrue(!fs.isOpen()); + } + + private static void assertNotEquals(Object a, Object b) { + assertTrue(a + " are not equal to: " + b, !a.equals(b)); + } + + @Test + public void comparables() throws IOException { // crear other vars - S3FileSystemProvider provider = new S3FileSystemProvider(); - S3FileSystem s3fs1 = (S3FileSystem) provider.newFileSystem(URI.create("s3://mirror1.amazon.test/"), buildFakeEnv()); - S3FileSystem s3fs2 = (S3FileSystem) provider.newFileSystem(URI.create("s3://mirror2.amazon.test/"), buildFakeEnv()); - S3FileSystem s3fs3 = (S3FileSystem) provider.newFileSystem(URI.create("s3://accessKey:secretKey@mirror1.amazon.test/"), null); - S3FileSystem s3fs4 = (S3FileSystem) provider.newFileSystem(URI.create("s3://accessKey:secretKey@mirror2.amazon.test"), null); - S3FileSystem s3fs6 = (S3FileSystem) provider.newFileSystem(URI.create("s3://access_key:secret_key@mirror1.amazon.test/"), null); - AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); - S3FileSystem s3fs7 = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); - S3FileSystem s3fs8 = new S3FileSystem(provider, null, amazonClientMock, null); - S3FileSystem s3fs9 = new S3FileSystem(provider, null, amazonClientMock, null); - S3FileSystem s3fs10 = new S3FileSystem(provider, "somekey", amazonClientMock, null); - S3FileSystem s3fs11 = new S3FileSystem(provider, "access-key@mirror2.amazon.test", amazonClientMock, "mirror2.amazon.test"); - + S3FileSystemProvider provider = new S3FileSystemProvider(); + S3FileSystem s3fs1 = (S3FileSystem) provider.newFileSystem(URI.create("s3://mirror1.amazon.test/"), buildFakeEnv()); + S3FileSystem s3fs2 = (S3FileSystem) provider.newFileSystem(URI.create("s3://mirror2.amazon.test/"), buildFakeEnv()); + S3FileSystem s3fs3 = (S3FileSystem) provider.newFileSystem(URI.create("s3://accessKey:secretKey@mirror1.amazon.test/"), null); + S3FileSystem s3fs4 = (S3FileSystem) provider.newFileSystem(URI.create("s3://accessKey:secretKey@mirror2.amazon.test"), null); + S3FileSystem s3fs6 = (S3FileSystem) provider.newFileSystem(URI.create("s3://access_key:secret_key@mirror1.amazon.test/"), null); + AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); + S3FileSystem s3fs7 = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); + S3FileSystem s3fs8 = new S3FileSystem(provider, null, amazonClientMock, null); + S3FileSystem s3fs9 = new S3FileSystem(provider, null, amazonClientMock, null); + S3FileSystem s3fs10 = new S3FileSystem(provider, "somekey", amazonClientMock, null); + S3FileSystem s3fs11 = new S3FileSystem(provider, "access-key@mirror2.amazon.test", amazonClientMock, "mirror2.amazon.test"); + // FIXME: review the hashcode creation. - assertEquals(1483378423, s3fs1.hashCode()); - assertEquals(684416791, s3fs2.hashCode()); - assertEquals(182977201, s3fs3.hashCode()); - assertEquals(1163233038, s3fs4.hashCode()); - assertEquals(-498271993, s3fs6.hashCode()); - assertEquals(-82123487, s3fs7.hashCode()); - - assertFalse(s3fs1.equals(s3fs2)); - assertFalse(s3fs1.equals(s3fs3)); - assertFalse(s3fs1.equals(s3fs4)); - assertFalse(s3fs1.equals(s3fs6)); - assertFalse(s3fs3.equals(s3fs4)); - assertFalse(s3fs3.equals(s3fs6)); - assertFalse(s3fs1.equals(s3fs6)); - assertFalse(s3fs1.equals(new S3FileStore(s3fs1, "emmer"))); - assertFalse(s3fs7.equals(s3fs8)); - assertTrue(s3fs8.equals(s3fs8)); - assertFalse(s3fs8.equals(s3fs1)); - assertTrue(s3fs8.equals(s3fs9)); - assertFalse(s3fs9.equals(s3fs10)); - assertTrue(s3fs2.equals(s3fs11)); - - assertEquals(-1, s3fs1.compareTo(s3fs2)); - assertEquals(1, s3fs2.compareTo(s3fs1)); - assertEquals(-50, s3fs1.compareTo(s3fs6)); - - s3fs7.close(); - s3fs8.close(); - s3fs9.close(); - s3fs10.close(); - s3fs11.close(); - } - - @Test - public void key2Parts() { - S3FileSystemProvider provider = new S3FileSystemProvider(); - AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); - S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); - try { - String[] parts = s3fs.key2Parts("/bucket/folder with spaces/file"); - assertEquals("", parts[0]); - assertEquals("bucket", parts[1]); - assertEquals("folder with spaces", parts[2]); - assertEquals("file", parts[3]); - } finally { - try { - s3fs.close(); - } catch (IOException e) { - // ignore - } - } - } - - @Test - public void parts2Key() { - S3FileSystemProvider provider = new S3FileSystemProvider(); - AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); - S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); - S3Path path = s3fs.getPath("/bucket", "folder with spaces", "file"); - try { - assertEquals("folder with spaces/file", path.getKey()); - } finally { - try { - s3fs.close(); - } catch (IOException e) { - // ignore - } - } - } - - @Test - public void urlWithSpecialCharacters() throws IOException { - String fileName = "Ī²eta.png"; - String expected = "https://bucket.s3.amazonaws.com/%CE%B2eta.png"; - - AmazonS3Client amazonS3Client = new AmazonS3Client(); - S3FileSystem s3FileSystem = new S3FileSystem(null, null, amazonS3Client, "mirror"); - S3Path path = new S3Path(s3FileSystem, fileName); - - String url = amazonS3Client.getResourceUrl("bucket", path.getKey()); - - assertEquals(expected, url); - } + assertEquals(1483378423, s3fs1.hashCode()); + assertEquals(684416791, s3fs2.hashCode()); + assertEquals(182977201, s3fs3.hashCode()); + assertEquals(1163233038, s3fs4.hashCode()); + assertEquals(-498271993, s3fs6.hashCode()); + assertEquals(-82123487, s3fs7.hashCode()); + + assertFalse(s3fs1.equals(s3fs2)); + assertFalse(s3fs1.equals(s3fs3)); + assertFalse(s3fs1.equals(s3fs4)); + assertFalse(s3fs1.equals(s3fs6)); + assertFalse(s3fs3.equals(s3fs4)); + assertFalse(s3fs3.equals(s3fs6)); + assertFalse(s3fs1.equals(s3fs6)); + assertFalse(s3fs1.equals(new S3FileStore(s3fs1, "emmer"))); + assertFalse(s3fs7.equals(s3fs8)); + assertTrue(s3fs8.equals(s3fs8)); + assertFalse(s3fs8.equals(s3fs1)); + assertTrue(s3fs8.equals(s3fs9)); + assertFalse(s3fs9.equals(s3fs10)); + assertTrue(s3fs2.equals(s3fs11)); + + assertEquals(-1, s3fs1.compareTo(s3fs2)); + assertEquals(1, s3fs2.compareTo(s3fs1)); + assertEquals(-50, s3fs1.compareTo(s3fs6)); + + s3fs7.close(); + s3fs8.close(); + s3fs9.close(); + s3fs10.close(); + s3fs11.close(); + } + + @Test + public void key2Parts() { + S3FileSystemProvider provider = new S3FileSystemProvider(); + AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); + S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); + try { + String[] parts = s3fs.key2Parts("/bucket/folder with spaces/file"); + assertEquals("", parts[0]); + assertEquals("bucket", parts[1]); + assertEquals("folder with spaces", parts[2]); + assertEquals("file", parts[3]); + } finally { + try { + s3fs.close(); + } catch (IOException e) { + // ignore + } + } + } + + @Test + public void parts2Key() { + S3FileSystemProvider provider = new S3FileSystemProvider(); + AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); + S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); + S3Path path = s3fs.getPath("/bucket", "folder with spaces", "file"); + try { + assertEquals("folder with spaces/file", path.getKey()); + } finally { + try { + s3fs.close(); + } catch (IOException e) { + // ignore + } + } + } + + @Test + public void urlWithSpecialCharacters() throws IOException { + String fileName = "Ī²eta.png"; + String expected = "https://bucket.s3.amazonaws.com/%CE%B2eta.png"; + + AmazonS3Client amazonS3Client = new AmazonS3Client(); + S3FileSystem s3FileSystem = new S3FileSystem(null, null, amazonS3Client, "mirror"); + S3Path path = new S3Path(s3FileSystem, fileName); + + String url = amazonS3Client.getResourceUrl("bucket", path.getKey()); + + assertEquals(expected, url); + } @Test public void urlWithSpaceCharacters() throws IOException { @@ -314,66 +314,66 @@ public void urlWithSpaceCharacters() throws IOException { assertEquals(expected, url); } - - @Test - public void createDirectory() throws IOException { - S3FileSystemProvider provider = new S3FileSystemProvider(); - AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); - S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); - try { - S3Path folder = s3fs.getPath("/bucket", "folder"); - provider.createDirectory(folder); - assertTrue(Files.exists(folder)); - } finally { - try { - s3fs.close(); - } catch (IOException e) { - // ignore - } - } - } - - @Test(expected=IllegalArgumentException.class) - public void createDirectoryWithAttributes() throws IOException { - S3FileSystemProvider provider = new S3FileSystemProvider(); - AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); - S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); - try { - S3Path folder = s3fs.getPath("/bucket", "folder"); - provider.createDirectory(folder, PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrw"))); - } finally { - try { - s3fs.close(); - } catch (IOException e) { - // ignore - } - } - } - - @Test - public void isSameFile() throws IOException { - S3FileSystemProvider provider = new S3FileSystemProvider(); - AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); - S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); - try { - S3Path folder = s3fs.getPath("/bucket", "folder"); - S3Path sameFolder = s3fs.getPath("/bucket", "folder"); - S3Path differentFolder = s3fs.getPath("/bucket", "folder2"); - Path relativize = folder.getParent().relativize(folder); - assertTrue(provider.isSameFile(folder, sameFolder)); - assertFalse(provider.isSameFile(folder, differentFolder)); - assertFalse(provider.isSameFile(folder, relativize)); - assertFalse(provider.isSameFile(relativize, folder)); - } finally { - try { - s3fs.close(); - } catch (IOException e) { - // ignore - } - } - } + + @Test + public void createDirectory() throws IOException { + S3FileSystemProvider provider = new S3FileSystemProvider(); + AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); + S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); + try { + S3Path folder = s3fs.getPath("/bucket", "folder"); + provider.createDirectory(folder); + assertTrue(Files.exists(folder)); + } finally { + try { + s3fs.close(); + } catch (IOException e) { + // ignore + } + } + } + + @Test(expected = IllegalArgumentException.class) + public void createDirectoryWithAttributes() throws IOException { + S3FileSystemProvider provider = new S3FileSystemProvider(); + AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); + S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); + try { + S3Path folder = s3fs.getPath("/bucket", "folder"); + provider.createDirectory(folder, PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrw"))); + } finally { + try { + s3fs.close(); + } catch (IOException e) { + // ignore + } + } + } + + @Test + public void isSameFile() throws IOException { + S3FileSystemProvider provider = new S3FileSystemProvider(); + AmazonS3ClientMock amazonClientMock = AmazonS3MockFactory.getAmazonClientMock(); + S3FileSystem s3fs = new S3FileSystem(provider, null, amazonClientMock, "mirror1.amazon.test"); + try { + S3Path folder = s3fs.getPath("/bucket", "folder"); + S3Path sameFolder = s3fs.getPath("/bucket", "folder"); + S3Path differentFolder = s3fs.getPath("/bucket", "folder2"); + Path relativize = folder.getParent().relativize(folder); + assertTrue(provider.isSameFile(folder, sameFolder)); + assertFalse(provider.isSameFile(folder, differentFolder)); + assertFalse(provider.isSameFile(folder, relativize)); + assertFalse(provider.isSameFile(relativize, folder)); + } finally { + try { + s3fs.close(); + } catch (IOException e) { + // ignore + } + } + } private Map buildFakeEnv() { - return ImmutableMap. builder().put(ACCESS_KEY, "access-key").put(SECRET_KEY, "secret-key").build(); + return ImmutableMap.builder().put(ACCESS_KEY, "access-key").put(SECRET_KEY, "secret-key").build(); } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/S3IteratorTest.java b/src/test/java/com/upplication/s3fs/S3IteratorTest.java index 98d34ab..d106b1c 100644 --- a/src/test/java/com/upplication/s3fs/S3IteratorTest.java +++ b/src/test/java/com/upplication/s3fs/S3IteratorTest.java @@ -29,213 +29,213 @@ public class S3IteratorTest extends S3UnitTestBase { - S3FileSystemProvider provider; + S3FileSystemProvider provider; private static URI endpoint = URI.create("s3://s3iteratortest.test"); - @Before - public void prepare() throws IOException { - provider = spy(new S3FileSystemProvider()); - doReturn(new Properties()).when(provider).loadAmazonProperties(); + @Before + public void prepare() throws IOException { + provider = spy(new S3FileSystemProvider()); + doReturn(new Properties()).when(provider).loadAmazonProperties(); doReturn(false).when(provider).overloadPropertiesWithSystemEnv(any(Properties.class), anyString()); FileSystems.newFileSystem(endpoint, null); reset(AmazonS3MockFactory.getAmazonClientMock()); - } - - @Test - public void iteratorDirectory() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1"); - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA", "dir"); - S3Iterator iterator = new S3Iterator(path); - assertIterator(iterator, "file1"); - } - - @Test - public void iteratorAnotherDirectory() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir2").file("dir2/file1","dir2/file2"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA", "dir2"); - S3Iterator iterator = new S3Iterator(path); - - assertIterator(iterator, "file1", "file2"); - } - - @Test - public void iteratorWithFileContainsDirectoryName() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir2").file("dir2/dir2-file", "dir2-file2"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA", "dir2"); - S3Iterator iterator = new S3Iterator(path); - - assertIterator(iterator, "dir2-file"); - } - - @Test - public void iteratorWithSubFolderAndSubFiles() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir", "dir/dir", "dir/dir2", "dir/dir2/dir3").file("dir/file", "dir/file2", "dir/dir/file", "dir/dir2/file", "dir/dir2/dir3/file"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA", "dir"); - S3Iterator iterator = new S3Iterator(path); - - assertIterator(iterator, "dir", "dir2", "file", "file2"); - } - - @Test - public void iteratorWithSubFolderAndSubFilesAtBucketLevel() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file", "file2", "dir/file3", "dir2/file4", "dir2/dir3/file3").dir("dir", "dir2", "dir2/dir3", "dir4"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA"); - S3Iterator iterator = new S3Iterator(path); - - assertIterator(iterator, "dir", "dir2", "dir4", "file", "file2"); - } - - @Test - public void iteratorFileReturnEmpty() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file1"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA", "file1"); - S3Iterator iterator = new S3Iterator(path); - - assertFalse(iterator.hasNext()); - } - - @Test - public void iteratorEmptyDirectory() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA", "dir"); - S3Iterator iterator = new S3Iterator(path); - - assertFalse(iterator.hasNext()); - } - - @Test - public void iteratorBucket() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file1", "file2", "file3"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA"); - S3Iterator iterator = new S3Iterator(path); - - assertIterator(iterator, "file1", "file2", "file3"); - } - - @Test(expected=NoSuchElementException.class) - public void iteratorExhausted() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file1", "file2", "file3"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA"); - S3Iterator iterator = new S3Iterator(path); - while(iterator.hasNext()) - iterator.next(); - iterator.next(); - } - - @Test - public void iteratorDirs() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("file1", "file2", "file3", "directory1/file1.1", "directory1/file1.2", "directory1/file1.3").dir("directory1"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA"); - S3Iterator iterator = new S3Iterator(path); - - assertIterator(iterator, "directory1", "file1", "file2", "file3"); - } - - @Test - public void virtualDirs() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("directory1/file1.1", "directory1/file1.2", "directory1/file1.3"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA/directory1"); - S3Iterator iterator = new S3Iterator(path); - - assertIterator(iterator, "file1.1", "file1.2", "file1.3"); - path = s3FileSystem.getPath("/bucketA"); - iterator = new S3Iterator(path); - assertIterator(iterator, "directory1"); - } - - @Test - public void incrementalVirtualDirs() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").file("dir/subdir/subberdir/file1.1", "dir/subdir/subberdir/file1.2", "dir/subdir/subberdir/file1.3"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA/dir/subdir"); - S3Iterator iterator = new S3Iterator(path, true); - - assertIterator(iterator, "subdir", "subberdir", "file1.1", "file1.2", "file1.3"); - } - - @Test - public void iteratorMoreThanAmazonS3ClientLimit() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket mocket = client.bucket("bucketD"); - - String filesNameExpected[] = new String[1050]; - for (int i = 0; i < 1050; i++) { - StringBuilder name = new StringBuilder("file-"); - if(i < 1000) - name.append("0"); - if(i < 100) - name.append("0"); - if(i < 10) - name.append("0"); - name.append(i); - mocket.file(name.toString()); - filesNameExpected[i] = name.toString(); - } - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketD"); - S3Iterator iterator = new S3Iterator(path); + } + + @Test + public void iteratorDirectory() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1"); + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA", "dir"); + S3Iterator iterator = new S3Iterator(path); + assertIterator(iterator, "file1"); + } + + @Test + public void iteratorAnotherDirectory() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir2").file("dir2/file1", "dir2/file2"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA", "dir2"); + S3Iterator iterator = new S3Iterator(path); + + assertIterator(iterator, "file1", "file2"); + } + + @Test + public void iteratorWithFileContainsDirectoryName() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir2").file("dir2/dir2-file", "dir2-file2"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA", "dir2"); + S3Iterator iterator = new S3Iterator(path); + + assertIterator(iterator, "dir2-file"); + } + + @Test + public void iteratorWithSubFolderAndSubFiles() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir", "dir/dir", "dir/dir2", "dir/dir2/dir3").file("dir/file", "dir/file2", "dir/dir/file", "dir/dir2/file", "dir/dir2/dir3/file"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA", "dir"); + S3Iterator iterator = new S3Iterator(path); + + assertIterator(iterator, "dir", "dir2", "file", "file2"); + } + + @Test + public void iteratorWithSubFolderAndSubFilesAtBucketLevel() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file", "file2", "dir/file3", "dir2/file4", "dir2/dir3/file3").dir("dir", "dir2", "dir2/dir3", "dir4"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA"); + S3Iterator iterator = new S3Iterator(path); + + assertIterator(iterator, "dir", "dir2", "dir4", "file", "file2"); + } + + @Test + public void iteratorFileReturnEmpty() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file1"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA", "file1"); + S3Iterator iterator = new S3Iterator(path); + + assertFalse(iterator.hasNext()); + } + + @Test + public void iteratorEmptyDirectory() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA", "dir"); + S3Iterator iterator = new S3Iterator(path); + + assertFalse(iterator.hasNext()); + } + + @Test + public void iteratorBucket() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file1", "file2", "file3"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA"); + S3Iterator iterator = new S3Iterator(path); + + assertIterator(iterator, "file1", "file2", "file3"); + } + + @Test(expected = NoSuchElementException.class) + public void iteratorExhausted() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file1", "file2", "file3"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA"); + S3Iterator iterator = new S3Iterator(path); + while (iterator.hasNext()) + iterator.next(); + iterator.next(); + } + + @Test + public void iteratorDirs() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("file1", "file2", "file3", "directory1/file1.1", "directory1/file1.2", "directory1/file1.3").dir("directory1"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA"); + S3Iterator iterator = new S3Iterator(path); + + assertIterator(iterator, "directory1", "file1", "file2", "file3"); + } + + @Test + public void virtualDirs() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("directory1/file1.1", "directory1/file1.2", "directory1/file1.3"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA/directory1"); + S3Iterator iterator = new S3Iterator(path); + + assertIterator(iterator, "file1.1", "file1.2", "file1.3"); + path = s3FileSystem.getPath("/bucketA"); + iterator = new S3Iterator(path); + assertIterator(iterator, "directory1"); + } + + @Test + public void incrementalVirtualDirs() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").file("dir/subdir/subberdir/file1.1", "dir/subdir/subberdir/file1.2", "dir/subdir/subberdir/file1.3"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA/dir/subdir"); + S3Iterator iterator = new S3Iterator(path, true); + + assertIterator(iterator, "subdir", "subberdir", "file1.1", "file1.2", "file1.3"); + } + + @Test + public void iteratorMoreThanAmazonS3ClientLimit() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket mocket = client.bucket("bucketD"); + + String filesNameExpected[] = new String[1050]; + for (int i = 0; i < 1050; i++) { + StringBuilder name = new StringBuilder("file-"); + if (i < 1000) + name.append("0"); + if (i < 100) + name.append("0"); + if (i < 10) + name.append("0"); + name.append(i); + mocket.file(name.toString()); + filesNameExpected[i] = name.toString(); + } + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketD"); + S3Iterator iterator = new S3Iterator(path); assertIterator(iterator, filesNameExpected); verify(client, times(1)).listNextBatchOfObjects(any(ObjectListing.class)); - } - - @Test(expected = UnsupportedOperationException.class) - public void remove() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("bucketA").dir("dir").file("dir/file1"); - - S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); - S3Path path = s3FileSystem.getPath("/bucketA", "dir"); - S3Iterator iterator = new S3Iterator(path); - iterator.remove(); - } - - private void assertIterator(Iterator iterator, final String... files) { - assertNotNull(iterator); - assertTrue(iterator.hasNext()); - List filesNamesExpected = Arrays.asList(files); - List filesNamesActual = new ArrayList<>(); - while (iterator.hasNext()) { - Path path = iterator.next(); - String fileName = path.getFileName().toString(); - filesNamesActual.add(fileName); - } - assertEquals(filesNamesExpected, filesNamesActual); - } + } + + @Test(expected = UnsupportedOperationException.class) + public void remove() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir").file("dir/file1"); + + S3FileSystem s3FileSystem = (S3FileSystem) FileSystems.getFileSystem(endpoint); + S3Path path = s3FileSystem.getPath("/bucketA", "dir"); + S3Iterator iterator = new S3Iterator(path); + iterator.remove(); + } + + private void assertIterator(Iterator iterator, final String... files) { + assertNotNull(iterator); + assertTrue(iterator.hasNext()); + List filesNamesExpected = Arrays.asList(files); + List filesNamesActual = new ArrayList<>(); + while (iterator.hasNext()) { + Path path = iterator.next(); + String fileName = path.getFileName().toString(); + filesNamesActual.add(fileName); + } + assertEquals(filesNamesExpected, filesNamesActual); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/S3PathTest.java b/src/test/java/com/upplication/s3fs/S3PathTest.java index dd6e8c4..1098c97 100644 --- a/src/test/java/com/upplication/s3fs/S3PathTest.java +++ b/src/test/java/com/upplication/s3fs/S3PathTest.java @@ -32,582 +32,582 @@ public void setup() throws IOException { .newFileSystem(S3_GLOBAL_URI, null); } - @Test - public void createNoPath() { - S3Path path = forPath("/bucket"); - - assertEquals("bucket", path.getFileStore().name()); - assertEquals("", path.getKey()); - } - - @Test - public void createWithTrailingSlash() { - S3Path path = forPath("/bucket/"); - - assertEquals(path.getFileStore().name(), "bucket"); - assertEquals(path.getKey(), ""); - } - - @Test - public void createWithPath() { - S3Path path = forPath("/bucket/path/to/file"); - - assertEquals(path.getFileStore().name(), "bucket"); - assertEquals(path.getKey(), "path/to/file"); - } - - @Test - public void createWithPathAndTrailingSlash() { - S3Path path = forPath("/bucket/path/to/file/"); - - assertEquals("bucket", path.getFileStore().name()); - assertEquals("path/to/file", path.getKey()); - } - - @Test - public void createRelative() { - S3Path path = forPath("path/to/file"); - - assertNull(path.getFileStore()); - assertEquals(path.getKey(), "path/to/file"); - assertFalse(path.isAbsolute()); - } - - @Test - public void getParent() { - assertEquals(forPath("/bucket/path/to/"), forPath("/bucket/path/to/file").getParent()); - assertEquals(forPath("/bucket/path/to/"), forPath("/bucket/path/to/file/").getParent()); - assertNull(forPath("/bucket/").getParent()); - assertNull(forPath("/bucket").getParent()); - } - - @Test - public void nameCount() { - assertEquals(forPath("/bucket/path/to/file").getNameCount(), 3); - assertEquals(forPath("/bucket/").getNameCount(), 0); - } - - @Test - public void resolve() { - assertEquals(forPath("/bucket/path/to/dir/").resolve(forPath("child/xyz")), forPath("/bucket/path/to/dir/child/xyz")); - assertEquals(forPath("/bucket/path/to/dir").resolve(forPath("child/xyz")), forPath("/bucket/path/to/dir/child/xyz")); - assertEquals(forPath("/bucket/path/to/file").resolve(forPath("")), forPath("/bucket/path/to/file")); // TODO: should this be "path/to/dir/" - assertEquals(forPath("path/to/file").resolve(forPath("child/xyz")), forPath("path/to/file/child/xyz")); - assertEquals(forPath("path/to/file").resolve(forPath("")), forPath("path/to/file")); // TODO: should this be "path/to/dir/" - assertEquals(forPath("/bucket/path/to/file").resolve(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); - } - - @Test - public void name() { - assertEquals(forPath("/bucket/path/to/file").getName(0), forPath("path/")); - assertEquals(forPath("/bucket/path/to/file").getName(1), forPath("to/")); - assertEquals(forPath("/bucket/path/to/file").getName(2), forPath("file")); - } - - @Test - public void subPath() { - assertEquals(forPath("/bucket/path/to/file").subpath(0, 1), forPath("path/")); - assertEquals(forPath("/bucket/path/to/file").subpath(0, 2), forPath("path/to/")); - assertEquals(forPath("/bucket/path/to/file").subpath(0, 3), forPath("path/to/file")); - assertEquals(forPath("/bucket/path/to/file").subpath(1, 2), forPath("to/")); - assertEquals(forPath("/bucket/path/to/file").subpath(1, 3), forPath("to/file")); - assertEquals(forPath("/bucket/path/to/file").subpath(2, 3), forPath("file")); - } - - @Test - public void iterator() { - Iterator iterator = forPath("/bucket/path/to/file").iterator(); - - assertEquals(iterator.next(), forPath("path/")); - assertEquals(iterator.next(), forPath("to/")); - assertEquals(iterator.next(), forPath("file")); - } - - @Test - public void resolveSibling() { - // absolute (non-root) vs... - assertEquals(forPath("/bucket/path/to/file").resolveSibling(forPath("other/child")), forPath("/bucket/path/to/other/child")); - assertEquals(forPath("/bucket/path/to/file").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); - assertEquals(forPath("/bucket/path/to/file").resolveSibling(forPath("")), forPath("/bucket/path/to/")); - - // absolute (root) vs ... - assertEquals(forPath("/bucket").resolveSibling(forPath("other/child")), forPath("other/child")); - assertEquals(forPath("/bucket").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); - assertEquals(forPath("/bucket").resolveSibling(forPath("")), forPath("")); - - // relative (empty) vs ... - assertEquals(forPath("").resolveSibling(forPath("other/child")), forPath("other/child")); - assertEquals(forPath("").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); - assertEquals(forPath("").resolveSibling(forPath("")), forPath("")); - - // relative (non-empty) vs ... - assertEquals(forPath("path/to/file").resolveSibling(forPath("other/child")), forPath("path/to/other/child")); - assertEquals(forPath("path/to/file").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); - assertEquals(forPath("path/to/file").resolveSibling(forPath("")), forPath("path/to/")); - } - - @Test - public void resolveSiblingString() { - // absolute (non-root) vs... - assertEquals(forPath("/bucket/path/to/file").resolveSibling("other/child"), forPath("/bucket/path/to/other/child")); - assertEquals(forPath("/bucket/path/to/file").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); - assertEquals(forPath("/bucket/path/to/file").resolveSibling(""), forPath("/bucket/path/to/")); - - // absolute (root) vs ... - assertEquals(forPath("/bucket").resolveSibling("other/child"), forPath("other/child")); - assertEquals(forPath("/bucket").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); - assertEquals(forPath("/bucket").resolveSibling(""), forPath("")); - - // relative (empty) vs ... - assertEquals(forPath("").resolveSibling("other/child"), forPath("other/child")); - assertEquals(forPath("").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); - assertEquals(forPath("").resolveSibling(""), forPath("")); - - // relative (non-empty) vs ... - assertEquals(forPath("path/to/file").resolveSibling("other/child"), forPath("path/to/other/child")); - assertEquals(forPath("path/to/file").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); - assertEquals(forPath("path/to/file").resolveSibling(""), forPath("path/to/")); - } - - @Test - public void relativize() { - Path path = forPath("/bucket/path/to/file"); - Path other = forPath("/bucket/path/to/file/hello"); - - assertEquals(forPath("hello"), path.relativize(other)); - - // another - - assertEquals(forPath("file/hello"), forPath("/bucket/path/to/").relativize(forPath("/bucket/path/to/file/hello"))); - - // empty - - assertEquals(forPath(""), forPath("/bucket/path/to/").relativize(forPath("/bucket/path/to/"))); - } - - // to uri - - @Test - public void toUri() { - Path path = forPath("/bucket/path/to/file"); - URI uri = path.toUri(); - - // the scheme is s3 - assertEquals("s3", uri.getScheme()); - - // could get the correct fileSystem - FileSystem fs = FileSystems.getFileSystem(uri); - assertTrue(fs instanceof S3FileSystem); - // the host is the endpoint specified in fileSystem - assertEquals(((S3FileSystem) fs).getEndpoint(), uri.getHost()); - - // bucket name as first path - Path pathActual = fs.provider().getPath(uri); - - assertEquals(path, pathActual); - } - - @Test - public void toUriWithEndpoint() throws IOException { - try (FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint/"), null)) { - Path path = fs.getPath("/bucket/path/to/file"); - URI uri = path.toUri(); - // the scheme is s3 - assertEquals("s3", uri.getScheme()); - assertEquals("endpoint", uri.getHost()); - assertEquals("/bucket/path/to/file", uri.getPath()); - } - } - - // tests startsWith - - @Test - public void startsWith() { - assertTrue(forPath("/bucket/file1").startsWith(forPath("/bucket"))); - } - - @Test - public void startsWithBlank() { - assertFalse(forPath("/bucket/file1").startsWith(forPath(""))); - } - - @Test - public void startsWithBlankRelative() { - assertFalse(forPath("file1").startsWith(forPath(""))); - } - - @Test - public void startsWithBlankBlank() { - assertTrue(forPath("").startsWith(forPath(""))); - } - - @Test - public void startsWithOnlyBuckets() { - assertTrue(forPath("/bucket").startsWith(forPath("/bucket"))); - } - - @Test - public void startsWithRelativeVsAbsolute() { - assertFalse(forPath("/bucket/file1").startsWith(forPath("file1"))); - } - - @Test - public void startsWithRelativeVsAbsoluteInBucket() { - assertFalse(forPath("/bucket/file1").startsWith(forPath("bucket"))); - } - - @Test - public void startsWithFalse() { - assertFalse(forPath("/bucket/file1").startsWith(forPath("/bucket/file1/file2"))); - assertTrue(forPath("/bucket/file1/file2").startsWith(forPath("/bucket/file1"))); - } - - @Test - public void startsWithNotNormalize() { - assertFalse(forPath("/bucket/file1/file2").startsWith(forPath("/bucket/file1/../"))); - } - - @Test - public void startsWithNormalize() { - // in this implementation not exists .. or . special paths - assertFalse(forPath("/bucket/file1/file2").startsWith(forPath("/bucket/file1/../").normalize())); - } - - @Test - public void startsWithRelative() { - assertTrue(forPath("file/file1").startsWith(forPath("file"))); - } - - @Test - public void startsWithDifferentProvider() { - assertFalse(forPath("/bucket/hello").startsWith(Paths.get("/bucket"))); - } - - @Test - public void startsWithString() { - assertTrue(forPath("/bucket/hello").startsWith("/bucket/hello")); - } - - @Test - public void startsWithStringRelative() { - assertTrue(forPath("subkey1/hello").startsWith("subkey1/hello")); - } - - @Test - public void startsWithStringOnlyBuckets() { - assertTrue(forPath("/bucket").startsWith("/bucket")); - } - - @Test - public void startsWithStringRelativeVsAbsolute() { - assertFalse(forPath("/bucket/file1").startsWith("file1")); - } - - @Test - public void startsWithStringFalse() { - assertFalse(forPath("/bucket/file1").startsWith("/bucket/file1/file2")); - assertTrue(forPath("/bucket/file1/file2").startsWith("/bucket/file1")); - } - - @Test - public void startsWithStringRelativeVsAbsoluteInBucket() { - assertFalse(forPath("/bucket/file1").startsWith("bucket")); - } - - // ends with - - @Test - public void endsWithAbsoluteRelative() { - assertTrue(forPath("/bucket/file1").endsWith(forPath("file1"))); - } - - @Test - public void endsWithAbsoluteAbsolute() { - assertTrue(forPath("/bucket/file1").endsWith(forPath("/bucket/file1"))); - } - - @Test - public void endsWithRelativeRelative() { - assertTrue(forPath("file/file1").endsWith(forPath("file1"))); - } - - @Test - public void endsWithRelativeAbsolute() { - assertFalse(forPath("file/file1").endsWith(forPath("/bucket"))); - } - - @Test - public void endsWithDifferenteFileSystem() { - assertFalse(forPath("/bucket/file1").endsWith(Paths.get("/bucket/file1"))); - } - - @Test - public void endsWithBlankRelativeAbsolute() { - assertFalse(forPath("").endsWith(forPath("/bucket"))); - } - - @Test - public void endsWithBlankBlank() { - assertTrue(forPath("").endsWith(forPath(""))); - } - - @Test - public void endsWithRelativeBlankAbsolute() { - assertFalse(forPath("/bucket/file1").endsWith(forPath(""))); - } - - @Test - public void endsWithRelativeBlankRelative() { - assertFalse(forPath("file1").endsWith(forPath(""))); - } - - @Test - public void endsWithDifferent() { - assertFalse(forPath("/bucket/dir/dir/file1").endsWith(forPath("fail/dir/file1"))); - } - - @Test - public void endsWithDifferentProvider() throws IOException { - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path fileLinux = linux.getPath("/file"); - - assertFalse(forPath("/bucket/file").endsWith(fileLinux)); - } - - try (FileSystem window = MemoryFileSystemBuilder.newWindows().build("window")) { - Path file = window.getPath("c:/file"); - - assertFalse(forPath("/c/file").endsWith(file)); - } - } - - @Test - public void endsWithString() { - // endsWithAbsoluteRelative(){ - assertTrue(forPath("/bucket/file1").endsWith("file1")); - // endsWithAbsoluteAbsolute - assertTrue(forPath("/bucket/file1").endsWith("/bucket/file1")); - // endsWithRelativeRelative - assertTrue(forPath("file/file1").endsWith("file1")); - // endsWithRelativeAbsolute - assertFalse(forPath("file/file1").endsWith("/bucket")); - // endsWithBlankRelativeAbsolute - assertFalse(forPath("").endsWith("/bucket")); - // endsWithBlankBlank - assertTrue(forPath("").endsWith("")); - // endsWithRelativeBlankAbsolute - assertFalse(forPath("/bucket/file1").endsWith("")); - // endsWithRelativeBlankRelative - assertFalse(forPath("file1").endsWith("")); - } - - // register - - @Test(expected = UnsupportedOperationException.class) - public void registerWithEventsThrowException() throws IOException { - forPath("file1").register(null); - } - - @Test(expected = UnsupportedOperationException.class) - public void registerThrowException() throws IOException { - forPath("file1").register(null); - } - - @Test(expected = UnsupportedOperationException.class) - public void registerWithEventsAndModiferThrowException() throws IOException { - forPath("file1").register(null); - } - - // to file - - @Test(expected = UnsupportedOperationException.class) - public void toFile() { - forPath("file1").toFile(); - } - - // compares to - - @Test - public void compare() { - assertTrue(forPath("file1").compareTo(forPath("file1")) == 0); - assertTrue(forPath("/path/file1").compareTo(forPath("/path/file1")) == 0); - assertTrue(forPath("/A/file1").compareTo(forPath("/B/file1")) == -1); - assertTrue(forPath("/B/file1").compareTo(forPath("/A/file1")) == 1); - assertTrue(forPath("/AA/file1").compareTo(forPath("/A/file1")) > 0); - assertTrue(forPath("a").compareTo(forPath("aa")) < 0); - assertTrue(forPath("ab").compareTo(forPath("aa")) > 0); - } - - // toRealPath - - @Test(expected = UnsupportedOperationException.class) - public void toRealPathThrowException() throws IOException { - forPath("file1").toRealPath(); - } - - // toAbsolutePath - - @SuppressWarnings("unused") - @Test(expected = IllegalStateException.class) - public void toAbsolutePathRelativePathThrowException() throws IOException { - forPath("file1").toAbsolutePath(); - } - - @Test - public void toAbsolutePath() { - Path path = forPath("/file1"); - Path other = path.toAbsolutePath(); - assertEquals(path, other); - } - - // get root - - @Test - public void getRootReturnBucket() { - assertEquals(forPath("/bucketA"), forPath("/bucketA/dir/file").getRoot()); - } - - @Test - public void getRootRelativeReturnNull() { - assertNull(forPath("dir/file").getRoot()); - } - - // file name - - @Test - public void getFileName() { - Path path = forPath("/bucketA/file"); - Path name = path.getFileName(); - - assertEquals(forPath("file"), name); - } - - @Test - public void getAnotherFileName() { - Path path = forPath("/bucketA/dir/another-file"); - Path fileName = path.getFileName(); - Path dirName = path.getParent().getFileName(); - - assertEquals(forPath("another-file"), fileName); - assertEquals(forPath("dir"), dirName); - } - - @Test - public void getFileNameBucket() { - Path path = forPath("/bucket"); - Path name = path.getFileName(); - assertEquals(name.toString(), "bucket"); - } - - // equals - - @Test - public void equals() { - Path path = forPath("/bucketA/dir/file"); - Path path2 = forPath("/bucketA/dir/file"); - - assertTrue(path.equals(path2)); - } - - @Test - public void notEquals() { - Path path = forPath("/bucketA/dir/file"); - Path path2 = forPath("/bucketA/dir/file2"); - - assertFalse(path.equals(path2)); - } - - @Test - public void notEqualsNull() { - Path path = forPath("/bucketA/dir/file"); - - assertFalse(path.equals(null)); - } - - @Test - public void notEqualsDifferentProvider() throws IOException { - Path path = forPath("/c/dir/file"); - - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path fileLinux = linux.getPath("/dir/file"); - - assertFalse(path.equals(fileLinux)); - } - - try (FileSystem window = MemoryFileSystemBuilder.newWindows().build("window")) { - Path file = window.getPath("c:/dir/file"); - - assertFalse(path.equals(file)); - } - } - - @Test - public void hashCodeHashMap() { - HashMap hashMap = new HashMap<>(); - hashMap.put(forPath("/bucket/a"), "a"); - hashMap.put(forPath("/bucket/a"), "b"); - - assertEquals(1, hashMap.size()); - assertEquals("b", hashMap.get(forPath("/bucket/a"))); - } - - @Test(expected=IllegalArgumentException.class) - public void preconditions() { - S3FileSystem fileSystem = new S3FileSystemProvider().getFileSystem(S3_GLOBAL_URI); - new S3Path(fileSystem, "/"); - } - - @Test - public void constructors() { - S3FileSystem fileSystem = new S3FileSystemProvider().getFileSystem(S3_GLOBAL_URI); - S3Path path = new S3Path(fileSystem, "/buckname"); - assertEquals("buckname", path.getFileStore().name()); - assertEquals("buckname", path.getFileName().toString()); - assertNull(path.getParent()); - assertEquals("", path.getKey()); - path = new S3Path(fileSystem, "/buckname/"); - assertEquals("buckname", path.getFileStore().name()); - assertEquals("buckname", path.getFileName().toString()); - assertEquals("", path.getKey()); - path = new S3Path(fileSystem, "/buckname/file"); - assertEquals("buckname", path.getFileStore().name()); - assertEquals("file", path.getFileName().toString()); - assertEquals("file", path.getKey()); - path = new S3Path(fileSystem, "/buckname/dir/file"); - assertEquals("buckname", path.getFileStore().name()); - assertEquals("file", path.getFileName().toString()); - assertEquals("dir/file", path.getKey()); - path = new S3Path(fileSystem, "dir/file"); - assertNull(path.getFileStore()); - assertEquals("file", path.getFileName().toString()); - assertEquals("dir/file", path.getKey()); - assertEquals("dir", path.getParent().toString()); - path = new S3Path(fileSystem, "bla"); - assertNull(path.getFileStore()); - assertEquals("bla", path.getFileName().toString()); - assertEquals("bla", path.getKey()); - assertNull(path.getParent()); - assertNull(path.toUri()); - path = new S3Path(fileSystem, ""); - assertNull(path.getFileStore()); - assertEquals("", path.getFileName().toString()); - assertEquals("", path.getKey()); - assertNull(path.getParent()); - } - - @Test(expected=UnsupportedOperationException.class) - public void register() throws IOException { - S3Path path = forPath("/buck/file"); - path.register(null); - } - - @Test(expected=UnsupportedOperationException.class) - public void registerWatchService() throws IOException { - S3Path path = forPath("/buck/file"); - path.register(null, new WatchEvent.Kind[0], new WatchEvent.Modifier[0]); - } - - private static S3Path forPath(String path) { - return (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath(path); - } + @Test + public void createNoPath() { + S3Path path = forPath("/bucket"); + + assertEquals("bucket", path.getFileStore().name()); + assertEquals("", path.getKey()); + } + + @Test + public void createWithTrailingSlash() { + S3Path path = forPath("/bucket/"); + + assertEquals(path.getFileStore().name(), "bucket"); + assertEquals(path.getKey(), ""); + } + + @Test + public void createWithPath() { + S3Path path = forPath("/bucket/path/to/file"); + + assertEquals(path.getFileStore().name(), "bucket"); + assertEquals(path.getKey(), "path/to/file"); + } + + @Test + public void createWithPathAndTrailingSlash() { + S3Path path = forPath("/bucket/path/to/file/"); + + assertEquals("bucket", path.getFileStore().name()); + assertEquals("path/to/file", path.getKey()); + } + + @Test + public void createRelative() { + S3Path path = forPath("path/to/file"); + + assertNull(path.getFileStore()); + assertEquals(path.getKey(), "path/to/file"); + assertFalse(path.isAbsolute()); + } + + @Test + public void getParent() { + assertEquals(forPath("/bucket/path/to/"), forPath("/bucket/path/to/file").getParent()); + assertEquals(forPath("/bucket/path/to/"), forPath("/bucket/path/to/file/").getParent()); + assertNull(forPath("/bucket/").getParent()); + assertNull(forPath("/bucket").getParent()); + } + + @Test + public void nameCount() { + assertEquals(forPath("/bucket/path/to/file").getNameCount(), 3); + assertEquals(forPath("/bucket/").getNameCount(), 0); + } + + @Test + public void resolve() { + assertEquals(forPath("/bucket/path/to/dir/").resolve(forPath("child/xyz")), forPath("/bucket/path/to/dir/child/xyz")); + assertEquals(forPath("/bucket/path/to/dir").resolve(forPath("child/xyz")), forPath("/bucket/path/to/dir/child/xyz")); + assertEquals(forPath("/bucket/path/to/file").resolve(forPath("")), forPath("/bucket/path/to/file")); // TODO: should this be "path/to/dir/" + assertEquals(forPath("path/to/file").resolve(forPath("child/xyz")), forPath("path/to/file/child/xyz")); + assertEquals(forPath("path/to/file").resolve(forPath("")), forPath("path/to/file")); // TODO: should this be "path/to/dir/" + assertEquals(forPath("/bucket/path/to/file").resolve(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); + } + + @Test + public void name() { + assertEquals(forPath("/bucket/path/to/file").getName(0), forPath("path/")); + assertEquals(forPath("/bucket/path/to/file").getName(1), forPath("to/")); + assertEquals(forPath("/bucket/path/to/file").getName(2), forPath("file")); + } + + @Test + public void subPath() { + assertEquals(forPath("/bucket/path/to/file").subpath(0, 1), forPath("path/")); + assertEquals(forPath("/bucket/path/to/file").subpath(0, 2), forPath("path/to/")); + assertEquals(forPath("/bucket/path/to/file").subpath(0, 3), forPath("path/to/file")); + assertEquals(forPath("/bucket/path/to/file").subpath(1, 2), forPath("to/")); + assertEquals(forPath("/bucket/path/to/file").subpath(1, 3), forPath("to/file")); + assertEquals(forPath("/bucket/path/to/file").subpath(2, 3), forPath("file")); + } + + @Test + public void iterator() { + Iterator iterator = forPath("/bucket/path/to/file").iterator(); + + assertEquals(iterator.next(), forPath("path/")); + assertEquals(iterator.next(), forPath("to/")); + assertEquals(iterator.next(), forPath("file")); + } + + @Test + public void resolveSibling() { + // absolute (non-root) vs... + assertEquals(forPath("/bucket/path/to/file").resolveSibling(forPath("other/child")), forPath("/bucket/path/to/other/child")); + assertEquals(forPath("/bucket/path/to/file").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); + assertEquals(forPath("/bucket/path/to/file").resolveSibling(forPath("")), forPath("/bucket/path/to/")); + + // absolute (root) vs ... + assertEquals(forPath("/bucket").resolveSibling(forPath("other/child")), forPath("other/child")); + assertEquals(forPath("/bucket").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); + assertEquals(forPath("/bucket").resolveSibling(forPath("")), forPath("")); + + // relative (empty) vs ... + assertEquals(forPath("").resolveSibling(forPath("other/child")), forPath("other/child")); + assertEquals(forPath("").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); + assertEquals(forPath("").resolveSibling(forPath("")), forPath("")); + + // relative (non-empty) vs ... + assertEquals(forPath("path/to/file").resolveSibling(forPath("other/child")), forPath("path/to/other/child")); + assertEquals(forPath("path/to/file").resolveSibling(forPath("/bucket2/other/child")), forPath("/bucket2/other/child")); + assertEquals(forPath("path/to/file").resolveSibling(forPath("")), forPath("path/to/")); + } + + @Test + public void resolveSiblingString() { + // absolute (non-root) vs... + assertEquals(forPath("/bucket/path/to/file").resolveSibling("other/child"), forPath("/bucket/path/to/other/child")); + assertEquals(forPath("/bucket/path/to/file").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); + assertEquals(forPath("/bucket/path/to/file").resolveSibling(""), forPath("/bucket/path/to/")); + + // absolute (root) vs ... + assertEquals(forPath("/bucket").resolveSibling("other/child"), forPath("other/child")); + assertEquals(forPath("/bucket").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); + assertEquals(forPath("/bucket").resolveSibling(""), forPath("")); + + // relative (empty) vs ... + assertEquals(forPath("").resolveSibling("other/child"), forPath("other/child")); + assertEquals(forPath("").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); + assertEquals(forPath("").resolveSibling(""), forPath("")); + + // relative (non-empty) vs ... + assertEquals(forPath("path/to/file").resolveSibling("other/child"), forPath("path/to/other/child")); + assertEquals(forPath("path/to/file").resolveSibling("/bucket2/other/child"), forPath("/bucket2/other/child")); + assertEquals(forPath("path/to/file").resolveSibling(""), forPath("path/to/")); + } + + @Test + public void relativize() { + Path path = forPath("/bucket/path/to/file"); + Path other = forPath("/bucket/path/to/file/hello"); + + assertEquals(forPath("hello"), path.relativize(other)); + + // another + + assertEquals(forPath("file/hello"), forPath("/bucket/path/to/").relativize(forPath("/bucket/path/to/file/hello"))); + + // empty + + assertEquals(forPath(""), forPath("/bucket/path/to/").relativize(forPath("/bucket/path/to/"))); + } + + // to uri + + @Test + public void toUri() { + Path path = forPath("/bucket/path/to/file"); + URI uri = path.toUri(); + + // the scheme is s3 + assertEquals("s3", uri.getScheme()); + + // could get the correct fileSystem + FileSystem fs = FileSystems.getFileSystem(uri); + assertTrue(fs instanceof S3FileSystem); + // the host is the endpoint specified in fileSystem + assertEquals(((S3FileSystem) fs).getEndpoint(), uri.getHost()); + + // bucket name as first path + Path pathActual = fs.provider().getPath(uri); + + assertEquals(path, pathActual); + } + + @Test + public void toUriWithEndpoint() throws IOException { + try (FileSystem fs = FileSystems.newFileSystem(URI.create("s3://endpoint/"), null)) { + Path path = fs.getPath("/bucket/path/to/file"); + URI uri = path.toUri(); + // the scheme is s3 + assertEquals("s3", uri.getScheme()); + assertEquals("endpoint", uri.getHost()); + assertEquals("/bucket/path/to/file", uri.getPath()); + } + } + + // tests startsWith + + @Test + public void startsWith() { + assertTrue(forPath("/bucket/file1").startsWith(forPath("/bucket"))); + } + + @Test + public void startsWithBlank() { + assertFalse(forPath("/bucket/file1").startsWith(forPath(""))); + } + + @Test + public void startsWithBlankRelative() { + assertFalse(forPath("file1").startsWith(forPath(""))); + } + + @Test + public void startsWithBlankBlank() { + assertTrue(forPath("").startsWith(forPath(""))); + } + + @Test + public void startsWithOnlyBuckets() { + assertTrue(forPath("/bucket").startsWith(forPath("/bucket"))); + } + + @Test + public void startsWithRelativeVsAbsolute() { + assertFalse(forPath("/bucket/file1").startsWith(forPath("file1"))); + } + + @Test + public void startsWithRelativeVsAbsoluteInBucket() { + assertFalse(forPath("/bucket/file1").startsWith(forPath("bucket"))); + } + + @Test + public void startsWithFalse() { + assertFalse(forPath("/bucket/file1").startsWith(forPath("/bucket/file1/file2"))); + assertTrue(forPath("/bucket/file1/file2").startsWith(forPath("/bucket/file1"))); + } + + @Test + public void startsWithNotNormalize() { + assertFalse(forPath("/bucket/file1/file2").startsWith(forPath("/bucket/file1/../"))); + } + + @Test + public void startsWithNormalize() { + // in this implementation not exists .. or . special paths + assertFalse(forPath("/bucket/file1/file2").startsWith(forPath("/bucket/file1/../").normalize())); + } + + @Test + public void startsWithRelative() { + assertTrue(forPath("file/file1").startsWith(forPath("file"))); + } + + @Test + public void startsWithDifferentProvider() { + assertFalse(forPath("/bucket/hello").startsWith(Paths.get("/bucket"))); + } + + @Test + public void startsWithString() { + assertTrue(forPath("/bucket/hello").startsWith("/bucket/hello")); + } + + @Test + public void startsWithStringRelative() { + assertTrue(forPath("subkey1/hello").startsWith("subkey1/hello")); + } + + @Test + public void startsWithStringOnlyBuckets() { + assertTrue(forPath("/bucket").startsWith("/bucket")); + } + + @Test + public void startsWithStringRelativeVsAbsolute() { + assertFalse(forPath("/bucket/file1").startsWith("file1")); + } + + @Test + public void startsWithStringFalse() { + assertFalse(forPath("/bucket/file1").startsWith("/bucket/file1/file2")); + assertTrue(forPath("/bucket/file1/file2").startsWith("/bucket/file1")); + } + + @Test + public void startsWithStringRelativeVsAbsoluteInBucket() { + assertFalse(forPath("/bucket/file1").startsWith("bucket")); + } + + // ends with + + @Test + public void endsWithAbsoluteRelative() { + assertTrue(forPath("/bucket/file1").endsWith(forPath("file1"))); + } + + @Test + public void endsWithAbsoluteAbsolute() { + assertTrue(forPath("/bucket/file1").endsWith(forPath("/bucket/file1"))); + } + + @Test + public void endsWithRelativeRelative() { + assertTrue(forPath("file/file1").endsWith(forPath("file1"))); + } + + @Test + public void endsWithRelativeAbsolute() { + assertFalse(forPath("file/file1").endsWith(forPath("/bucket"))); + } + + @Test + public void endsWithDifferenteFileSystem() { + assertFalse(forPath("/bucket/file1").endsWith(Paths.get("/bucket/file1"))); + } + + @Test + public void endsWithBlankRelativeAbsolute() { + assertFalse(forPath("").endsWith(forPath("/bucket"))); + } + + @Test + public void endsWithBlankBlank() { + assertTrue(forPath("").endsWith(forPath(""))); + } + + @Test + public void endsWithRelativeBlankAbsolute() { + assertFalse(forPath("/bucket/file1").endsWith(forPath(""))); + } + + @Test + public void endsWithRelativeBlankRelative() { + assertFalse(forPath("file1").endsWith(forPath(""))); + } + + @Test + public void endsWithDifferent() { + assertFalse(forPath("/bucket/dir/dir/file1").endsWith(forPath("fail/dir/file1"))); + } + + @Test + public void endsWithDifferentProvider() throws IOException { + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path fileLinux = linux.getPath("/file"); + + assertFalse(forPath("/bucket/file").endsWith(fileLinux)); + } + + try (FileSystem window = MemoryFileSystemBuilder.newWindows().build("window")) { + Path file = window.getPath("c:/file"); + + assertFalse(forPath("/c/file").endsWith(file)); + } + } + + @Test + public void endsWithString() { + // endsWithAbsoluteRelative(){ + assertTrue(forPath("/bucket/file1").endsWith("file1")); + // endsWithAbsoluteAbsolute + assertTrue(forPath("/bucket/file1").endsWith("/bucket/file1")); + // endsWithRelativeRelative + assertTrue(forPath("file/file1").endsWith("file1")); + // endsWithRelativeAbsolute + assertFalse(forPath("file/file1").endsWith("/bucket")); + // endsWithBlankRelativeAbsolute + assertFalse(forPath("").endsWith("/bucket")); + // endsWithBlankBlank + assertTrue(forPath("").endsWith("")); + // endsWithRelativeBlankAbsolute + assertFalse(forPath("/bucket/file1").endsWith("")); + // endsWithRelativeBlankRelative + assertFalse(forPath("file1").endsWith("")); + } + + // register + + @Test(expected = UnsupportedOperationException.class) + public void registerWithEventsThrowException() throws IOException { + forPath("file1").register(null); + } + + @Test(expected = UnsupportedOperationException.class) + public void registerThrowException() throws IOException { + forPath("file1").register(null); + } + + @Test(expected = UnsupportedOperationException.class) + public void registerWithEventsAndModiferThrowException() throws IOException { + forPath("file1").register(null); + } + + // to file + + @Test(expected = UnsupportedOperationException.class) + public void toFile() { + forPath("file1").toFile(); + } + + // compares to + + @Test + public void compare() { + assertTrue(forPath("file1").compareTo(forPath("file1")) == 0); + assertTrue(forPath("/path/file1").compareTo(forPath("/path/file1")) == 0); + assertTrue(forPath("/A/file1").compareTo(forPath("/B/file1")) == -1); + assertTrue(forPath("/B/file1").compareTo(forPath("/A/file1")) == 1); + assertTrue(forPath("/AA/file1").compareTo(forPath("/A/file1")) > 0); + assertTrue(forPath("a").compareTo(forPath("aa")) < 0); + assertTrue(forPath("ab").compareTo(forPath("aa")) > 0); + } + + // toRealPath + + @Test(expected = UnsupportedOperationException.class) + public void toRealPathThrowException() throws IOException { + forPath("file1").toRealPath(); + } + + // toAbsolutePath + + @SuppressWarnings("unused") + @Test(expected = IllegalStateException.class) + public void toAbsolutePathRelativePathThrowException() throws IOException { + forPath("file1").toAbsolutePath(); + } + + @Test + public void toAbsolutePath() { + Path path = forPath("/file1"); + Path other = path.toAbsolutePath(); + assertEquals(path, other); + } + + // get root + + @Test + public void getRootReturnBucket() { + assertEquals(forPath("/bucketA"), forPath("/bucketA/dir/file").getRoot()); + } + + @Test + public void getRootRelativeReturnNull() { + assertNull(forPath("dir/file").getRoot()); + } + + // file name + + @Test + public void getFileName() { + Path path = forPath("/bucketA/file"); + Path name = path.getFileName(); + + assertEquals(forPath("file"), name); + } + + @Test + public void getAnotherFileName() { + Path path = forPath("/bucketA/dir/another-file"); + Path fileName = path.getFileName(); + Path dirName = path.getParent().getFileName(); + + assertEquals(forPath("another-file"), fileName); + assertEquals(forPath("dir"), dirName); + } + + @Test + public void getFileNameBucket() { + Path path = forPath("/bucket"); + Path name = path.getFileName(); + assertEquals(name.toString(), "bucket"); + } + + // equals + + @Test + public void equals() { + Path path = forPath("/bucketA/dir/file"); + Path path2 = forPath("/bucketA/dir/file"); + + assertTrue(path.equals(path2)); + } + + @Test + public void notEquals() { + Path path = forPath("/bucketA/dir/file"); + Path path2 = forPath("/bucketA/dir/file2"); + + assertFalse(path.equals(path2)); + } + + @Test + public void notEqualsNull() { + Path path = forPath("/bucketA/dir/file"); + + assertFalse(path.equals(null)); + } + + @Test + public void notEqualsDifferentProvider() throws IOException { + Path path = forPath("/c/dir/file"); + + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path fileLinux = linux.getPath("/dir/file"); + + assertFalse(path.equals(fileLinux)); + } + + try (FileSystem window = MemoryFileSystemBuilder.newWindows().build("window")) { + Path file = window.getPath("c:/dir/file"); + + assertFalse(path.equals(file)); + } + } + + @Test + public void hashCodeHashMap() { + HashMap hashMap = new HashMap<>(); + hashMap.put(forPath("/bucket/a"), "a"); + hashMap.put(forPath("/bucket/a"), "b"); + + assertEquals(1, hashMap.size()); + assertEquals("b", hashMap.get(forPath("/bucket/a"))); + } + + @Test(expected = IllegalArgumentException.class) + public void preconditions() { + S3FileSystem fileSystem = new S3FileSystemProvider().getFileSystem(S3_GLOBAL_URI); + new S3Path(fileSystem, "/"); + } + + @Test + public void constructors() { + S3FileSystem fileSystem = new S3FileSystemProvider().getFileSystem(S3_GLOBAL_URI); + S3Path path = new S3Path(fileSystem, "/buckname"); + assertEquals("buckname", path.getFileStore().name()); + assertEquals("buckname", path.getFileName().toString()); + assertNull(path.getParent()); + assertEquals("", path.getKey()); + path = new S3Path(fileSystem, "/buckname/"); + assertEquals("buckname", path.getFileStore().name()); + assertEquals("buckname", path.getFileName().toString()); + assertEquals("", path.getKey()); + path = new S3Path(fileSystem, "/buckname/file"); + assertEquals("buckname", path.getFileStore().name()); + assertEquals("file", path.getFileName().toString()); + assertEquals("file", path.getKey()); + path = new S3Path(fileSystem, "/buckname/dir/file"); + assertEquals("buckname", path.getFileStore().name()); + assertEquals("file", path.getFileName().toString()); + assertEquals("dir/file", path.getKey()); + path = new S3Path(fileSystem, "dir/file"); + assertNull(path.getFileStore()); + assertEquals("file", path.getFileName().toString()); + assertEquals("dir/file", path.getKey()); + assertEquals("dir", path.getParent().toString()); + path = new S3Path(fileSystem, "bla"); + assertNull(path.getFileStore()); + assertEquals("bla", path.getFileName().toString()); + assertEquals("bla", path.getKey()); + assertNull(path.getParent()); + assertNull(path.toUri()); + path = new S3Path(fileSystem, ""); + assertNull(path.getFileStore()); + assertEquals("", path.getFileName().toString()); + assertEquals("", path.getKey()); + assertNull(path.getParent()); + } + + @Test(expected = UnsupportedOperationException.class) + public void register() throws IOException { + S3Path path = forPath("/buck/file"); + path.register(null); + } + + @Test(expected = UnsupportedOperationException.class) + public void registerWatchService() throws IOException { + S3Path path = forPath("/buck/file"); + path.register(null, new WatchEvent.Kind[0], new WatchEvent.Modifier[0]); + } + + private static S3Path forPath(String path) { + return (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath(path); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/S3SeekableByteChannelTest.java b/src/test/java/com/upplication/s3fs/S3SeekableByteChannelTest.java index 26c36df..d01cff6 100644 --- a/src/test/java/com/upplication/s3fs/S3SeekableByteChannelTest.java +++ b/src/test/java/com/upplication/s3fs/S3SeekableByteChannelTest.java @@ -27,30 +27,30 @@ public void setup() throws IOException { FileSystems.newFileSystem(S3_GLOBAL_URI, null); } - @Test - public void constructor() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("buck").file("file1"); - - S3Path file1 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file1"); - S3SeekableByteChannel channel = new S3SeekableByteChannel(file1, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ)); - assertNotNull(channel); - channel.write(ByteBuffer.wrap("hoi".getBytes())); - channel.close(); - } - - @Test - public void readDontNeedToSyncTempFile() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("buck").file("file1"); - - S3Path file1 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file1"); - S3SeekableByteChannel channel = spy(new S3SeekableByteChannel(file1, EnumSet.of(StandardOpenOption.READ))); - assertNotNull(channel); - channel.close(); + @Test + public void constructor() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("buck").file("file1"); + + S3Path file1 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file1"); + S3SeekableByteChannel channel = new S3SeekableByteChannel(file1, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ)); + assertNotNull(channel); + channel.write(ByteBuffer.wrap("hoi".getBytes())); + channel.close(); + } + + @Test + public void readDontNeedToSyncTempFile() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("buck").file("file1"); + + S3Path file1 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file1"); + S3SeekableByteChannel channel = spy(new S3SeekableByteChannel(file1, EnumSet.of(StandardOpenOption.READ))); + assertNotNull(channel); + channel.close(); verify(channel, never()).sync(); - } + } @Test public void writeNeedToSyncTempFile() throws IOException { @@ -66,37 +66,37 @@ public void writeNeedToSyncTempFile() throws IOException { verify(channel, times(1)).sync(); } - - @Test(expected=FileAlreadyExistsException.class) - public void alreadyExists() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("buck").file("file1"); - - S3Path file1 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file1"); - S3SeekableByteChannel channel = new S3SeekableByteChannel(file1, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)); - assertNotNull(channel); - channel.write(ByteBuffer.wrap("hoi".getBytes())); - channel.close(); - } - - @Test(expected=RuntimeException.class) - public void brokenNetwork() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - doThrow(new RuntimeException("network broken")).when(client).getObject("buck", "file2"); - - S3Path file2 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file2"); - S3SeekableByteChannel channel = new S3SeekableByteChannel(file2, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ)); - channel.close(); - } - - @Test(expected=NoSuchFileException.class) - public void tempFileDisappeared() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - S3Path file2 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file2"); - S3SeekableByteChannel channel = new S3SeekableByteChannel(file2, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ)); - Field f = channel.getClass().getDeclaredField("tempFile"); - f.setAccessible(true); - Path tempFile = (Path) f.get(channel); - Files.delete(tempFile); - channel.close(); - } + + @Test(expected = FileAlreadyExistsException.class) + public void alreadyExists() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("buck").file("file1"); + + S3Path file1 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file1"); + S3SeekableByteChannel channel = new S3SeekableByteChannel(file1, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)); + assertNotNull(channel); + channel.write(ByteBuffer.wrap("hoi".getBytes())); + channel.close(); + } + + @Test(expected = RuntimeException.class) + public void brokenNetwork() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + doThrow(new RuntimeException("network broken")).when(client).getObject("buck", "file2"); + + S3Path file2 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file2"); + S3SeekableByteChannel channel = new S3SeekableByteChannel(file2, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ)); + channel.close(); + } + + @Test(expected = NoSuchFileException.class) + public void tempFileDisappeared() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + S3Path file2 = (S3Path) FileSystems.getFileSystem(S3_GLOBAL_URI).getPath("/buck/file2"); + S3SeekableByteChannel channel = new S3SeekableByteChannel(file2, EnumSet.of(StandardOpenOption.WRITE, StandardOpenOption.READ)); + Field f = channel.getClass().getDeclaredField("tempFile"); + f.setAccessible(true); + Path tempFile = (Path) f.get(channel); + Files.delete(tempFile); + channel.close(); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/S3UnitTestBase.java b/src/test/java/com/upplication/s3fs/S3UnitTestBase.java index d902113..71c2049 100644 --- a/src/test/java/com/upplication/s3fs/S3UnitTestBase.java +++ b/src/test/java/com/upplication/s3fs/S3UnitTestBase.java @@ -13,24 +13,24 @@ import com.upplication.s3fs.util.AmazonS3MockFactory; public class S3UnitTestBase { - - public static final URI S3_GLOBAL_URI = URI.create("s3://s3.amazonaws.com/"); - - @BeforeClass - public static void setProperties() { - System.setProperty(AMAZON_S3_FACTORY_CLASS, "com.upplication.s3fs.util.AmazonS3MockFactory"); - } - - @After - public void closeMemory() { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.clear(); - for (S3FileSystem s3FileSystem : S3FileSystemProvider.getFilesystems().values()) { - try { - s3FileSystem.close(); - } catch (Exception e) { - //ignore - } - } - } + + public static final URI S3_GLOBAL_URI = URI.create("s3://s3.test.amazonaws.com/"); + + @BeforeClass + public static void setProperties() { + System.setProperty(AMAZON_S3_FACTORY_CLASS, "com.upplication.s3fs.util.AmazonS3MockFactory"); + } + + @After + public void closeMemory() { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.clear(); + for (S3FileSystem s3FileSystem : S3FileSystemProvider.getFilesystems().values()) { + try { + s3FileSystem.close(); + } catch (Exception e) { + //ignore + } + } + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/S3UtilsIT.java b/src/test/java/com/upplication/s3fs/S3UtilsIT.java index 0a53bab..90c9449 100644 --- a/src/test/java/com/upplication/s3fs/S3UtilsIT.java +++ b/src/test/java/com/upplication/s3fs/S3UtilsIT.java @@ -26,119 +26,119 @@ public class S3UtilsIT { - private static final String bucket = EnvironmentBuilder.getBucket(); + private static final String bucket = EnvironmentBuilder.getBucket(); private static final URI uriGlobal = EnvironmentBuilder.getS3URI(S3_GLOBAL_URI); - private FileSystem fileSystemAmazon; + private FileSystem fileSystemAmazon; @Before - public void setup() throws IOException { - fileSystemAmazon = build(); - } + public void setup() throws IOException { + fileSystemAmazon = build(); + } - private static FileSystem build() throws IOException { + private static FileSystem build() throws IOException { System.clearProperty(S3FileSystemProvider.AMAZON_S3_FACTORY_CLASS); System.clearProperty(ACCESS_KEY); System.clearProperty(SECRET_KEY); - try { - FileSystems.getFileSystem(uriGlobal).close(); - return createNewFileSystem(); - } catch (FileSystemNotFoundException e) { - return createNewFileSystem(); - } - } - - private static FileSystem createNewFileSystem() throws IOException { - return FileSystems.newFileSystem(uriGlobal, EnvironmentBuilder.getRealEnv()); - } + try { + FileSystems.getFileSystem(uriGlobal).close(); + return createNewFileSystem(); + } catch (FileSystemNotFoundException e) { + return createNewFileSystem(); + } + } + + private static FileSystem createNewFileSystem() throws IOException { + return FileSystems.newFileSystem(uriGlobal, EnvironmentBuilder.getRealEnv()); + } @Test - public void lookup_S3Object_when_S3Path_is_file() throws IOException { + public void lookup_S3Object_when_S3Path_is_file() throws IOException { - Path path; - final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + Path path; + final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path base = Files.createDirectory(linux.getPath("/base")); - Files.createFile(base.resolve("file")); - path = fileSystemAmazon.getPath(bucket, startPath); - Files.walkFileTree(base, new CopyDirVisitor(base, path)); - } + Path base = Files.createDirectory(linux.getPath("/base")); + Files.createFile(base.resolve("file")); + path = fileSystemAmazon.getPath(bucket, startPath); + Files.walkFileTree(base, new CopyDirVisitor(base, path)); + } - S3Path s3Path = (S3Path) path.resolve("file"); - S3ObjectSummary result = getS3ObjectSummary(s3Path); + S3Path s3Path = (S3Path) path.resolve("file"); + S3ObjectSummary result = getS3ObjectSummary(s3Path); - assertEquals(s3Path.getKey(), result.getKey()); - } + assertEquals(s3Path.getKey(), result.getKey()); + } @Test - public void lookup_S3Object_when_S3Path_is_file_and_exists_other_starts_with_same_name() throws IOException { - Path path; - final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - - Path base = Files.createDirectory(linux.getPath("/base")); - Files.createFile(base.resolve("file")); - Files.createFile(base.resolve("file1")); - path = fileSystemAmazon.getPath(bucket, startPath); - Files.walkFileTree(base, new CopyDirVisitor(base, path)); - } - - S3Path s3Path = (S3Path) path.resolve("file"); - S3ObjectSummary result = getS3ObjectSummary(s3Path); - - assertEquals(s3Path.getKey(), result.getKey()); - } + public void lookup_S3Object_when_S3Path_is_file_and_exists_other_starts_with_same_name() throws IOException { + Path path; + final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + + Path base = Files.createDirectory(linux.getPath("/base")); + Files.createFile(base.resolve("file")); + Files.createFile(base.resolve("file1")); + path = fileSystemAmazon.getPath(bucket, startPath); + Files.walkFileTree(base, new CopyDirVisitor(base, path)); + } + + S3Path s3Path = (S3Path) path.resolve("file"); + S3ObjectSummary result = getS3ObjectSummary(s3Path); + + assertEquals(s3Path.getKey(), result.getKey()); + } @Test - public void lookup_S3Object_when_S3Path_is_a_directory() throws IOException { - Path path; - final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; - try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { + public void lookup_S3Object_when_S3Path_is_a_directory() throws IOException { + Path path; + final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; + try (FileSystem linux = MemoryFileSystemBuilder.newLinux().build("linux")) { - Path base = Files.createDirectories(linux.getPath("/base").resolve("dir")); - path = fileSystemAmazon.getPath(bucket, startPath); - Files.walkFileTree(base.getParent(), new CopyDirVisitor(base.getParent(), path)); - } + Path base = Files.createDirectories(linux.getPath("/base").resolve("dir")); + path = fileSystemAmazon.getPath(bucket, startPath); + Files.walkFileTree(base.getParent(), new CopyDirVisitor(base.getParent(), path)); + } - S3Path s3Path = (S3Path) path.resolve("dir"); + S3Path s3Path = (S3Path) path.resolve("dir"); - S3ObjectSummary result = getS3ObjectSummary(s3Path); + S3ObjectSummary result = getS3ObjectSummary(s3Path); - assertEquals(s3Path.getKey() + "/", result.getKey()); - } + assertEquals(s3Path.getKey() + "/", result.getKey()); + } @Test - public void lookup_S3Object_when_S3Path_is_a_directory_and_exists_other_directory_starts_same_name() throws IOException { + public void lookup_S3Object_when_S3Path_is_a_directory_and_exists_other_directory_starts_same_name() throws IOException { - final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; - S3FileSystem s3FileSystem = (S3FileSystem) fileSystemAmazon; - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentLength(0L); - s3FileSystem.getClient().putObject(bucket.replace("/", ""), startPath + "lib/angular/", new ByteArrayInputStream("".getBytes()), metadata); - s3FileSystem.getClient().putObject(bucket.replace("/", ""), startPath + "lib/angular-dynamic-locale/", new ByteArrayInputStream("".getBytes()), metadata); + final String startPath = "0000example" + UUID.randomUUID().toString() + "/"; + S3FileSystem s3FileSystem = (S3FileSystem) fileSystemAmazon; + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(0L); + s3FileSystem.getClient().putObject(bucket.replace("/", ""), startPath + "lib/angular/", new ByteArrayInputStream("".getBytes()), metadata); + s3FileSystem.getClient().putObject(bucket.replace("/", ""), startPath + "lib/angular-dynamic-locale/", new ByteArrayInputStream("".getBytes()), metadata); - S3Path s3Path = s3FileSystem.getPath(bucket, startPath, "lib", "angular"); - S3ObjectSummary result = getS3ObjectSummary(s3Path); + S3Path s3Path = s3FileSystem.getPath(bucket, startPath, "lib", "angular"); + S3ObjectSummary result = getS3ObjectSummary(s3Path); - assertEquals(startPath + "lib/angular/", result.getKey()); - } + assertEquals(startPath + "lib/angular/", result.getKey()); + } @Test - public void lookup_S3Object_when_S3Path_is_a_directory_and_is_virtual() throws IOException { + public void lookup_S3Object_when_S3Path_is_a_directory_and_is_virtual() throws IOException { - String folder = "angular" + UUID.randomUUID().toString(); - String key = folder + "/content.js"; + String folder = "angular" + UUID.randomUUID().toString(); + String key = folder + "/content.js"; - S3FileSystem s3FileSystem = (S3FileSystem) fileSystemAmazon; - s3FileSystem.getClient().putObject(bucket.replace("/", ""), key, new ByteArrayInputStream("contenido1".getBytes()), new ObjectMetadata()); + S3FileSystem s3FileSystem = (S3FileSystem) fileSystemAmazon; + s3FileSystem.getClient().putObject(bucket.replace("/", ""), key, new ByteArrayInputStream("contenido1".getBytes()), new ObjectMetadata()); - S3Path s3Path = (S3Path) fileSystemAmazon.getPath(bucket, folder); - S3ObjectSummary result = getS3ObjectSummary(s3Path); + S3Path s3Path = (S3Path) fileSystemAmazon.getPath(bucket, folder); + S3ObjectSummary result = getS3ObjectSummary(s3Path); - assertEquals(key, result.getKey()); - } + assertEquals(key, result.getKey()); + } public S3ObjectSummary getS3ObjectSummary(S3Path s3Path) throws NoSuchFileException { return new S3Utils().getS3ObjectSummary(s3Path); diff --git a/src/test/java/com/upplication/s3fs/S3WalkerTest.java b/src/test/java/com/upplication/s3fs/S3WalkerTest.java index 8b4a4a9..7cb53b0 100644 --- a/src/test/java/com/upplication/s3fs/S3WalkerTest.java +++ b/src/test/java/com/upplication/s3fs/S3WalkerTest.java @@ -20,218 +20,218 @@ public class S3WalkerTest extends S3UnitTestBase { - class RegisteringVisitor implements FileVisitor { - List visitOrder = new ArrayList<>(); - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - visitOrder.add("preVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - visitOrder.add("visitFile(" + file.toAbsolutePath().toString() + ")"); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { - visitOrder.add("visitFileFailed(" + file.toAbsolutePath().toString() + ", " + exc.getClass().getSimpleName() + "(" + exc.getMessage() + "))"); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - visitOrder.add("postVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); - return FileVisitResult.CONTINUE; - } - - public List getVisitOrder() { - return visitOrder; - } - } - - class CheckVisitor implements FileVisitor { - private Iterator iterator; - - public CheckVisitor(Iterator iterator) { - this.iterator = iterator; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "preVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "visitFile(" + file.toAbsolutePath().toString() + ")"); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { - assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "visitFileFailed(" + file.toAbsolutePath().toString() + ", " + exc.getClass().getSimpleName() + "(" + exc.getMessage() + "))"); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "postVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); - return FileVisitResult.CONTINUE; - } - } + class RegisteringVisitor implements FileVisitor { + List visitOrder = new ArrayList<>(); + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + visitOrder.add("preVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + visitOrder.add("visitFile(" + file.toAbsolutePath().toString() + ")"); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + visitOrder.add("visitFileFailed(" + file.toAbsolutePath().toString() + ", " + exc.getClass().getSimpleName() + "(" + exc.getMessage() + "))"); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + visitOrder.add("postVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); + return FileVisitResult.CONTINUE; + } + + public List getVisitOrder() { + return visitOrder; + } + } + + class CheckVisitor implements FileVisitor { + private Iterator iterator; + + public CheckVisitor(Iterator iterator) { + this.iterator = iterator; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + assertTrue(iterator.hasNext()); + assertEquals(iterator.next(), "preVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + assertTrue(iterator.hasNext()); + assertEquals(iterator.next(), "visitFile(" + file.toAbsolutePath().toString() + ")"); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + assertTrue(iterator.hasNext()); + assertEquals(iterator.next(), "visitFileFailed(" + file.toAbsolutePath().toString() + ", " + exc.getClass().getSimpleName() + "(" + exc.getMessage() + "))"); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + assertTrue(iterator.hasNext()); + assertEquals(iterator.next(), "postVisitDirectory(" + dir.toAbsolutePath().toString() + ")"); + return FileVisitResult.CONTINUE; + } + } @Before public void setup() throws IOException { FileSystems.newFileSystem(S3_GLOBAL_URI, null); } - @Test - public void walkFileTree() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket mocket = client.bucket("/tree"); - mocket.dir("folder", "folder/subfolder1"); - mocket.file("folder/subfolder1/file1.1", "folder/subfolder1/file1.2", "folder/subfolder1/file1.3", "folder/subfolder1/file1.4"); - mocket.file("folder/subfolder2/file2.1", "folder/subfolder2/file2.2", "folder/subfolder2/file2.3", "folder/subfolder2/file2.4"); - - S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); - reset(client); - RegisteringVisitor registrar = new RegisteringVisitor(); - Files.walkFileTree(folder, registrar); + @Test + public void walkFileTree() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket mocket = client.bucket("/tree"); + mocket.dir("folder", "folder/subfolder1"); + mocket.file("folder/subfolder1/file1.1", "folder/subfolder1/file1.2", "folder/subfolder1/file1.3", "folder/subfolder1/file1.4"); + mocket.file("folder/subfolder2/file2.1", "folder/subfolder2/file2.2", "folder/subfolder2/file2.3", "folder/subfolder2/file2.4"); + + S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); + reset(client); + RegisteringVisitor registrar = new RegisteringVisitor(); + Files.walkFileTree(folder, registrar); // 14: 2 for folders: one previst and one postvisit and 1 for files assertEquals(14, registrar.getVisitOrder().size()); - final Iterator iterator = registrar.getVisitOrder().iterator(); - reset(client); + final Iterator iterator = registrar.getVisitOrder().iterator(); + reset(client); Files.walkFileTree(folder, new CheckVisitor(iterator)); - assertFalse("Iterator should have been exhausted.", iterator.hasNext()); + assertFalse("Iterator should have been exhausted.", iterator.hasNext()); - reset(client); - Iterator iter = registrar.getVisitOrder().iterator(); + reset(client); + Iterator iter = registrar.getVisitOrder().iterator(); Files.walkFileTree(folder, Collections.emptySet(), 20, new CheckVisitor(iter)); - assertFalse("Iterator should have been exhausted.", iter.hasNext()); - } + assertFalse("Iterator should have been exhausted.", iter.hasNext()); + } - @Test - public void walkEmptyFileTree() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("tree").dir("folder"); + @Test + public void walkEmptyFileTree() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("tree").dir("folder"); - S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); - RegisteringVisitor registrar = new RegisteringVisitor(); + S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); + RegisteringVisitor registrar = new RegisteringVisitor(); - reset(client); - Files.walkFileTree(folder, registrar); + reset(client); + Files.walkFileTree(folder, registrar); assertEquals(2, registrar.getVisitOrder().size()); - final Iterator iterator = registrar.getVisitOrder().iterator(); - reset(client); + final Iterator iterator = registrar.getVisitOrder().iterator(); + reset(client); Files.walkFileTree(folder, new CheckVisitor(iterator)); - assertFalse("Iterator should have been exhausted.", iterator.hasNext()); - } - - @Test - public void walkLargeFileTree() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket mocket = client.bucket("/tree"); - for (int i = 0; i < 21; i++) { - for (int j = 0; j < 50; j++) { - StringBuilder filename = new StringBuilder("folder/subfolder"); - if (i < 10) - filename.append("0"); - filename.append(i); - filename.append("/file"); - if (j < 10) - filename.append("0"); - filename.append(j); - mocket.file(filename.toString()); - } - } - S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); - - reset(client); - RegisteringVisitor registrar = new RegisteringVisitor(); - Files.walkFileTree(folder, registrar); - assertEquals(1094, registrar.getVisitOrder().size()); - - final Iterator iterator = registrar.getVisitOrder().iterator(); - reset(client); + assertFalse("Iterator should have been exhausted.", iterator.hasNext()); + } + + @Test + public void walkLargeFileTree() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket mocket = client.bucket("/tree"); + for (int i = 0; i < 21; i++) { + for (int j = 0; j < 50; j++) { + StringBuilder filename = new StringBuilder("folder/subfolder"); + if (i < 10) + filename.append("0"); + filename.append(i); + filename.append("/file"); + if (j < 10) + filename.append("0"); + filename.append(j); + mocket.file(filename.toString()); + } + } + S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); + + reset(client); + RegisteringVisitor registrar = new RegisteringVisitor(); + Files.walkFileTree(folder, registrar); + assertEquals(1094, registrar.getVisitOrder().size()); + + final Iterator iterator = registrar.getVisitOrder().iterator(); + reset(client); Files.walkFileTree(folder, new CheckVisitor(iterator)); - assertFalse("Iterator should have been exhausted.", iterator.hasNext()); - } - - @Test - public void noSuchElementTreeWalk() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - client.bucket("/tree"); - S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); - reset(client); - RegisteringVisitor registrar = new RegisteringVisitor(); - Files.walkFileTree(folder, registrar); - assertEquals(1, registrar.getVisitOrder().size()); - - final Iterator iterator = registrar.getVisitOrder().iterator(); - reset(client); + assertFalse("Iterator should have been exhausted.", iterator.hasNext()); + } + + @Test + public void noSuchElementTreeWalk() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("/tree"); + S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); + reset(client); + RegisteringVisitor registrar = new RegisteringVisitor(); + Files.walkFileTree(folder, registrar); + assertEquals(1, registrar.getVisitOrder().size()); + + final Iterator iterator = registrar.getVisitOrder().iterator(); + reset(client); Files.walkFileTree(folder, new CheckVisitor(iterator)); - assertFalse("Iterator should have been exhausted.", iterator.hasNext()); - } - - @Test - public void skippingWalk() throws IOException { - AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); - MockBucket mocket = client.bucket("/tree"); - mocket.dir("folder", "folder/subfolder1"); - mocket.file("folder/subfolder1/file1.1", "folder/subfolder1/file1.2"); - mocket.file("folder/subfolder2/file2.1", "folder/subfolder2/file2.2"); - mocket.file("folder/subfolder3/file3.1", "folder/subfolder3/file3.2"); - mocket.file("folder/subfolder4/file4.1", "folder/subfolder4/file4.2"); - - S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); - reset(client); - final List visitation = new ArrayList<>(); - FileVisitor visitor = new FileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - String fileName = dir.getFileName().toString(); - if(fileName.equals("subfolder2")) - return FileVisitResult.SKIP_SUBTREE; - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - String name = file.getFileName().toString(); - visitation.add(name); - if(name.equals("file3.1")) - return FileVisitResult.SKIP_SIBLINGS; - if(name.equals("file4.1")) - return FileVisitResult.TERMINATE; - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - return FileVisitResult.CONTINUE; - } - }; - Files.walkFileTree(folder, visitor); - assertEquals(Arrays.asList("file1.1", "file1.2", "file3.1", "file4.1"), visitation); - - visitation.clear(); + assertFalse("Iterator should have been exhausted.", iterator.hasNext()); + } + + @Test + public void skippingWalk() throws IOException { + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + MockBucket mocket = client.bucket("/tree"); + mocket.dir("folder", "folder/subfolder1"); + mocket.file("folder/subfolder1/file1.1", "folder/subfolder1/file1.2"); + mocket.file("folder/subfolder2/file2.1", "folder/subfolder2/file2.2"); + mocket.file("folder/subfolder3/file3.1", "folder/subfolder3/file3.2"); + mocket.file("folder/subfolder4/file4.1", "folder/subfolder4/file4.2"); + + S3Path folder = (S3Path) Paths.get(URI.create(S3_GLOBAL_URI + "tree/folder")); + reset(client); + final List visitation = new ArrayList<>(); + FileVisitor visitor = new FileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + String fileName = dir.getFileName().toString(); + if (fileName.equals("subfolder2")) + return FileVisitResult.SKIP_SUBTREE; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String name = file.getFileName().toString(); + visitation.add(name); + if (name.equals("file3.1")) + return FileVisitResult.SKIP_SIBLINGS; + if (name.equals("file4.1")) + return FileVisitResult.TERMINATE; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + }; Files.walkFileTree(folder, visitor); - assertEquals(Arrays.asList("file1.1", "file1.2", "file3.1", "file4.1"), visitation); - } + assertEquals(Arrays.asList("file1.1", "file1.2", "file3.1", "file4.1"), visitation); + + visitation.clear(); + Files.walkFileTree(folder, visitor); + assertEquals(Arrays.asList("file1.1", "file1.2", "file3.1", "file4.1"), visitation); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/spike/EnvironmentIT.java b/src/test/java/com/upplication/s3fs/spike/EnvironmentIT.java index 8ee51ff..67a22c9 100644 --- a/src/test/java/com/upplication/s3fs/spike/EnvironmentIT.java +++ b/src/test/java/com/upplication/s3fs/spike/EnvironmentIT.java @@ -14,11 +14,11 @@ public class EnvironmentIT { @Test - public void couldCreateFileSystem() { - Map res = EnvironmentBuilder.getRealEnv(); + public void couldCreateFileSystem() { + Map res = EnvironmentBuilder.getRealEnv(); - assertNotNull(res); - assertNotNull(res.get(ACCESS_KEY)); - assertNotNull(res.get(SECRET_KEY)); - } + assertNotNull(res); + assertNotNull(res.get(ACCESS_KEY)); + assertNotNull(res.get(SECRET_KEY)); + } } diff --git a/src/test/java/com/upplication/s3fs/spike/InstallProviderTest.java b/src/test/java/com/upplication/s3fs/spike/InstallProviderTest.java index 6c6ecec..e996394 100644 --- a/src/test/java/com/upplication/s3fs/spike/InstallProviderTest.java +++ b/src/test/java/com/upplication/s3fs/spike/InstallProviderTest.java @@ -27,111 +27,111 @@ * FileSystems.newFileSystem busca mediante el serviceLoader los * posibles fileSystemsProvider y los llama con newFileSystem. * Si - * @author jarnaiz * + * @author jarnaiz */ public class InstallProviderTest { - @Before - public void cleanup() { - //clean resources - try { - FileSystems.getFileSystem(S3_GLOBAL_URI).close(); - } catch (FileSystemNotFoundException | IOException e) { - // ignore this - } - } - - @Test - public void useZipProvider() throws IOException { - - Path path = createZipTempFile(); - String pathFinal = pathToString(path); - - FileSystem fs = FileSystems.newFileSystem(URI.create("jar:file:" + pathFinal), new HashMap(), this.getClass().getClassLoader()); - Path zipPath = fs.getPath("test.zip"); - - assertNotNull(zipPath); - assertNotNull(zipPath.getFileSystem()); - assertNotNull(zipPath.getFileSystem().provider()); - //assertTrue(zipPath.getFileSystem().provider() instanceof com.sun.nio.zipfs.ZipFileSystemProvider); - } - - @Test(expected = FileSystemNotFoundException.class) - public void useZipProviderPathNotExists() throws IOException { - FileSystems.newFileSystem(URI.create("jar:file:/not/exists/zip.zip"), new HashMap(), this.getClass().getClassLoader()); - } - - @Test - public void useAlternativeZipProvider() throws IOException { - - Path path = createZipTempFile(); - String pathFinal = pathToString(path); - - FileSystem fs = FileSystems.newFileSystem(URI.create("zipfs:file:" + pathFinal), new HashMap(), this.getClass().getClassLoader()); - - Path zipPath = fs.getPath("test.zip"); - - assertNotNull(zipPath); - assertNotNull(zipPath.getFileSystem()); - assertNotNull(zipPath.getFileSystem().provider()); - assertTrue(zipPath.getFileSystem().provider() instanceof com.github.marschall.com.sun.nio.zipfs.ZipFileSystemProvider); - } - - @Test - public void newS3Provider() throws IOException { - URI uri = URI.create("s3:///hola/que/tal/"); - // if meta-inf/services/java.ni.spi.FileSystemProvider is not present with - // the content: com.upplication.s3fs.S3FileSystemProvider - // this method return ProviderNotFoundException - FileSystem fs = FileSystems.newFileSystem(uri, new HashMap(), this.getClass().getClassLoader()); - - Path path = fs.getPath("test.zip"); - assertNotNull(path); - assertNotNull(path.getFileSystem()); - assertNotNull(path.getFileSystem().provider()); - assertTrue(path.getFileSystem().provider() instanceof S3FileSystemProvider); - // close fs (FileSystems.getFileSystem throw exception) - fs.close(); - } - - @Test(expected = FileSystemNotFoundException.class) - public void getZipProvider() { - URI uri = URI.create("jar:file:/file.zip"); - FileSystems.getFileSystem(uri); - } - - // desviaton from spec - @Test(expected = FileSystemNotFoundException.class) - public void getZipPath() { - Paths.get(URI.create("jar:file:/file.zip!/BAR")); - } - - // desviation from spec - @Test(expected = FileSystemNotFoundException.class) - public void getMemoryPath() { - Paths.get(URI.create("memory:hellou:/file.zip")); - } - - // ~ helpers methods - - private Path createZipTempFile() throws IOException { - File zip = Files.createTempFile("temp", ".zip").toFile(); - - try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zip))) { - ZipEntry entry = new ZipEntry("text.txt"); - out.putNextEntry(entry); - } - - return zip.toPath(); - } - - private String pathToString(Path pathNext) { - StringBuilder pathFinal = new StringBuilder(); - - for (; pathNext.getParent() != null; pathNext = pathNext.getParent()) { - pathFinal.insert(0, "/" + pathNext.getFileName().toString()); - } - return pathFinal.toString(); - } + @Before + public void cleanup() { + //clean resources + try { + FileSystems.getFileSystem(S3_GLOBAL_URI).close(); + } catch (FileSystemNotFoundException | IOException e) { + // ignore this + } + } + + @Test + public void useZipProvider() throws IOException { + + Path path = createZipTempFile(); + String pathFinal = pathToString(path); + + FileSystem fs = FileSystems.newFileSystem(URI.create("jar:file:" + pathFinal), new HashMap(), this.getClass().getClassLoader()); + Path zipPath = fs.getPath("test.zip"); + + assertNotNull(zipPath); + assertNotNull(zipPath.getFileSystem()); + assertNotNull(zipPath.getFileSystem().provider()); + //assertTrue(zipPath.getFileSystem().provider() instanceof com.sun.nio.zipfs.ZipFileSystemProvider); + } + + @Test(expected = FileSystemNotFoundException.class) + public void useZipProviderPathNotExists() throws IOException { + FileSystems.newFileSystem(URI.create("jar:file:/not/exists/zip.zip"), new HashMap(), this.getClass().getClassLoader()); + } + + @Test + public void useAlternativeZipProvider() throws IOException { + + Path path = createZipTempFile(); + String pathFinal = pathToString(path); + + FileSystem fs = FileSystems.newFileSystem(URI.create("zipfs:file:" + pathFinal), new HashMap(), this.getClass().getClassLoader()); + + Path zipPath = fs.getPath("test.zip"); + + assertNotNull(zipPath); + assertNotNull(zipPath.getFileSystem()); + assertNotNull(zipPath.getFileSystem().provider()); + assertTrue(zipPath.getFileSystem().provider() instanceof com.github.marschall.com.sun.nio.zipfs.ZipFileSystemProvider); + } + + @Test + public void newS3Provider() throws IOException { + URI uri = URI.create("s3:///hola/que/tal/"); + // if meta-inf/services/java.ni.spi.FileSystemProvider is not present with + // the content: com.upplication.s3fs.S3FileSystemProvider + // this method return ProviderNotFoundException + FileSystem fs = FileSystems.newFileSystem(uri, new HashMap(), this.getClass().getClassLoader()); + + Path path = fs.getPath("test.zip"); + assertNotNull(path); + assertNotNull(path.getFileSystem()); + assertNotNull(path.getFileSystem().provider()); + assertTrue(path.getFileSystem().provider() instanceof S3FileSystemProvider); + // close fs (FileSystems.getFileSystem throw exception) + fs.close(); + } + + @Test(expected = FileSystemNotFoundException.class) + public void getZipProvider() { + URI uri = URI.create("jar:file:/file.zip"); + FileSystems.getFileSystem(uri); + } + + // desviaton from spec + @Test(expected = FileSystemNotFoundException.class) + public void getZipPath() { + Paths.get(URI.create("jar:file:/file.zip!/BAR")); + } + + // desviation from spec + @Test(expected = FileSystemNotFoundException.class) + public void getMemoryPath() { + Paths.get(URI.create("memory:hellou:/file.zip")); + } + + // ~ helpers methods + + private Path createZipTempFile() throws IOException { + File zip = Files.createTempFile("temp", ".zip").toFile(); + + try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zip))) { + ZipEntry entry = new ZipEntry("text.txt"); + out.putNextEntry(entry); + } + + return zip.toPath(); + } + + private String pathToString(Path pathNext) { + StringBuilder pathFinal = new StringBuilder(); + + for (; pathNext.getParent() != null; pathNext = pathNext.getParent()) { + pathFinal.insert(0, "/" + pathNext.getFileName().toString()); + } + return pathFinal.toString(); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/spike/PathSpecTest.java b/src/test/java/com/upplication/s3fs/spike/PathSpecTest.java index 4190e49..ca217c8 100644 --- a/src/test/java/com/upplication/s3fs/spike/PathSpecTest.java +++ b/src/test/java/com/upplication/s3fs/spike/PathSpecTest.java @@ -18,154 +18,154 @@ public class PathSpecTest { - FileSystem fs; - - @Before - public void setup() throws IOException { - fs = MemoryFileSystemBuilder.newLinux().build("linux"); - } - - @After - public void close() throws IOException { - fs.close(); - } - - // first and more - - @Test - public void firstAndMore() { - assertEquals(fs.getPath("/dir", "dir", "file"), fs.getPath("/dir", "dir/file")); - assertEquals(fs.getPath("/dir/dir/file"), fs.getPath("/dir", "dir/file")); - } - - // absolute relative - - @Test - public void relative() { - assertTrue(!get("file").isAbsolute()); - } - - @Test - public void absolute() { - assertTrue(get("/file/file2").isAbsolute()); - } - - // test starts with - - @Test - public void startsWith() { - assertTrue(get("/file/file1").startsWith(get("/file"))); - } - - @Test - public void startsWithBlank() { - assertFalse(get("/file").startsWith(get(""))); - } - - @Test - public void startsWithBlankRelative() { - assertFalse(get("file1").startsWith(get(""))); - } - - @Test - public void startsWithBlankBlank() { - assertTrue(get("").startsWith(get(""))); - } - - @Test - public void startsWithRelativeVsAbsolute() { - assertFalse(get("/file/file1").startsWith(get("file"))); - } - - @Test - public void startsWithFalse() { - assertFalse(get("/file/file1").startsWith(get("/file/file1/file2"))); - assertTrue(get("/file/file1/file2").startsWith(get("/file/file1"))); - } - - @Test - public void startsWithNotNormalize() { - assertFalse(get("/file/file1/file2").startsWith(get("/file/file1/../"))); - } - - @Test - public void startsWithNormalize() { - assertTrue(get("/file/file1/file2").startsWith(get("/file/file1/../").normalize())); - } - - @Test - public void startsWithRelative() { - assertTrue(get("file/file1").startsWith(get("file"))); - } - - @Test - public void startsWithString() { - assertTrue(get("/file/file1").startsWith("/file")); - } - - // ends with - - @Test - public void endsWithAbsoluteRelative() { - assertTrue(get("/file/file1").endsWith(get("file1"))); - } - - @Test - public void endsWithAbsoluteAbsolute() { - assertTrue(get("/file/file1").endsWith(get("/file/file1"))); - } - - @Test - public void endsWithRelativeRelative() { - assertTrue(get("file/file1").endsWith(get("file1"))); - } - - @Test - public void endsWithRelativeAbsolute() { - assertFalse(get("file/file1").endsWith(get("/file"))); - } - - @Test - public void endsWithDifferenteFileSystem() { - assertFalse(get("/file/file1").endsWith(Paths.get("/file/file1"))); - } - - @Test - public void endsWithBlankRelativeAbsolute() { - assertFalse(get("").endsWith(get("/bucket"))); - } - - @Test - public void endsWithBlankBlank() { - assertTrue(get("").endsWith(get(""))); - } - - @Test - public void endsWithRelativeBlankAbsolute() { - assertFalse(get("/bucket/file1").endsWith(get(""))); - } - - @Test - public void endsWithRelativeBlankRelative() { - assertFalse(get("file1").endsWith(get(""))); - } - - // file name - - @Test - public void getFileName() throws IOException { - try (FileSystem windows = MemoryFileSystemBuilder.newWindows().build("widows")) { - Path fileName = windows.getPath("C:/file").getFileName(); - Path rootName = windows.getPath("C:/").getFileName(); - - assertEquals(windows.getPath("file"), fileName); - assertNull(rootName); - } - } - - // ~ helpers methods - - private Path get(String path) { - return fs.getPath(path); - } + FileSystem fs; + + @Before + public void setup() throws IOException { + fs = MemoryFileSystemBuilder.newLinux().build("linux"); + } + + @After + public void close() throws IOException { + fs.close(); + } + + // first and more + + @Test + public void firstAndMore() { + assertEquals(fs.getPath("/dir", "dir", "file"), fs.getPath("/dir", "dir/file")); + assertEquals(fs.getPath("/dir/dir/file"), fs.getPath("/dir", "dir/file")); + } + + // absolute relative + + @Test + public void relative() { + assertTrue(!get("file").isAbsolute()); + } + + @Test + public void absolute() { + assertTrue(get("/file/file2").isAbsolute()); + } + + // test starts with + + @Test + public void startsWith() { + assertTrue(get("/file/file1").startsWith(get("/file"))); + } + + @Test + public void startsWithBlank() { + assertFalse(get("/file").startsWith(get(""))); + } + + @Test + public void startsWithBlankRelative() { + assertFalse(get("file1").startsWith(get(""))); + } + + @Test + public void startsWithBlankBlank() { + assertTrue(get("").startsWith(get(""))); + } + + @Test + public void startsWithRelativeVsAbsolute() { + assertFalse(get("/file/file1").startsWith(get("file"))); + } + + @Test + public void startsWithFalse() { + assertFalse(get("/file/file1").startsWith(get("/file/file1/file2"))); + assertTrue(get("/file/file1/file2").startsWith(get("/file/file1"))); + } + + @Test + public void startsWithNotNormalize() { + assertFalse(get("/file/file1/file2").startsWith(get("/file/file1/../"))); + } + + @Test + public void startsWithNormalize() { + assertTrue(get("/file/file1/file2").startsWith(get("/file/file1/../").normalize())); + } + + @Test + public void startsWithRelative() { + assertTrue(get("file/file1").startsWith(get("file"))); + } + + @Test + public void startsWithString() { + assertTrue(get("/file/file1").startsWith("/file")); + } + + // ends with + + @Test + public void endsWithAbsoluteRelative() { + assertTrue(get("/file/file1").endsWith(get("file1"))); + } + + @Test + public void endsWithAbsoluteAbsolute() { + assertTrue(get("/file/file1").endsWith(get("/file/file1"))); + } + + @Test + public void endsWithRelativeRelative() { + assertTrue(get("file/file1").endsWith(get("file1"))); + } + + @Test + public void endsWithRelativeAbsolute() { + assertFalse(get("file/file1").endsWith(get("/file"))); + } + + @Test + public void endsWithDifferenteFileSystem() { + assertFalse(get("/file/file1").endsWith(Paths.get("/file/file1"))); + } + + @Test + public void endsWithBlankRelativeAbsolute() { + assertFalse(get("").endsWith(get("/bucket"))); + } + + @Test + public void endsWithBlankBlank() { + assertTrue(get("").endsWith(get(""))); + } + + @Test + public void endsWithRelativeBlankAbsolute() { + assertFalse(get("/bucket/file1").endsWith(get(""))); + } + + @Test + public void endsWithRelativeBlankRelative() { + assertFalse(get("file1").endsWith(get(""))); + } + + // file name + + @Test + public void getFileName() throws IOException { + try (FileSystem windows = MemoryFileSystemBuilder.newWindows().build("widows")) { + Path fileName = windows.getPath("C:/file").getFileName(); + Path rootName = windows.getPath("C:/").getFileName(); + + assertEquals(windows.getPath("file"), fileName); + assertNull(rootName); + } + } + + // ~ helpers methods + + private Path get(String path) { + return fs.getPath(path); + } } diff --git a/src/test/java/com/upplication/s3fs/spike/ProviderSpecTest.java b/src/test/java/com/upplication/s3fs/spike/ProviderSpecTest.java index 0ebb846..2e522e6 100644 --- a/src/test/java/com/upplication/s3fs/spike/ProviderSpecTest.java +++ b/src/test/java/com/upplication/s3fs/spike/ProviderSpecTest.java @@ -19,63 +19,63 @@ import com.github.marschall.memoryfilesystem.MemoryFileSystemBuilder; public class ProviderSpecTest { - FileSystem fs; - - @Before - public void setup() throws IOException { - fs = MemoryFileSystemBuilder.newLinux().build("linux"); - } - - @After - public void close() throws IOException { - fs.close(); - } - - @Test - public void readNothing() throws IOException { - //Path base = Files.createDirectories(fs.getPath("/dir")); - Path base = Files.createTempDirectory("asdadadasd"); - try (SeekableByteChannel seekable = Files.newByteChannel(Files.createFile(base.resolve("file1.html")), EnumSet.of(StandardOpenOption.DELETE_ON_CLOSE))) { - // do nothing - } - assertTrue(Files.notExists(base.resolve("file1.html"))); - } - - // FIXME @Test - public void seekable() throws IOException { - Path base = Files.createDirectories(fs.getPath("/dir")); - // in windows throw exception - try (SeekableByteChannel seekable = Files.newByteChannel(base.resolve("file1.html"), - EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ))) { - - ByteBuffer buffer = ByteBuffer.wrap("content".getBytes()); - seekable.position(7); - seekable.write(buffer); - - ByteBuffer bufferRead = ByteBuffer.allocate(7); - bufferRead.clear(); - seekable.read(bufferRead); - - assertArrayEquals(bufferRead.array(), buffer.array()); - } - } - - @Test - public void seekableRead() throws IOException { - /* - Path base = Files.createDirectories(fs.getPath("/dir")); + FileSystem fs; + + @Before + public void setup() throws IOException { + fs = MemoryFileSystemBuilder.newLinux().build("linux"); + } + + @After + public void close() throws IOException { + fs.close(); + } + + @Test + public void readNothing() throws IOException { + //Path base = Files.createDirectories(fs.getPath("/dir")); + Path base = Files.createTempDirectory("asdadadasd"); + try (SeekableByteChannel seekable = Files.newByteChannel(Files.createFile(base.resolve("file1.html")), EnumSet.of(StandardOpenOption.DELETE_ON_CLOSE))) { + // do nothing + } + assertTrue(Files.notExists(base.resolve("file1.html"))); + } + + // FIXME @Test + public void seekable() throws IOException { + Path base = Files.createDirectories(fs.getPath("/dir")); + // in windows throw exception + try (SeekableByteChannel seekable = Files.newByteChannel(base.resolve("file1.html"), + EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ))) { + + ByteBuffer buffer = ByteBuffer.wrap("content".getBytes()); + seekable.position(7); + seekable.write(buffer); + + ByteBuffer bufferRead = ByteBuffer.allocate(7); + bufferRead.clear(); + seekable.read(bufferRead); + + assertArrayEquals(bufferRead.array(), buffer.array()); + } + } + + @Test + public void seekableRead() throws IOException { + /* + Path base = Files.createDirectories(fs.getPath("/dir")); Path path = Files.write(base.resolve("file"), "contenido yuhu".getBytes(), StandardOpenOption.CREATE_NEW); */ - Path path = Files.write(Files.createTempFile("asdas", "asdsadad"), "contenido uyuhu".getBytes(), StandardOpenOption.APPEND); - try (SeekableByteChannel channel = Files.newByteChannel(path)) { + Path path = Files.write(Files.createTempFile("asdas", "asdsadad"), "contenido uyuhu".getBytes(), StandardOpenOption.APPEND); + try (SeekableByteChannel channel = Files.newByteChannel(path)) { - //channel = Paths.get("Path to file").newByteChannel(StandardOpenOption.READ); - ByteBuffer buffer = ByteBuffer.allocate(4096); + //channel = Paths.get("Path to file").newByteChannel(StandardOpenOption.READ); + ByteBuffer buffer = ByteBuffer.allocate(4096); - while (channel.read(buffer) > 0) { - buffer.rewind(); - buffer.flip(); - } + while (channel.read(buffer) > 0) { + buffer.rewind(); + buffer.flip(); + } /* ByteBuffer buffer = ByteBuffer.allocate(1024); @@ -105,6 +105,6 @@ public void seekableRead() throws IOException { System.out.println("\nNumber of bytes read: " + numberOfBytesRead); } */ - } - } + } + } } diff --git a/src/test/java/com/upplication/s3fs/spike/SpecTest.java b/src/test/java/com/upplication/s3fs/spike/SpecTest.java index 919dc82..e732c95 100644 --- a/src/test/java/com/upplication/s3fs/spike/SpecTest.java +++ b/src/test/java/com/upplication/s3fs/spike/SpecTest.java @@ -3,10 +3,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.io.IOException; import java.nio.file.FileSystems; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributeView; import java.nio.file.spi.FileSystemProvider; import java.util.List; +import java.util.Map; import org.junit.Test; @@ -20,6 +24,13 @@ public void parentOfRelativeSinglePathIsNull() { assertNull(path.getParent()); } + @Test + public void readAttributes() throws IOException { + Path path = Files.createTempFile("asdas", "sdasda"); + Map attrs = Files.readAttributes(path, "*"); + Map attrs2 = Files.readAttributes(path, "lastModifiedTime"); + } + @Test public void installedFileSystemsLoadFromMetaInf() { List providers = FileSystemProvider.installedProviders(); diff --git a/src/test/java/com/upplication/s3fs/util/AmazonS3ClientMock.java b/src/test/java/com/upplication/s3fs/util/AmazonS3ClientMock.java index b4a3038..520254b 100644 --- a/src/test/java/com/upplication/s3fs/util/AmazonS3ClientMock.java +++ b/src/test/java/com/upplication/s3fs/util/AmazonS3ClientMock.java @@ -7,9 +7,9 @@ * The ASF licenses this file to You 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 - * + *

+ * 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. @@ -120,1096 +120,1099 @@ import com.amazonaws.util.StringUtils; public class AmazonS3ClientMock implements AmazonS3 { - /** - * max elements amazon aws - */ - private static final int LIMIT_AWS_MAX_ELEMENTS = 1000; - - // default owner - private Owner defaultOwner = new Owner() { - private static final long serialVersionUID = 5510838843790352879L; - { - setDisplayName("Mock"); - setId("1"); - } - }; - - private Path base; - private Map bucketOwners = new HashMap<>(); - - public AmazonS3ClientMock(Path base) { - this.base = base; - } - - /** - * list all objects without and return ObjectListing with all elements - * and with truncated to false - */ - @Override - public ObjectListing listObjects(ListObjectsRequest listObjectsRequest) throws AmazonClientException { - String bucketName = listObjectsRequest.getBucketName(); - String prefix = listObjectsRequest.getPrefix(); - String marker = listObjectsRequest.getMarker(); - String delimiter = listObjectsRequest.getDelimiter(); - - ObjectListing objectListing = new ObjectListing(); - objectListing.setBucketName(bucketName); - objectListing.setPrefix(prefix); - objectListing.setMarker(marker); - objectListing.setDelimiter(delimiter); - - final Path bucket = find(bucketName); - final TreeMap elems = new TreeMap<>(); - try { - for (Path elem : Files.newDirectoryStream(bucket)) { - S3Element element = parse(elem, bucket); - if (!elems.containsKey(element.getS3Object().getKey())) - elems.put(element.getS3Object().getKey(), element); - } - } catch (IOException e) { - throw new AmazonClientException(e); - } - Iterator iterator = elems.values().iterator(); - int i = 0; - boolean waitForMarker = !StringUtils.isNullOrEmpty(marker); - while (iterator.hasNext()) { - S3Element elem = iterator.next(); - if (elem.getS3Object().getKey().equals("/")) - continue; - String key = elem.getS3Object().getKey(); - if(waitForMarker) { - waitForMarker = !key.startsWith(marker); - if(waitForMarker) - continue; - } - - if (prefix != null && key.startsWith(prefix)) { - int beginIndex = key.indexOf(prefix) + prefix.length(); - String rest = key.substring(beginIndex); - if(delimiter != null && delimiter.length() > 0 && rest.contains(delimiter)) { - String substring = key.substring(0, beginIndex + rest.indexOf(delimiter)); - if(!objectListing.getCommonPrefixes().contains(substring)) - objectListing.getCommonPrefixes().add(substring); - continue; - } - S3ObjectSummary s3ObjectSummary = parseToS3ObjectSummary(elem); - objectListing.getObjectSummaries().add(s3ObjectSummary); - - if (i + 1 == LIMIT_AWS_MAX_ELEMENTS && iterator.hasNext()) { - objectListing.setTruncated(true); - objectListing.setNextMarker(iterator.next().getS3Object().getKey()); - return objectListing; - } - objectListing.setTruncated(false); - - i++; - } - - } - Collections.sort(objectListing.getObjectSummaries(), new Comparator() { - @Override - public int compare(S3ObjectSummary o1, S3ObjectSummary o2) { - return o1.getKey().compareTo(o2.getKey()); - } - }); - return objectListing; - } - - @Override - public ObjectListing listNextBatchOfObjects(ObjectListing previousObjectListing) { - ObjectListing objectListing = new ObjectListing(); - objectListing.setBucketName(previousObjectListing.getBucketName()); - objectListing.setPrefix(previousObjectListing.getPrefix()); - objectListing.setMarker(previousObjectListing.getMarker()); - objectListing.setDelimiter(previousObjectListing.getDelimiter()); - - if (!previousObjectListing.isTruncated() || previousObjectListing.getNextMarker() == null) { - return objectListing; - } - - Path bucket = find(previousObjectListing.getBucketName()); - List elems = new ArrayList<>(); - try { - for (Path elem : Files.newDirectoryStream(bucket)) { - elems.add(parse(elem, bucket)); - } - } catch (IOException e) { - throw new AmazonClientException(e); - } - Collections.sort(elems, new Comparator(){ - @Override - public int compare(S3Element o1, S3Element o2) { - return o1.getS3Object().getKey().compareTo(o2.getS3Object().getKey()); - }}); - Iterator iterator = elems.iterator(); - - int i = 0; - boolean continueElement = false; - - while (iterator.hasNext()) { - - S3Element elem = iterator.next(); - - if (!continueElement && elem.getS3Object().getKey().equals(previousObjectListing.getNextMarker())) { - continueElement = true; - } - - if (continueElement) { - // TODO. add delimiter and marker support - if (previousObjectListing.getPrefix() != null && elem.getS3Object().getKey().startsWith(previousObjectListing.getPrefix())) { - - S3ObjectSummary s3ObjectSummary = parseToS3ObjectSummary(elem); - objectListing.getObjectSummaries().add(s3ObjectSummary); - // max 1000 elements at same time. - if (i + 1 == LIMIT_AWS_MAX_ELEMENTS && iterator.hasNext()) { - objectListing.setTruncated(true); - objectListing.setNextMarker(iterator.next().getS3Object().getKey()); - return objectListing; - } - objectListing.setTruncated(false); - i++; - } - } - } - - return objectListing; - } - - /** - * create a new S3ObjectSummary using the S3Element - * @param elem S3Element to parse - * @return S3ObjectSummary - */ - private S3ObjectSummary parseToS3ObjectSummary(S3Element elem) { - S3Object s3Object = elem.getS3Object(); - ObjectMetadata objectMetadata = s3Object.getObjectMetadata(); - S3ObjectSummary s3ObjectSummary = new S3ObjectSummary(); - s3ObjectSummary.setBucketName(s3Object.getBucketName()); - s3ObjectSummary.setKey(s3Object.getKey()); - s3ObjectSummary.setLastModified(objectMetadata.getLastModified()); - s3ObjectSummary.setOwner(getOwner(s3Object.getBucketName())); - s3ObjectSummary.setETag(objectMetadata.getETag()); - s3ObjectSummary.setSize(objectMetadata.getContentLength()); - return s3ObjectSummary; - } - - private Owner getOwner(String bucketName) { - if (!bucketOwners.containsKey(bucketName)) - return defaultOwner; - return bucketOwners.get(bucketName); - } - - @Override - public Owner getS3AccountOwner() throws AmazonClientException { - return defaultOwner; - } - - public void setS3AccountOwner(Owner owner) { - this.defaultOwner = owner; - } - - @Override - public List listBuckets() throws AmazonClientException { - List result = new ArrayList<>(); - try { - for (Path path : Files.newDirectoryStream(base)) { - String bucketName = path.getFileName().toString(); - Bucket bucket = new Bucket(bucketName); - bucket.setOwner(getOwner(bucketName)); - bucket.setCreationDate(new Date(Files.readAttributes(path, BasicFileAttributes.class).creationTime().toMillis())); - result.add(bucket); - } - } catch (IOException e) { - throw new AmazonClientException(e); - } - return result; - } - - @Override - public Bucket createBucket(CreateBucketRequest createBucketRequest) throws AmazonClientException, AmazonServiceException { - return createBucket(createBucketRequest.getBucketName()); - } - - @Override - public Bucket createBucket(String bucketName) throws AmazonClientException, AmazonServiceException { - try { - String name = bucketName.replaceAll("//", ""); - Path path = Files.createDirectories(base.resolve(name)); - Bucket bucket = new Bucket(name); - bucket.setOwner(getOwner(name)); - bucket.setCreationDate(new Date(Files.readAttributes(path, BasicFileAttributes.class).creationTime().toMillis())); - return bucket; - } catch (IOException e) { - throw new AmazonClientException(e); - } - } - - @Override - public AccessControlList getObjectAcl(String bucketName, String key) throws AmazonClientException { - Path elem = find(bucketName, key); - if (elem != null) { - try { - return parse(elem, find(bucketName)).getPermission(); - } catch (IOException e) { - throw new AmazonServiceException("Problem getting mock ACL: ", e); - } - } - throw new AmazonServiceException("key not found, " + key); - } - - @Override - public AccessControlList getBucketAcl(String bucketName) throws AmazonClientException { - Path bucket = find(bucketName); - if (bucket == null) { - throw new AmazonServiceException("bucket not found, " + bucketName); - } - return createAllPermission(bucketName); - } - - @Override - public S3Object getObject(String bucketName, String key) throws AmazonClientException { - Path result = find(bucketName, key); - if (result == null || !Files.exists(result)) { - result = find(bucketName, key+"/"); - } - if (result == null || !Files.exists(result)) { - AmazonS3Exception amazonS3Exception = new AmazonS3Exception("not found with key: " + key); - amazonS3Exception.setStatusCode(404); - throw amazonS3Exception; - } - try { - return parse(result, find(bucketName)).getS3Object(); - } catch (IOException e) { - throw new AmazonServiceException("Problem getting Mock Object: ", e); - } - } - - @Override - public PutObjectResult putObject(String bucketName, String key, File file) throws AmazonClientException { - try { - ByteArrayInputStream stream = new ByteArrayInputStream(Files.readAllBytes(file.toPath())); - S3Element elem = parse(stream, bucketName, key); - - persist(bucketName, elem); - - PutObjectResult putObjectResult = new PutObjectResult(); - putObjectResult.setETag("3a5c8b1ad448bca04584ecb55b836264"); - return putObjectResult; - } catch (IOException e) { - throw new AmazonServiceException("", e); - } - - } - - @Override - public PutObjectResult putObject(String bucket, String keyName, InputStream inputStream, ObjectMetadata metadata) { - S3Element elem = parse(inputStream, bucket, keyName); - - persist(bucket, elem); - - PutObjectResult putObjectResult = new PutObjectResult(); - putObjectResult.setETag("3a5c8b1ad448bca04584ecb55b836264"); - return putObjectResult; - - } - - /** - * store in the memory map - * @param bucketName bucket where persist - * @param elem - */ - private void persist(String bucketName, S3Element elem) { - Path bucket = find(bucketName); - String key = elem.getS3Object().getKey().replaceAll("/", "%2F"); - Path resolve = bucket.resolve(key); - if (Files.exists(resolve)) - try { - Files.delete(resolve); - } catch (IOException e1) { - // ignore - } - - try { - Files.createFile(resolve); - S3ObjectInputStream objectContent = elem.getS3Object().getObjectContent(); - if (objectContent != null) { - byte[] byteArray = IOUtils.toByteArray(objectContent); - Files.write(resolve, byteArray); - } - } catch (IOException e) { - throw new AmazonServiceException("Problem creating mock element: ", e); - } - } - - @Override - public CopyObjectResult copyObject(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey) throws AmazonClientException { - Path src = find(sourceBucketName, sourceKey); - if (src != null && Files.exists(src)) { - Path bucket = find(destinationBucketName); - Path dest = bucket.resolve(destinationKey.replaceAll("/", "%2F")); - try { - Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - throw new AmazonServiceException("Problem copying mock objects: ", e); - } - - return new CopyObjectResult(); - } - - throw new AmazonServiceException("object source not found"); - } - - @Override - public void deleteObject(String bucketName, String key) throws AmazonClientException { - Path bucket = find(bucketName); - Path resolve = bucket.resolve(key); - if (Files.exists(resolve)) - try { - Files.delete(resolve); - } catch (IOException e) { - throw new AmazonServiceException("Problem deleting mock object: ", e); - } - else { - resolve = bucket.resolve(key.replaceAll("/", "%2F")); - if(Files.exists(resolve)) - try { - Files.delete(resolve); - } catch (IOException e) { - throw new AmazonServiceException("Problem deleting mock object: ", e); - } - } - } - - private S3Element parse(InputStream stream, String bucketName, String key) { - S3Object object = new S3Object(); - object.setBucketName(bucketName); - object.setKey(key); - byte[] content; - try { - content = IOUtils.toByteArray(stream); - } catch (IOException e) { - throw new IllegalStateException("the stream is closed", e); - } finally { - try { - object.close(); - } catch (IOException e) { - // ignore - } - } - - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setLastModified(new Date()); - metadata.setContentLength(content.length); - - object.setObjectContent(new ByteArrayInputStream(content)); - object.setObjectMetadata(metadata); - // TODO: create converter between path permission and s3 permission - AccessControlList permission = createAllPermission(bucketName); - return new S3Element(object, permission, false); - } - - private S3Element parse(Path elem, Path bucket) throws IOException { - S3Object object = new S3Object(); - - String bucketName = bucket.getFileName().toString(); - object.setBucketName(bucketName); - - String key = bucket.relativize(elem).toString().replaceAll("%2F", "/"); - boolean dir = key.endsWith("/") || key.isEmpty(); - object.setKey(key); - - ObjectMetadata metadata = new ObjectMetadata(); - BasicFileAttributes attr = Files.readAttributes(elem, BasicFileAttributes.class); - metadata.setLastModified(new Date(attr.lastAccessTime().toMillis())); - if (dir) { - metadata.setContentLength(0); - object.setObjectContent(null); - } else { - metadata.setContentLength(attr.size()); - object.setObjectContent(new ByteArrayInputStream(Files.readAllBytes(elem))); - } - - object.setObjectMetadata(metadata); - // TODO: create converter between path permission and s3 permission - AccessControlList permission = createAllPermission(bucketName); - - return new S3Element(object, permission, dir); - } - - private AccessControlList createAllPermission(String bucketName) { - AccessControlList res = new AccessControlList(); - final Owner owner = getOwner(bucketName); - res.setOwner(owner); - Grantee grant = new Grantee() { - @Override - public void setIdentifier(String id) { - // - } - - @Override - public String getTypeIdentifier() { - return owner.getId(); - } - - @Override - public String getIdentifier() { - return owner.getId(); - } - }; - - res.grantPermission(grant, Permission.FullControl); - res.grantPermission(grant, Permission.Read); - res.grantPermission(grant, Permission.Write); - return res; - } - public AccessControlList createReadOnly(String bucketName) { - return createReadOnly(getOwner(bucketName)); - } - - public AccessControlList createReadOnly(final Owner owner) { - AccessControlList res = new AccessControlList(); - res.setOwner(owner); - Grantee grant = new Grantee() { - @Override - public void setIdentifier(String id) { - // - } - - @Override - public String getTypeIdentifier() { - return owner.getId(); - } - - @Override - public String getIdentifier() { - return owner.getId(); - } - }; - res.grantPermission(grant, Permission.Read); - return res; - } - - private Path find(String bucketName, final String key) { - final Path bucket = find(bucketName); - if (bucket == null || !Files.exists(bucket)) { - return null; - } - try { - final String fileKey = key.replaceAll("/", "%2F"); - final List matches = new ArrayList(); - Files.walkFileTree(bucket, new SimpleFileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - String relativize = bucket.relativize(dir).toString(); - if (relativize.equals(fileKey)) { - matches.add(dir); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - String relativize = bucket.relativize(file).toString(); - if (relativize.equals(fileKey)) { - matches.add(file); - } - return FileVisitResult.CONTINUE; - } - }); - if (!matches.isEmpty()) - return matches.iterator().next(); - } catch (IOException e) { - throw new AmazonServiceException("Problem getting mock S3Element: ", e); - } - - return null; - } - - private Path find(String bucketName) { - return base.resolve(bucketName); - } - - public static class S3Element { - - private S3Object s3Object; - private boolean directory; - private AccessControlList permission; - - public S3Element(S3Object s3Object, AccessControlList permission, boolean directory) { - this.s3Object = s3Object; - this.directory = directory; - this.permission = permission; - } - - public S3Object getS3Object() { - return s3Object; - } - - public void setS3Object(S3Object s3Object) { - this.s3Object = s3Object; - } - - public AccessControlList getPermission() { - return permission; - } - - public boolean isDirectory() { - return directory; - } - - public void setDirectory(boolean directory) { - this.directory = directory; - } - - public void setPermission(AccessControlList permission) { - this.permission = permission; - } - - @Override - public boolean equals(Object object) { - - if (object == null) { - return false; - } - - if (object instanceof S3Element) { - S3Element elem = (S3Element) object; - // only is the same if bucketname and key are not null and are the same - if (elem.getS3Object() != null && this.getS3Object() != null && elem.getS3Object().getBucketName() != null - && elem.getS3Object().getBucketName().equals(this.getS3Object().getBucketName()) && elem.getS3Object().getKey() != null - && elem.getS3Object().getKey().equals(this.getS3Object().getKey())) { - return true; - } - - return false; - } - return false; - } - - @Override - public int hashCode() { - int result = s3Object != null && s3Object.getBucketName() != null ? s3Object.getBucketName().hashCode() : 0; - result = 31 * result + (s3Object != null && s3Object.getKey() != null ? s3Object.getKey().hashCode() : 0); - return result; - } - } - - @Override - public ObjectMetadata getObjectMetadata(String bucketName, String key) { - S3Object object = getObject(bucketName, key); - if (object.getKey().equals(key)) - return object.getObjectMetadata(); - AmazonS3Exception exception = new AmazonS3Exception("Resource not available: " + bucketName + "/" + key); - exception.setStatusCode(404); - throw exception; - } - - @Override - public boolean doesBucketExist(String bucketName) throws AmazonClientException, AmazonServiceException { - return Files.exists(base.resolve(bucketName)); - } - - public MockBucket bucket(String bucketName) throws IOException { - return new MockBucket(this, Files.createDirectories(base.resolve(bucketName))); - } - - public Path bucket(String bucketName, Owner owner) throws IOException { - bucketOwners.put(bucketName, owner); - return Files.createDirectories(base.resolve(bucketName)); - } - - @Override - public void deleteBucket(String bucketName) throws AmazonClientException, AmazonServiceException { - try { - Path bucket = base.resolve(bucketName); - Files.walkFileTree(bucket, new SimpleFileVisitor() { - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - }); - } catch (IOException e) { - throw new AmazonClientException(e); - } - } - - public void addFile(Path bucket, String fileName) throws IOException { - if(fileName.endsWith("/")) - fileName.substring(0, fileName.length()-1); - Files.createFile(bucket.resolve(fileName.replaceAll("/", "%2F"))); - } - - public void addFile(Path bucket, String fileName, byte[] content) throws IOException { - if(fileName.endsWith("/")) - fileName.substring(0, fileName.length()-1); - Path file = Files.createFile(bucket.resolve(fileName.replaceAll("/", "%2F"))); - OutputStream outputStream = Files.newOutputStream(file); - outputStream.write(content); - outputStream.close(); - } - - public void addDirectory(Path bucket, String directoryName) throws IOException { - if(!directoryName.endsWith("/")) - directoryName+="/"; - Files.createFile(bucket.resolve(directoryName.replaceAll("/", "%2F"))); - } - - public void clear() { - try { - Files.walkFileTree(base, new SimpleFileVisitor() { - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - if (dir != base) - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - }); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void setEndpoint(String endpoint) { - throw new UnsupportedOperationException(); - } - - @Override - public void setRegion(Region region) throws IllegalArgumentException { - throw new UnsupportedOperationException(); - } - - @Override - public void setS3ClientOptions(S3ClientOptions clientOptions) { - throw new UnsupportedOperationException(); - } - - @Override - public void changeObjectStorageClass(String bucketName, String key, StorageClass newStorageClass) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setObjectRedirectLocation(String bucketName, String key, String newRedirectLocation) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public ObjectListing listObjects(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public ObjectListing listObjects(String bucketName, String prefix) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public VersionListing listVersions(String bucketName, String prefix) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public VersionListing listNextBatchOfVersions(VersionListing previousVersionListing) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public VersionListing listVersions(String bucketName, String prefix, String keyMarker, String versionIdMarker, String delimiter, Integer maxResults) - throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public VersionListing listVersions(ListVersionsRequest listVersionsRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public List listBuckets(ListBucketsRequest listBucketsRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public String getBucketLocation(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public String getBucketLocation(GetBucketLocationRequest getBucketLocationRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public Bucket createBucket(String bucketName, com.amazonaws.services.s3.model.Region region) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public Bucket createBucket(String bucketName, String region) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public AccessControlList getObjectAcl(String bucketName, String key, String versionId) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setObjectAcl(String bucketName, String key, AccessControlList acl) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setObjectAcl(String bucketName, String key, CannedAccessControlList acl) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setObjectAcl(String bucketName, String key, String versionId, AccessControlList acl) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setObjectAcl(String bucketName, String key, String versionId, CannedAccessControlList acl) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketAcl(SetBucketAclRequest setBucketAclRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public AccessControlList getBucketAcl(GetBucketAclRequest getBucketAclRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketAcl(String bucketName, AccessControlList acl) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketAcl(String bucketName, CannedAccessControlList acl) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public ObjectMetadata getObjectMetadata(GetObjectMetadataRequest getObjectMetadataRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public S3Object getObject(GetObjectRequest getObjectRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public ObjectMetadata getObject(GetObjectRequest getObjectRequest, File destinationFile) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucket(DeleteBucketRequest deleteBucketRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public PutObjectResult putObject(PutObjectRequest putObjectRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public CopyObjectResult copyObject(CopyObjectRequest copyObjectRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public CopyPartResult copyPart(CopyPartRequest copyPartRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteObject(DeleteObjectRequest deleteObjectRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public DeleteObjectsResult deleteObjects(DeleteObjectsRequest deleteObjectsRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteVersion(String bucketName, String key, String versionId) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteVersion(DeleteVersionRequest deleteVersionRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public BucketLoggingConfiguration getBucketLoggingConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketLoggingConfiguration(SetBucketLoggingConfigurationRequest setBucketLoggingConfigurationRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public BucketVersioningConfiguration getBucketVersioningConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketVersioningConfiguration(SetBucketVersioningConfigurationRequest setBucketVersioningConfigurationRequest) throws AmazonClientException, - AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public BucketLifecycleConfiguration getBucketLifecycleConfiguration(String bucketName) { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketLifecycleConfiguration(String bucketName, BucketLifecycleConfiguration bucketLifecycleConfiguration) { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketLifecycleConfiguration(SetBucketLifecycleConfigurationRequest setBucketLifecycleConfigurationRequest) { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketLifecycleConfiguration(String bucketName) { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketLifecycleConfiguration(DeleteBucketLifecycleConfigurationRequest deleteBucketLifecycleConfigurationRequest) { - throw new UnsupportedOperationException(); - } - - @Override - public BucketCrossOriginConfiguration getBucketCrossOriginConfiguration(String bucketName) { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketCrossOriginConfiguration(String bucketName, BucketCrossOriginConfiguration bucketCrossOriginConfiguration) { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketCrossOriginConfiguration(SetBucketCrossOriginConfigurationRequest setBucketCrossOriginConfigurationRequest) { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketCrossOriginConfiguration(String bucketName) { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketCrossOriginConfiguration(DeleteBucketCrossOriginConfigurationRequest deleteBucketCrossOriginConfigurationRequest) { - throw new UnsupportedOperationException(); - } - - @Override - public BucketTaggingConfiguration getBucketTaggingConfiguration(String bucketName) { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketTaggingConfiguration(String bucketName, BucketTaggingConfiguration bucketTaggingConfiguration) { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketTaggingConfiguration(SetBucketTaggingConfigurationRequest setBucketTaggingConfigurationRequest) { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketTaggingConfiguration(String bucketName) { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketTaggingConfiguration(DeleteBucketTaggingConfigurationRequest deleteBucketTaggingConfigurationRequest) { - throw new UnsupportedOperationException(); - } - - @Override - public BucketNotificationConfiguration getBucketNotificationConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketNotificationConfiguration(SetBucketNotificationConfigurationRequest setBucketNotificationConfigurationRequest) throws AmazonClientException, - AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketNotificationConfiguration(String bucketName, BucketNotificationConfiguration bucketNotificationConfiguration) throws AmazonClientException, - AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public BucketWebsiteConfiguration getBucketWebsiteConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public BucketWebsiteConfiguration getBucketWebsiteConfiguration(GetBucketWebsiteConfigurationRequest getBucketWebsiteConfigurationRequest) throws AmazonClientException, - AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketWebsiteConfiguration(String bucketName, BucketWebsiteConfiguration configuration) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketWebsiteConfiguration(SetBucketWebsiteConfigurationRequest setBucketWebsiteConfigurationRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketWebsiteConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketWebsiteConfiguration(DeleteBucketWebsiteConfigurationRequest deleteBucketWebsiteConfigurationRequest) throws AmazonClientException, - AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public BucketPolicy getBucketPolicy(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public BucketPolicy getBucketPolicy(GetBucketPolicyRequest getBucketPolicyRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketPolicy(String bucketName, String policyText) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void setBucketPolicy(SetBucketPolicyRequest setBucketPolicyRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketPolicy(String bucketName) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void deleteBucketPolicy(DeleteBucketPolicyRequest deleteBucketPolicyRequest) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public URL generatePresignedUrl(String bucketName, String key, Date expiration) throws AmazonClientException { - throw new UnsupportedOperationException(); - } - - @Override - public URL generatePresignedUrl(String bucketName, String key, Date expiration, HttpMethod method) throws AmazonClientException { - throw new UnsupportedOperationException(); - } - - @Override - public URL generatePresignedUrl(GeneratePresignedUrlRequest generatePresignedUrlRequest) throws AmazonClientException { - throw new UnsupportedOperationException(); - } - - @Override - public InitiateMultipartUploadResult initiateMultipartUpload(InitiateMultipartUploadRequest request) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public UploadPartResult uploadPart(UploadPartRequest request) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public PartListing listParts(ListPartsRequest request) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void abortMultipartUpload(AbortMultipartUploadRequest request) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest request) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public MultipartUploadListing listMultipartUploads(ListMultipartUploadsRequest request) throws AmazonClientException, AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public S3ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { - throw new UnsupportedOperationException(); - } - - @Override - public void restoreObject(RestoreObjectRequest request) throws AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void restoreObject(String bucketName, String key, int expirationInDays) throws AmazonServiceException { - throw new UnsupportedOperationException(); - } - - @Override - public void enableRequesterPays(String bucketName) throws AmazonServiceException, AmazonClientException { - throw new UnsupportedOperationException(); - } - - @Override - public void disableRequesterPays(String bucketName) throws AmazonServiceException, AmazonClientException { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequesterPaysEnabled(String bucketName) throws AmazonServiceException, AmazonClientException { - return false; - } + /** + * max elements amazon aws + */ + private static final int LIMIT_AWS_MAX_ELEMENTS = 1000; + + // default owner + private Owner defaultOwner = new Owner() { + private static final long serialVersionUID = 5510838843790352879L; + + { + setDisplayName("Mock"); + setId("1"); + } + }; + + private Path base; + private Map bucketOwners = new HashMap<>(); + + public AmazonS3ClientMock(Path base) { + this.base = base; + } + + /** + * list all objects without and return ObjectListing with all elements + * and with truncated to false + */ + @Override + public ObjectListing listObjects(ListObjectsRequest listObjectsRequest) throws AmazonClientException { + String bucketName = listObjectsRequest.getBucketName(); + String prefix = listObjectsRequest.getPrefix(); + String marker = listObjectsRequest.getMarker(); + String delimiter = listObjectsRequest.getDelimiter(); + + ObjectListing objectListing = new ObjectListing(); + objectListing.setBucketName(bucketName); + objectListing.setPrefix(prefix); + objectListing.setMarker(marker); + objectListing.setDelimiter(delimiter); + + final Path bucket = find(bucketName); + final TreeMap elems = new TreeMap<>(); + try { + for (Path elem : Files.newDirectoryStream(bucket)) { + S3Element element = parse(elem, bucket); + if (!elems.containsKey(element.getS3Object().getKey())) + elems.put(element.getS3Object().getKey(), element); + } + } catch (IOException e) { + throw new AmazonClientException(e); + } + Iterator iterator = elems.values().iterator(); + int i = 0; + boolean waitForMarker = !StringUtils.isNullOrEmpty(marker); + while (iterator.hasNext()) { + S3Element elem = iterator.next(); + if (elem.getS3Object().getKey().equals("/")) + continue; + String key = elem.getS3Object().getKey(); + if (waitForMarker) { + waitForMarker = !key.startsWith(marker); + if (waitForMarker) + continue; + } + + if (prefix != null && key.startsWith(prefix)) { + int beginIndex = key.indexOf(prefix) + prefix.length(); + String rest = key.substring(beginIndex); + if (delimiter != null && delimiter.length() > 0 && rest.contains(delimiter)) { + String substring = key.substring(0, beginIndex + rest.indexOf(delimiter)); + if (!objectListing.getCommonPrefixes().contains(substring)) + objectListing.getCommonPrefixes().add(substring); + continue; + } + S3ObjectSummary s3ObjectSummary = parseToS3ObjectSummary(elem); + objectListing.getObjectSummaries().add(s3ObjectSummary); + + if (i + 1 == LIMIT_AWS_MAX_ELEMENTS && iterator.hasNext()) { + objectListing.setTruncated(true); + objectListing.setNextMarker(iterator.next().getS3Object().getKey()); + return objectListing; + } + objectListing.setTruncated(false); + + i++; + } + + } + Collections.sort(objectListing.getObjectSummaries(), new Comparator() { + @Override + public int compare(S3ObjectSummary o1, S3ObjectSummary o2) { + return o1.getKey().compareTo(o2.getKey()); + } + }); + return objectListing; + } + + @Override + public ObjectListing listNextBatchOfObjects(ObjectListing previousObjectListing) { + ObjectListing objectListing = new ObjectListing(); + objectListing.setBucketName(previousObjectListing.getBucketName()); + objectListing.setPrefix(previousObjectListing.getPrefix()); + objectListing.setMarker(previousObjectListing.getMarker()); + objectListing.setDelimiter(previousObjectListing.getDelimiter()); + + if (!previousObjectListing.isTruncated() || previousObjectListing.getNextMarker() == null) { + return objectListing; + } + + Path bucket = find(previousObjectListing.getBucketName()); + List elems = new ArrayList<>(); + try { + for (Path elem : Files.newDirectoryStream(bucket)) { + elems.add(parse(elem, bucket)); + } + } catch (IOException e) { + throw new AmazonClientException(e); + } + Collections.sort(elems, new Comparator() { + @Override + public int compare(S3Element o1, S3Element o2) { + return o1.getS3Object().getKey().compareTo(o2.getS3Object().getKey()); + } + }); + Iterator iterator = elems.iterator(); + + int i = 0; + boolean continueElement = false; + + while (iterator.hasNext()) { + + S3Element elem = iterator.next(); + + if (!continueElement && elem.getS3Object().getKey().equals(previousObjectListing.getNextMarker())) { + continueElement = true; + } + + if (continueElement) { + // TODO. add delimiter and marker support + if (previousObjectListing.getPrefix() != null && elem.getS3Object().getKey().startsWith(previousObjectListing.getPrefix())) { + + S3ObjectSummary s3ObjectSummary = parseToS3ObjectSummary(elem); + objectListing.getObjectSummaries().add(s3ObjectSummary); + // max 1000 elements at same time. + if (i + 1 == LIMIT_AWS_MAX_ELEMENTS && iterator.hasNext()) { + objectListing.setTruncated(true); + objectListing.setNextMarker(iterator.next().getS3Object().getKey()); + return objectListing; + } + objectListing.setTruncated(false); + i++; + } + } + } + + return objectListing; + } + + /** + * create a new S3ObjectSummary using the S3Element + * @param elem S3Element to parse + * @return S3ObjectSummary + */ + private S3ObjectSummary parseToS3ObjectSummary(S3Element elem) { + S3Object s3Object = elem.getS3Object(); + ObjectMetadata objectMetadata = s3Object.getObjectMetadata(); + S3ObjectSummary s3ObjectSummary = new S3ObjectSummary(); + s3ObjectSummary.setBucketName(s3Object.getBucketName()); + s3ObjectSummary.setKey(s3Object.getKey()); + s3ObjectSummary.setLastModified(objectMetadata.getLastModified()); + s3ObjectSummary.setOwner(getOwner(s3Object.getBucketName())); + s3ObjectSummary.setETag(objectMetadata.getETag()); + s3ObjectSummary.setSize(objectMetadata.getContentLength()); + return s3ObjectSummary; + } + + private Owner getOwner(String bucketName) { + if (!bucketOwners.containsKey(bucketName)) + return defaultOwner; + return bucketOwners.get(bucketName); + } + + @Override + public Owner getS3AccountOwner() throws AmazonClientException { + return defaultOwner; + } + + public void setS3AccountOwner(Owner owner) { + this.defaultOwner = owner; + } + + @Override + public List listBuckets() throws AmazonClientException { + List result = new ArrayList<>(); + try { + for (Path path : Files.newDirectoryStream(base)) { + String bucketName = path.getFileName().toString(); + Bucket bucket = new Bucket(bucketName); + bucket.setOwner(getOwner(bucketName)); + bucket.setCreationDate(new Date(Files.readAttributes(path, BasicFileAttributes.class).creationTime().toMillis())); + result.add(bucket); + } + } catch (IOException e) { + throw new AmazonClientException(e); + } + return result; + } + + @Override + public Bucket createBucket(CreateBucketRequest createBucketRequest) throws AmazonClientException, AmazonServiceException { + return createBucket(createBucketRequest.getBucketName()); + } + + @Override + public Bucket createBucket(String bucketName) throws AmazonClientException, AmazonServiceException { + try { + String name = bucketName.replaceAll("//", ""); + Path path = Files.createDirectories(base.resolve(name)); + Bucket bucket = new Bucket(name); + bucket.setOwner(getOwner(name)); + bucket.setCreationDate(new Date(Files.readAttributes(path, BasicFileAttributes.class).creationTime().toMillis())); + return bucket; + } catch (IOException e) { + throw new AmazonClientException(e); + } + } + + @Override + public AccessControlList getObjectAcl(String bucketName, String key) throws AmazonClientException { + Path elem = find(bucketName, key); + if (elem != null) { + try { + return parse(elem, find(bucketName)).getPermission(); + } catch (IOException e) { + throw new AmazonServiceException("Problem getting mock ACL: ", e); + } + } + throw new AmazonServiceException("key not found, " + key); + } + + @Override + public AccessControlList getBucketAcl(String bucketName) throws AmazonClientException { + Path bucket = find(bucketName); + if (bucket == null) { + throw new AmazonServiceException("bucket not found, " + bucketName); + } + return createAllPermission(bucketName); + } + + @Override + public S3Object getObject(String bucketName, String key) throws AmazonClientException { + Path result = find(bucketName, key); + if (result == null || !Files.exists(result)) { + result = find(bucketName, key + "/"); + } + if (result == null || !Files.exists(result)) { + AmazonS3Exception amazonS3Exception = new AmazonS3Exception("not found with key: " + key); + amazonS3Exception.setStatusCode(404); + throw amazonS3Exception; + } + try { + return parse(result, find(bucketName)).getS3Object(); + } catch (IOException e) { + throw new AmazonServiceException("Problem getting Mock Object: ", e); + } + } + + @Override + public PutObjectResult putObject(String bucketName, String key, File file) throws AmazonClientException { + try { + ByteArrayInputStream stream = new ByteArrayInputStream(Files.readAllBytes(file.toPath())); + S3Element elem = parse(stream, bucketName, key); + + persist(bucketName, elem); + + PutObjectResult putObjectResult = new PutObjectResult(); + putObjectResult.setETag("3a5c8b1ad448bca04584ecb55b836264"); + return putObjectResult; + } catch (IOException e) { + throw new AmazonServiceException("", e); + } + + } + + @Override + public PutObjectResult putObject(String bucket, String keyName, InputStream inputStream, ObjectMetadata metadata) { + S3Element elem = parse(inputStream, bucket, keyName); + + persist(bucket, elem); + + PutObjectResult putObjectResult = new PutObjectResult(); + putObjectResult.setETag("3a5c8b1ad448bca04584ecb55b836264"); + return putObjectResult; + + } + + /** + * store in the memory map + * @param bucketName bucket where persist + * @param elem + */ + private void persist(String bucketName, S3Element elem) { + Path bucket = find(bucketName); + String key = elem.getS3Object().getKey().replaceAll("/", "%2F"); + Path resolve = bucket.resolve(key); + if (Files.exists(resolve)) + try { + Files.delete(resolve); + } catch (IOException e1) { + // ignore + } + + try { + Files.createFile(resolve); + S3ObjectInputStream objectContent = elem.getS3Object().getObjectContent(); + if (objectContent != null) { + byte[] byteArray = IOUtils.toByteArray(objectContent); + Files.write(resolve, byteArray); + } + } catch (IOException e) { + throw new AmazonServiceException("Problem creating mock element: ", e); + } + } + + @Override + public CopyObjectResult copyObject(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey) throws AmazonClientException { + Path src = find(sourceBucketName, sourceKey); + if (src != null && Files.exists(src)) { + Path bucket = find(destinationBucketName); + Path dest = bucket.resolve(destinationKey.replaceAll("/", "%2F")); + try { + Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new AmazonServiceException("Problem copying mock objects: ", e); + } + + return new CopyObjectResult(); + } + + throw new AmazonServiceException("object source not found"); + } + + @Override + public void deleteObject(String bucketName, String key) throws AmazonClientException { + Path bucket = find(bucketName); + Path resolve = bucket.resolve(key); + if (Files.exists(resolve)) + try { + Files.delete(resolve); + } catch (IOException e) { + throw new AmazonServiceException("Problem deleting mock object: ", e); + } + else { + resolve = bucket.resolve(key.replaceAll("/", "%2F")); + if (Files.exists(resolve)) + try { + Files.delete(resolve); + } catch (IOException e) { + throw new AmazonServiceException("Problem deleting mock object: ", e); + } + } + } + + private S3Element parse(InputStream stream, String bucketName, String key) { + S3Object object = new S3Object(); + object.setBucketName(bucketName); + object.setKey(key); + byte[] content; + try { + content = IOUtils.toByteArray(stream); + } catch (IOException e) { + throw new IllegalStateException("the stream is closed", e); + } finally { + try { + object.close(); + } catch (IOException e) { + // ignore + } + } + + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setLastModified(new Date()); + metadata.setContentLength(content.length); + + object.setObjectContent(new ByteArrayInputStream(content)); + object.setObjectMetadata(metadata); + // TODO: create converter between path permission and s3 permission + AccessControlList permission = createAllPermission(bucketName); + return new S3Element(object, permission, false); + } + + private S3Element parse(Path elem, Path bucket) throws IOException { + S3Object object = new S3Object(); + + String bucketName = bucket.getFileName().toString(); + object.setBucketName(bucketName); + + String key = bucket.relativize(elem).toString().replaceAll("%2F", "/"); + boolean dir = key.endsWith("/") || key.isEmpty(); + object.setKey(key); + + ObjectMetadata metadata = new ObjectMetadata(); + BasicFileAttributes attr = Files.readAttributes(elem, BasicFileAttributes.class); + metadata.setLastModified(new Date(attr.lastAccessTime().toMillis())); + if (dir) { + metadata.setContentLength(0); + object.setObjectContent(null); + } else { + metadata.setContentLength(attr.size()); + object.setObjectContent(new ByteArrayInputStream(Files.readAllBytes(elem))); + } + + object.setObjectMetadata(metadata); + // TODO: create converter between path permission and s3 permission + AccessControlList permission = createAllPermission(bucketName); + + return new S3Element(object, permission, dir); + } + + private AccessControlList createAllPermission(String bucketName) { + AccessControlList res = new AccessControlList(); + final Owner owner = getOwner(bucketName); + res.setOwner(owner); + Grantee grant = new Grantee() { + @Override + public void setIdentifier(String id) { + // + } + + @Override + public String getTypeIdentifier() { + return owner.getId(); + } + + @Override + public String getIdentifier() { + return owner.getId(); + } + }; + + res.grantPermission(grant, Permission.FullControl); + res.grantPermission(grant, Permission.Read); + res.grantPermission(grant, Permission.Write); + return res; + } + + public AccessControlList createReadOnly(String bucketName) { + return createReadOnly(getOwner(bucketName)); + } + + public AccessControlList createReadOnly(final Owner owner) { + AccessControlList res = new AccessControlList(); + res.setOwner(owner); + Grantee grant = new Grantee() { + @Override + public void setIdentifier(String id) { + // + } + + @Override + public String getTypeIdentifier() { + return owner.getId(); + } + + @Override + public String getIdentifier() { + return owner.getId(); + } + }; + res.grantPermission(grant, Permission.Read); + return res; + } + + private Path find(String bucketName, final String key) { + final Path bucket = find(bucketName); + if (bucket == null || !Files.exists(bucket)) { + return null; + } + try { + final String fileKey = key.replaceAll("/", "%2F"); + final List matches = new ArrayList(); + Files.walkFileTree(bucket, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + String relativize = bucket.relativize(dir).toString(); + if (relativize.equals(fileKey)) { + matches.add(dir); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String relativize = bucket.relativize(file).toString(); + if (relativize.equals(fileKey)) { + matches.add(file); + } + return FileVisitResult.CONTINUE; + } + }); + if (!matches.isEmpty()) + return matches.iterator().next(); + } catch (IOException e) { + throw new AmazonServiceException("Problem getting mock S3Element: ", e); + } + + return null; + } + + private Path find(String bucketName) { + return base.resolve(bucketName); + } + + public static class S3Element { + + private S3Object s3Object; + private boolean directory; + private AccessControlList permission; + + public S3Element(S3Object s3Object, AccessControlList permission, boolean directory) { + this.s3Object = s3Object; + this.directory = directory; + this.permission = permission; + } + + public S3Object getS3Object() { + return s3Object; + } + + public void setS3Object(S3Object s3Object) { + this.s3Object = s3Object; + } + + public AccessControlList getPermission() { + return permission; + } + + public boolean isDirectory() { + return directory; + } + + public void setDirectory(boolean directory) { + this.directory = directory; + } + + public void setPermission(AccessControlList permission) { + this.permission = permission; + } + + @Override + public boolean equals(Object object) { + + if (object == null) { + return false; + } + + if (object instanceof S3Element) { + S3Element elem = (S3Element) object; + // only is the same if bucketname and key are not null and are the same + if (elem.getS3Object() != null && this.getS3Object() != null && elem.getS3Object().getBucketName() != null + && elem.getS3Object().getBucketName().equals(this.getS3Object().getBucketName()) && elem.getS3Object().getKey() != null + && elem.getS3Object().getKey().equals(this.getS3Object().getKey())) { + return true; + } + + return false; + } + return false; + } + + @Override + public int hashCode() { + int result = s3Object != null && s3Object.getBucketName() != null ? s3Object.getBucketName().hashCode() : 0; + result = 31 * result + (s3Object != null && s3Object.getKey() != null ? s3Object.getKey().hashCode() : 0); + return result; + } + } + + @Override + public ObjectMetadata getObjectMetadata(String bucketName, String key) { + S3Object object = getObject(bucketName, key); + if (object.getKey().equals(key)) + return object.getObjectMetadata(); + AmazonS3Exception exception = new AmazonS3Exception("Resource not available: " + bucketName + "/" + key); + exception.setStatusCode(404); + throw exception; + } + + @Override + public boolean doesBucketExist(String bucketName) throws AmazonClientException, AmazonServiceException { + return Files.exists(base.resolve(bucketName)); + } + + public MockBucket bucket(String bucketName) throws IOException { + return new MockBucket(this, Files.createDirectories(base.resolve(bucketName))); + } + + public Path bucket(String bucketName, Owner owner) throws IOException { + bucketOwners.put(bucketName, owner); + return Files.createDirectories(base.resolve(bucketName)); + } + + @Override + public void deleteBucket(String bucketName) throws AmazonClientException, AmazonServiceException { + try { + Path bucket = base.resolve(bucketName); + Files.walkFileTree(bucket, new SimpleFileVisitor() { + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + throw new AmazonClientException(e); + } + } + + public void addFile(Path bucket, String fileName) throws IOException { + if (fileName.endsWith("/")) + fileName.substring(0, fileName.length() - 1); + Files.createFile(bucket.resolve(fileName.replaceAll("/", "%2F"))); + } + + public void addFile(Path bucket, String fileName, byte[] content) throws IOException { + if (fileName.endsWith("/")) + fileName.substring(0, fileName.length() - 1); + Path file = Files.createFile(bucket.resolve(fileName.replaceAll("/", "%2F"))); + OutputStream outputStream = Files.newOutputStream(file); + outputStream.write(content); + outputStream.close(); + } + + public void addDirectory(Path bucket, String directoryName) throws IOException { + if (!directoryName.endsWith("/")) + directoryName += "/"; + Files.createFile(bucket.resolve(directoryName.replaceAll("/", "%2F"))); + } + + public void clear() { + try { + Files.walkFileTree(base, new SimpleFileVisitor() { + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (dir != base) + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void setEndpoint(String endpoint) { + throw new UnsupportedOperationException(); + } + + @Override + public void setRegion(Region region) throws IllegalArgumentException { + throw new UnsupportedOperationException(); + } + + @Override + public void setS3ClientOptions(S3ClientOptions clientOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public void changeObjectStorageClass(String bucketName, String key, StorageClass newStorageClass) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setObjectRedirectLocation(String bucketName, String key, String newRedirectLocation) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public ObjectListing listObjects(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public ObjectListing listObjects(String bucketName, String prefix) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public VersionListing listVersions(String bucketName, String prefix) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public VersionListing listNextBatchOfVersions(VersionListing previousVersionListing) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public VersionListing listVersions(String bucketName, String prefix, String keyMarker, String versionIdMarker, String delimiter, Integer maxResults) + throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public VersionListing listVersions(ListVersionsRequest listVersionsRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public List listBuckets(ListBucketsRequest listBucketsRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public String getBucketLocation(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public String getBucketLocation(GetBucketLocationRequest getBucketLocationRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public Bucket createBucket(String bucketName, com.amazonaws.services.s3.model.Region region) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public Bucket createBucket(String bucketName, String region) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public AccessControlList getObjectAcl(String bucketName, String key, String versionId) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setObjectAcl(String bucketName, String key, AccessControlList acl) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setObjectAcl(String bucketName, String key, CannedAccessControlList acl) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setObjectAcl(String bucketName, String key, String versionId, AccessControlList acl) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setObjectAcl(String bucketName, String key, String versionId, CannedAccessControlList acl) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketAcl(SetBucketAclRequest setBucketAclRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public AccessControlList getBucketAcl(GetBucketAclRequest getBucketAclRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketAcl(String bucketName, AccessControlList acl) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketAcl(String bucketName, CannedAccessControlList acl) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public ObjectMetadata getObjectMetadata(GetObjectMetadataRequest getObjectMetadataRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public S3Object getObject(GetObjectRequest getObjectRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public ObjectMetadata getObject(GetObjectRequest getObjectRequest, File destinationFile) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucket(DeleteBucketRequest deleteBucketRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public PutObjectResult putObject(PutObjectRequest putObjectRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public CopyObjectResult copyObject(CopyObjectRequest copyObjectRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public CopyPartResult copyPart(CopyPartRequest copyPartRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteObject(DeleteObjectRequest deleteObjectRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public DeleteObjectsResult deleteObjects(DeleteObjectsRequest deleteObjectsRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteVersion(String bucketName, String key, String versionId) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteVersion(DeleteVersionRequest deleteVersionRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public BucketLoggingConfiguration getBucketLoggingConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketLoggingConfiguration(SetBucketLoggingConfigurationRequest setBucketLoggingConfigurationRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public BucketVersioningConfiguration getBucketVersioningConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketVersioningConfiguration(SetBucketVersioningConfigurationRequest setBucketVersioningConfigurationRequest) throws AmazonClientException, + AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public BucketLifecycleConfiguration getBucketLifecycleConfiguration(String bucketName) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketLifecycleConfiguration(String bucketName, BucketLifecycleConfiguration bucketLifecycleConfiguration) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketLifecycleConfiguration(SetBucketLifecycleConfigurationRequest setBucketLifecycleConfigurationRequest) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketLifecycleConfiguration(String bucketName) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketLifecycleConfiguration(DeleteBucketLifecycleConfigurationRequest deleteBucketLifecycleConfigurationRequest) { + throw new UnsupportedOperationException(); + } + + @Override + public BucketCrossOriginConfiguration getBucketCrossOriginConfiguration(String bucketName) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketCrossOriginConfiguration(String bucketName, BucketCrossOriginConfiguration bucketCrossOriginConfiguration) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketCrossOriginConfiguration(SetBucketCrossOriginConfigurationRequest setBucketCrossOriginConfigurationRequest) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketCrossOriginConfiguration(String bucketName) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketCrossOriginConfiguration(DeleteBucketCrossOriginConfigurationRequest deleteBucketCrossOriginConfigurationRequest) { + throw new UnsupportedOperationException(); + } + + @Override + public BucketTaggingConfiguration getBucketTaggingConfiguration(String bucketName) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketTaggingConfiguration(String bucketName, BucketTaggingConfiguration bucketTaggingConfiguration) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketTaggingConfiguration(SetBucketTaggingConfigurationRequest setBucketTaggingConfigurationRequest) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketTaggingConfiguration(String bucketName) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketTaggingConfiguration(DeleteBucketTaggingConfigurationRequest deleteBucketTaggingConfigurationRequest) { + throw new UnsupportedOperationException(); + } + + @Override + public BucketNotificationConfiguration getBucketNotificationConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketNotificationConfiguration(SetBucketNotificationConfigurationRequest setBucketNotificationConfigurationRequest) throws AmazonClientException, + AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketNotificationConfiguration(String bucketName, BucketNotificationConfiguration bucketNotificationConfiguration) throws AmazonClientException, + AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public BucketWebsiteConfiguration getBucketWebsiteConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public BucketWebsiteConfiguration getBucketWebsiteConfiguration(GetBucketWebsiteConfigurationRequest getBucketWebsiteConfigurationRequest) throws AmazonClientException, + AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketWebsiteConfiguration(String bucketName, BucketWebsiteConfiguration configuration) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketWebsiteConfiguration(SetBucketWebsiteConfigurationRequest setBucketWebsiteConfigurationRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketWebsiteConfiguration(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketWebsiteConfiguration(DeleteBucketWebsiteConfigurationRequest deleteBucketWebsiteConfigurationRequest) throws AmazonClientException, + AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public BucketPolicy getBucketPolicy(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public BucketPolicy getBucketPolicy(GetBucketPolicyRequest getBucketPolicyRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketPolicy(String bucketName, String policyText) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void setBucketPolicy(SetBucketPolicyRequest setBucketPolicyRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketPolicy(String bucketName) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteBucketPolicy(DeleteBucketPolicyRequest deleteBucketPolicyRequest) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public URL generatePresignedUrl(String bucketName, String key, Date expiration) throws AmazonClientException { + throw new UnsupportedOperationException(); + } + + @Override + public URL generatePresignedUrl(String bucketName, String key, Date expiration, HttpMethod method) throws AmazonClientException { + throw new UnsupportedOperationException(); + } + + @Override + public URL generatePresignedUrl(GeneratePresignedUrlRequest generatePresignedUrlRequest) throws AmazonClientException { + throw new UnsupportedOperationException(); + } + + @Override + public InitiateMultipartUploadResult initiateMultipartUpload(InitiateMultipartUploadRequest request) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public UploadPartResult uploadPart(UploadPartRequest request) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public PartListing listParts(ListPartsRequest request) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void abortMultipartUpload(AbortMultipartUploadRequest request) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest request) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public MultipartUploadListing listMultipartUploads(ListMultipartUploadsRequest request) throws AmazonClientException, AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public S3ResponseMetadata getCachedResponseMetadata(AmazonWebServiceRequest request) { + throw new UnsupportedOperationException(); + } + + @Override + public void restoreObject(RestoreObjectRequest request) throws AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void restoreObject(String bucketName, String key, int expirationInDays) throws AmazonServiceException { + throw new UnsupportedOperationException(); + } + + @Override + public void enableRequesterPays(String bucketName) throws AmazonServiceException, AmazonClientException { + throw new UnsupportedOperationException(); + } + + @Override + public void disableRequesterPays(String bucketName) throws AmazonServiceException, AmazonClientException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isRequesterPaysEnabled(String bucketName) throws AmazonServiceException, AmazonClientException { + return false; + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/AmazonS3MockFactory.java b/src/test/java/com/upplication/s3fs/util/AmazonS3MockFactory.java index 5b04967..fcc7d25 100644 --- a/src/test/java/com/upplication/s3fs/util/AmazonS3MockFactory.java +++ b/src/test/java/com/upplication/s3fs/util/AmazonS3MockFactory.java @@ -17,32 +17,32 @@ public class AmazonS3MockFactory extends AmazonS3Factory { - private static FileSystem fsMem; - private static AmazonS3ClientMock amazonS3Client; - - @Override - public AmazonS3 getAmazonS3(URI uri, Properties props) { - return getAmazonClientMock(); - } - - @Override - protected AmazonS3 createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { - return getAmazonClientMock(); - } - - public static AmazonS3ClientMock getAmazonClientMock() { - if (amazonS3Client == null) - amazonS3Client = spy(new AmazonS3ClientMock(getFsMem().getPath("/"))); - return amazonS3Client; - } - - private static FileSystem getFsMem() { - if (fsMem == null) - try { - fsMem = MemoryFileSystemBuilder.newEmpty().build(UUID.randomUUID().toString()); - } catch (IOException e) { - throw new RuntimeException(e); - } - return fsMem; - } + private static FileSystem fsMem; + private static AmazonS3ClientMock amazonS3Client; + + @Override + public AmazonS3 getAmazonS3(URI uri, Properties props) { + return getAmazonClientMock(); + } + + @Override + protected AmazonS3 createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { + return getAmazonClientMock(); + } + + public static AmazonS3ClientMock getAmazonClientMock() { + if (amazonS3Client == null) + amazonS3Client = spy(new AmazonS3ClientMock(getFsMem().getPath("/"))); + return amazonS3Client; + } + + private static FileSystem getFsMem() { + if (fsMem == null) + try { + fsMem = MemoryFileSystemBuilder.newEmpty().build(UUID.randomUUID().toString()); + } catch (IOException e) { + throw new RuntimeException(e); + } + return fsMem; + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/BrokenAmazonS3Factory.java b/src/test/java/com/upplication/s3fs/util/BrokenAmazonS3Factory.java index 32040f7..4b7e2a3 100644 --- a/src/test/java/com/upplication/s3fs/util/BrokenAmazonS3Factory.java +++ b/src/test/java/com/upplication/s3fs/util/BrokenAmazonS3Factory.java @@ -7,15 +7,15 @@ import com.upplication.s3fs.AmazonS3Factory; public class BrokenAmazonS3Factory extends AmazonS3Factory { - /** - * @param name to make the constructor non default - */ - public BrokenAmazonS3Factory(String name) { - // only non default constructor - } + /** + * @param name to make the constructor non default + */ + public BrokenAmazonS3Factory(String name) { + // only non default constructor + } - @Override - protected AmazonS3 createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { - return null; - } + @Override + protected AmazonS3 createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { + return null; + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/BrokenRequestMetricCollector.java b/src/test/java/com/upplication/s3fs/util/BrokenRequestMetricCollector.java index de29548..9894072 100644 --- a/src/test/java/com/upplication/s3fs/util/BrokenRequestMetricCollector.java +++ b/src/test/java/com/upplication/s3fs/util/BrokenRequestMetricCollector.java @@ -1,10 +1,10 @@ package com.upplication.s3fs.util; public class BrokenRequestMetricCollector extends NoOpRequestMetricCollector { - /** - * @param name to make the constructor non default - */ - public BrokenRequestMetricCollector(String name) { - // only non default constructor - } + /** + * @param name to make the constructor non default + */ + public BrokenRequestMetricCollector(String name) { + // only non default constructor + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/CopyDirVisitor.java b/src/test/java/com/upplication/s3fs/util/CopyDirVisitor.java index 1cdfcb1..0a7282b 100644 --- a/src/test/java/com/upplication/s3fs/util/CopyDirVisitor.java +++ b/src/test/java/com/upplication/s3fs/util/CopyDirVisitor.java @@ -12,59 +12,59 @@ public class CopyDirVisitor extends SimpleFileVisitor { private Path fromPath; - private Path toPath; - private StandardCopyOption copyOption; + private Path toPath; + private StandardCopyOption copyOption; - public CopyDirVisitor(Path fromPath, Path toPath, StandardCopyOption copyOption) { - this.fromPath = fromPath; - this.toPath = toPath; - this.copyOption = copyOption; - } + public CopyDirVisitor(Path fromPath, Path toPath, StandardCopyOption copyOption) { + this.fromPath = fromPath; + this.toPath = toPath; + this.copyOption = copyOption; + } - public CopyDirVisitor(Path fromPath, Path toPath) { - this(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING); - } + public CopyDirVisitor(Path fromPath, Path toPath) { + this(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING); + } - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - // permitimos resolver entre distintos providers - Path targetPath = appendPath(dir); + // permitimos resolver entre distintos providers + Path targetPath = appendPath(dir); - if (!Files.exists(targetPath)) { - if (!targetPath.getFileName().toString().endsWith("/")) { - targetPath = targetPath.getParent().resolve(targetPath.getFileName().toString() + "/"); - } - Files.createDirectory(targetPath); - } - return FileVisitResult.CONTINUE; - } + if (!Files.exists(targetPath)) { + if (!targetPath.getFileName().toString().endsWith("/")) { + targetPath = targetPath.getParent().resolve(targetPath.getFileName().toString() + "/"); + } + Files.createDirectory(targetPath); + } + return FileVisitResult.CONTINUE; + } - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Path targetPath = appendPath(file); + Path targetPath = appendPath(file); - Files.copy(file, targetPath, copyOption); - return FileVisitResult.CONTINUE; - } + Files.copy(file, targetPath, copyOption); + return FileVisitResult.CONTINUE; + } - /** - * Obtenemos el path que corresponde en el parametro: {@link #fromPath} - * relativo al parametro Path to - * - * @param to Path - * @return - */ - private Path appendPath(Path to) { - Path targetPath = toPath; - // sacamos el path relativo y lo recorremos para - // aƱadirlo al nuevo - for (Path path : fromPath.relativize(to)) { - // si utilizamos path en vez de string: lanza error por ser - // distintos paths - targetPath = targetPath.resolve(path.getFileName().toString()); - } - return targetPath; - } + /** + * Obtenemos el path que corresponde en el parametro: {@link #fromPath} + * relativo al parametro Path to + * + * @param to Path + * @return + */ + private Path appendPath(Path to) { + Path targetPath = toPath; + // sacamos el path relativo y lo recorremos para + // aƱadirlo al nuevo + for (Path path : fromPath.relativize(to)) { + // si utilizamos path en vez de string: lanza error por ser + // distintos paths + targetPath = targetPath.resolve(path.getFileName().toString()); + } + return targetPath; + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/EnvironmentBuilder.java b/src/test/java/com/upplication/s3fs/util/EnvironmentBuilder.java index bdae45b..49833df 100644 --- a/src/test/java/com/upplication/s3fs/util/EnvironmentBuilder.java +++ b/src/test/java/com/upplication/s3fs/util/EnvironmentBuilder.java @@ -16,51 +16,53 @@ */ public abstract class EnvironmentBuilder { - public static final String BUCKET_NAME_KEY = "bucket_name"; + public static final String BUCKET_NAME_KEY = "bucket_name"; - /** - * Get credentials from environment vars, and if not found from amazon-test.properties - * @return Map with the credentials - */ - public static Map getRealEnv() { - Map env = null; + /** + * Get credentials from environment vars, and if not found from amazon-test.properties + * + * @return Map with the credentials + */ + public static Map getRealEnv() { + Map env = null; - String accessKey = System.getenv(ACCESS_KEY); - String secretKey = System.getenv(SECRET_KEY); + String accessKey = System.getenv(ACCESS_KEY); + String secretKey = System.getenv(SECRET_KEY); - if (accessKey != null && secretKey != null) { - env = ImmutableMap. builder().put(ACCESS_KEY, accessKey).put(SECRET_KEY, secretKey).build(); - } else { - final Properties props = new Properties(); - try { - props.load(EnvironmentBuilder.class.getResourceAsStream("/amazon-test.properties")); - } catch (IOException e) { - throw new RuntimeException("not found amazon-test.properties in the classpath", e); - } - env = ImmutableMap. builder().put(ACCESS_KEY, props.getProperty(ACCESS_KEY)).put(SECRET_KEY, props.getProperty(SECRET_KEY)).build(); - } + if (accessKey != null && secretKey != null) { + env = ImmutableMap.builder().put(ACCESS_KEY, accessKey).put(SECRET_KEY, secretKey).build(); + } else { + final Properties props = new Properties(); + try { + props.load(EnvironmentBuilder.class.getResourceAsStream("/amazon-test.properties")); + } catch (IOException e) { + throw new RuntimeException("not found amazon-test.properties in the classpath", e); + } + env = ImmutableMap.builder().put(ACCESS_KEY, props.getProperty(ACCESS_KEY)).put(SECRET_KEY, props.getProperty(SECRET_KEY)).build(); + } - return env; - } + return env; + } - /** - * get default bucket name - * @return String without end separator - */ - public static String getBucket() { + /** + * get default bucket name + * + * @return String without end separator + */ + public static String getBucket() { - String bucketName = System.getenv(BUCKET_NAME_KEY); - if (bucketName != null) { - return bucketName; - } - final Properties props = new Properties(); - try { - props.load(FilesOperationsIT.class.getResourceAsStream("/amazon-test.properties")); - return props.getProperty(BUCKET_NAME_KEY); - } catch (IOException e) { - throw new RuntimeException("needed /amazon-test.properties in the classpath"); - } - } + String bucketName = System.getenv(BUCKET_NAME_KEY); + if (bucketName != null) { + return bucketName; + } + final Properties props = new Properties(); + try { + props.load(FilesOperationsIT.class.getResourceAsStream("/amazon-test.properties")); + return props.getProperty(BUCKET_NAME_KEY); + } catch (IOException e) { + throw new RuntimeException("needed /amazon-test.properties in the classpath"); + } + } public static URI getS3URI(URI s3GlobalUri) { Map env = getRealEnv(); diff --git a/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3Client.java b/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3Client.java index 824a189..f1fee1f 100644 --- a/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3Client.java +++ b/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3Client.java @@ -6,22 +6,22 @@ import com.amazonaws.services.s3.AmazonS3Client; public class ExposingAmazonS3Client extends AmazonS3Client { - private AWSCredentialsProvider awsCredentialsProvider; + private AWSCredentialsProvider awsCredentialsProvider; - public ExposingAmazonS3Client(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { - super(credentialsProvider, clientConfiguration, requestMetricsCollector); - this.awsCredentialsProvider = credentialsProvider; - } + public ExposingAmazonS3Client(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { + super(credentialsProvider, clientConfiguration, requestMetricsCollector); + this.awsCredentialsProvider = credentialsProvider; + } - public AWSCredentialsProvider getAWSCredentialsProvider() { - return awsCredentialsProvider; - } + public AWSCredentialsProvider getAWSCredentialsProvider() { + return awsCredentialsProvider; + } - public ClientConfiguration getClientConfiguration() { - return clientConfiguration; - } + public ClientConfiguration getClientConfiguration() { + return clientConfiguration; + } - public RequestMetricCollector getRequestMetricCollector() { - return super.requestMetricCollector(); - } + public RequestMetricCollector getRequestMetricCollector() { + return super.requestMetricCollector(); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3ClientFactory.java b/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3ClientFactory.java index ede3611..9b19255 100644 --- a/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3ClientFactory.java +++ b/src/test/java/com/upplication/s3fs/util/ExposingAmazonS3ClientFactory.java @@ -7,8 +7,8 @@ import com.upplication.s3fs.AmazonS3ClientFactory; public class ExposingAmazonS3ClientFactory extends AmazonS3ClientFactory { - @Override - protected AmazonS3Client createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { - return new ExposingAmazonS3Client(credentialsProvider, clientConfiguration, requestMetricsCollector); - } + @Override + protected AmazonS3Client createAmazonS3(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration, RequestMetricCollector requestMetricsCollector) { + return new ExposingAmazonS3Client(credentialsProvider, clientConfiguration, requestMetricsCollector); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/MockBucket.java b/src/test/java/com/upplication/s3fs/util/MockBucket.java index f95a29b..3384d39 100644 --- a/src/test/java/com/upplication/s3fs/util/MockBucket.java +++ b/src/test/java/com/upplication/s3fs/util/MockBucket.java @@ -4,32 +4,32 @@ import java.nio.file.Path; public class MockBucket { - private AmazonS3ClientMock amazonS3ClientMock; - private Path mocketPath; + private AmazonS3ClientMock amazonS3ClientMock; + private Path mocketPath; - public MockBucket(AmazonS3ClientMock amazonS3ClientMock, Path mocketPath) { - this.amazonS3ClientMock = amazonS3ClientMock; - this.mocketPath = mocketPath; - } - - public MockBucket file(String... file) throws IOException { - for (String string : file) - amazonS3ClientMock.addFile(mocketPath, string, "sample-content".getBytes()); - return this; - } - - public MockBucket file(String file, byte[] content) throws IOException { - amazonS3ClientMock.addFile(mocketPath, file, content); - return this; - } - - public MockBucket dir(String... dir) throws IOException { - for (String string : dir) - amazonS3ClientMock.addDirectory(mocketPath, string); - return this; - } + public MockBucket(AmazonS3ClientMock amazonS3ClientMock, Path mocketPath) { + this.amazonS3ClientMock = amazonS3ClientMock; + this.mocketPath = mocketPath; + } - public Path resolve(String file) { - return mocketPath.resolve(file.replaceAll("/", "%2F")); - } + public MockBucket file(String... file) throws IOException { + for (String string : file) + amazonS3ClientMock.addFile(mocketPath, string, "sample-content".getBytes()); + return this; + } + + public MockBucket file(String file, byte[] content) throws IOException { + amazonS3ClientMock.addFile(mocketPath, file, content); + return this; + } + + public MockBucket dir(String... dir) throws IOException { + for (String string : dir) + amazonS3ClientMock.addDirectory(mocketPath, string); + return this; + } + + public Path resolve(String file) { + return mocketPath.resolve(file.replaceAll("/", "%2F")); + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/NoOpRequestMetricCollector.java b/src/test/java/com/upplication/s3fs/util/NoOpRequestMetricCollector.java index 0e39c7a..4a83b21 100644 --- a/src/test/java/com/upplication/s3fs/util/NoOpRequestMetricCollector.java +++ b/src/test/java/com/upplication/s3fs/util/NoOpRequestMetricCollector.java @@ -5,12 +5,13 @@ import com.amazonaws.metrics.RequestMetricCollector; public class NoOpRequestMetricCollector extends RequestMetricCollector { - @Override - public void collectMetrics(Request request, Response response) { - // - } - @Override - public boolean isEnabled() { - return false; - } + @Override + public void collectMetrics(Request request, Response response) { + // + } + + @Override + public boolean isEnabled() { + return false; + } } \ No newline at end of file diff --git a/src/test/java/com/upplication/s3fs/util/UnsupportedFileStoreAttributeView.java b/src/test/java/com/upplication/s3fs/util/UnsupportedFileStoreAttributeView.java index 3c8d6c5..fbfa9fe 100644 --- a/src/test/java/com/upplication/s3fs/util/UnsupportedFileStoreAttributeView.java +++ b/src/test/java/com/upplication/s3fs/util/UnsupportedFileStoreAttributeView.java @@ -3,8 +3,8 @@ import java.nio.file.attribute.FileStoreAttributeView; public class UnsupportedFileStoreAttributeView implements FileStoreAttributeView { - @Override - public String name() { - return "unsupported"; - } + @Override + public String name() { + return "unsupported"; + } } \ No newline at end of file