Skip to content

Commit

Permalink
🎉 version 2.0.0
Browse files Browse the repository at this point in the history
Fix #76 and #78
  • Loading branch information
jarnaiz committed Nov 27, 2017
1 parent cc946f2 commit 0ca9a15
Show file tree
Hide file tree
Showing 40 changed files with 1,738 additions and 892 deletions.
98 changes: 67 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
### What is new
* Implemented S3FileChannel and adopted few places so that the FileSystem can be plugged in Apache Mina SFTP
* Upgraded AWS SDK to 1.11.125
* Added propagation of all passed in env's

### How to use in Apache MINA
```ruby
public FileSystemFactory createFileSystemFactory(String bucketName) throws IOException, URISyntaxException {
FileSystem fileSystem = FileSystems.newFileSystem(new URI("s3:///"), env, Thread.currentThread().getContextClassLoader());
String bucketPath = fileSystem.getPath("/" + bucketName);

return new VirtualFileSystemFactory(bucketPath);
}
```
--

An **Amazon AWS S3** FileSystem Provider **JSR-203** for Java 7 (NIO2)

Amazon Simple Storage Service provides a fully redundant data storage infrastructure for storing and retrieving any amount of data, at any time.
Expand All @@ -22,27 +6,27 @@ This project provides a first API implementation, little optimized, but "complet

[![Build Status](https://travis-ci.org/Upplication/Amazon-S3-FileSystem-NIO2.svg?branch=master)](https://travis-ci.org/Upplication/Amazon-S3-FileSystem-NIO2/builds) [![Coverage Status](https://coveralls.io/repos/Upplication/Amazon-S3-FileSystem-NIO2/badge.png?branch=master)](https://coveralls.io/r/Upplication/Amazon-S3-FileSystem-NIO2?branch=master) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.upplication/s3fs/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.upplication/s3fs)

## How to use
#### How to use

### Download from Maven Central
##### Download from Maven Central

```XML
<dependency>
<groupId>com.upplication</groupId>
<artifactId>s3fs</artifactId>
<version>1.5.4</version>
<version>2.0.0</version>
</dependency>
```


And add to your META-INF/services/java.nio.file.spi.FileSystemProvider (create if not exists yet) a new line like this: com.upplication.s3fs.S3FileSystemProvider.

### S3FileSystem and AmazonS3 settings
##### S3FileSystem and AmazonS3 settings

All settings for S3FileSystem and for the underlying AmazonS3 connector library can be set through System properties or environment variables.
Possible settings can be found in com.upplication.s3fs.AmazonS3Factory.

### Using service locator and system vars
#### Using service locator and system vars

Check that s3fs_access_key and s3fs_secret_key system vars are present with the correct values to have full access to your amazon s3 bucket.

Expand All @@ -52,19 +36,19 @@ Use this code to create the fileSystem and set to a concrete endpoint.
FileSystems.newFileSystem("s3:///", new HashMap<String,Object>(), Thread.currentThread().getContextClassLoader());
```

### Using service locator and amazon.properties in the classpath
##### Using service locator and amazon.properties in the classpath

Add to your resources folder the file amazon.properties with the content:
s3fs_access_key=access key
s3fs_secret_key=secret key
s3fs_access_key=access-key
s3fs_secret_key=secret-key

Use this code to create the fileSystem and set to a concrete endpoint.

```java
FileSystems.newFileSystem("s3:///", new HashMap<String,Object>(), Thread.currentThread().getContextClassLoader());
```

### Using service locator and programatically authentication
##### Using service locator and programatically authentication

Create a map with the authentication and use the fileSystem to create the fileSystem and set to a concrete endpoint.

Expand Down Expand Up @@ -96,7 +80,7 @@ Complete settings lists:
* s3fs_user_agent
* s3fs_amazon_s3_factory

### Set endpoint to reduce data latency in your applications
##### Set endpoint to reduce data latency in your applications

```java
// Northern Virginia or Pacific Northwest
Expand All @@ -113,7 +97,59 @@ FileSystems.newFileSystem("s3://s3-eu-west-1.amazonaws.com/", env, Thread.curren

For a complete list of available regions look at: http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region

## Features:
##### How to use in Apache MINA

```java
public FileSystemFactory createFileSystemFactory(String bucketName) throws IOException, URISyntaxException {
FileSystem fileSystem = FileSystems.newFileSystem(new URI("s3:///"), env, Thread.currentThread().getContextClassLoader());
String bucketPath = fileSystem.getPath("/" + bucketName);

return new VirtualFileSystemFactory(bucketPath);
}
```

##### How to use in Spring

Add to classpath and configure:

```java
@Configuration
public class AwsConfig {

@Value("${upplication.aws.accessKey}")
private String accessKey;

@Value("${upplication.aws.secretKey}")
private String secretKey;

@Bean
public FileSystem s3FileSystem() throws IOException {
Map<String, String> env = new HashMap<>();
env.put(com.upplication.s3fs.AmazonS3Factory.ACCESS_KEY, accessKey);
env.put(com.upplication.s3fs.AmazonS3Factory.SECRET_KEY, secretKey);

return FileSystems.newFileSystem(URI.create("s3:///"), env, Thread.currentThread().getContextClassLoader());
}
}
```

Now you can inject in any spring component:

```java
@Autowired
private FileSystem s3FileSystem;

```

##### What is new 2.0.0

* Preserve URI with end slash #76
* Removed META-INF/services/java.nio.file.spi.FileTypeDetector #78
* Bucket are filestores and root directories for a bucket is the bucket itself.
* getFileName for a root Path is ```null```
* Improved S3Path Tests

#### Features:

* Copy and create folders and files
* Delete folders and files
Expand All @@ -123,16 +159,16 @@ For a complete list of available regions look at: http://docs.aws.amazon.com/gen
* List buckets for the client
* Multi endpoint fileSystem

## Roadmap:
#### Roadmap:

* Performance issue (slow querys with virtual folders, add multipart submit...)
* Disallow upload binary files with same name as folders and vice versa

## Out of Roadmap:
#### Out of Roadmap:

* Watchers

## How to contribute
#### How to contribute

Clone the github repository:

Expand All @@ -153,6 +189,6 @@ s3fs_access_key=your access key for test

Thats all, now you can run the test with the command: `mvn test` or `mvn integration-test -Pintegration-tests`

## LICENSE:
#### LICENSE:

Amazon S3 FileSystem NIO2 is released under the MIT License.
10 changes: 8 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.upplication</groupId>
<artifactId>s3fs</artifactId>
<packaging>jar</packaging>
<version>1.5.4</version>
<version>2.0.0</version>
<name>s3fs</name>
<description>S3 filesystem provider for Java 7</description>
<url>https://github.com/Upplication/Amazon-S3-FileSystem-NIO2</url>
Expand All @@ -16,6 +16,12 @@
</license>
</licenses>
<developers>

<developer>
<id>jcustovic</id>
<name>Jan Čustović</name>
<email>jan.custovic@gmail.com</email>
</developer>
<developer>
<id>heikkipora</id>
<name>Heikki Pora</name>
Expand Down Expand Up @@ -52,7 +58,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.surfire.plugin.version>2.7.1</maven.surfire.plugin.version>
<slf4j.version>1.7.5</slf4j.version>
<com.amazonaws.aws-java-sdk-s3.version>1.11.125</com.amazonaws.aws-java-sdk-s3.version>
<com.amazonaws.aws-java-sdk-s3.version>1.11.232</com.amazonaws.aws-java-sdk-s3.version>
<com.google.guava.guava.version>18.0</com.google.guava.guava.version>
<org.apache.tika.tika-core.version>1.5</org.apache.tika.tika-core.version>
<com.google.code.findbugs.jsr305.version>1.3.9</com.google.code.findbugs.jsr305.version>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/upplication/s3fs/S3FileStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private Bucket getBucket(String bucketName) {
}

public S3Path getRootDirectory() {
return new S3Path(fileSystem, this, ImmutableList.<String>of());
return new S3Path(fileSystem, "/" + this.name());
}

private AmazonS3 getClient() {
Expand Down
8 changes: 0 additions & 8 deletions src/main/java/com/upplication/s3fs/S3FileSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
import java.nio.file.PathMatcher;
import java.nio.file.WatchService;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.util.List;
import java.util.Set;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.Bucket;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

Expand Down Expand Up @@ -139,12 +137,6 @@ public String[] key2Parts(String keyParts) {
return split;
}

public String parts2Key(List<String> parts) {
if (parts.isEmpty())
return "";
return Joiner.on(PATH_SEPARATOR).join(ImmutableList.copyOf(parts));
}

@Override
public int hashCode() {
final int prime = 31;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/upplication/s3fs/S3FileSystemProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,8 @@ public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOExcept
// 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);
String directoryKey = s3Path.getKey().endsWith("/") ? s3Path.getKey() : s3Path.getKey() + "/";
s3Path.getFileSystem().getClient().putObject(bucketName, directoryKey, new ByteArrayInputStream(new byte[0]), metadata);
}

@Override
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/upplication/s3fs/S3Iterator.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public S3Iterator(S3Path path) {
}

public S3Iterator(S3Path path, boolean incremental) {
this(path.getFileStore(), path.getKey().length() == 0 ? "" : (path.getKey() + (incremental ? "" : "/")), incremental);
this(path.getFileStore(), path.getKey() + (!incremental && !path.getKey().isEmpty() && !path.getKey().endsWith("/") ? "/" : ""), incremental);
}

public S3Iterator(S3FileStore fileStore, String key, boolean incremental) {
Expand Down Expand Up @@ -89,7 +89,7 @@ private void parseObjects() {
final String objectSummaryKey = objectSummary.getKey();
String[] keyParts = fileSystem.key2Parts(objectSummaryKey);
addParentPaths(keyParts);
S3Path path = new S3Path(fileSystem, fileStore, keyParts);
S3Path path = new S3Path(fileSystem, "/" + fileStore.name(), keyParts);
if (!items.contains(path)) {
items.add(path);
}
Expand All @@ -102,7 +102,7 @@ private void addParentPaths(String[] keyParts) {
String[] subParts = Arrays.copyOf(keyParts, keyParts.length - 1);
List<S3Path> parentPaths = new ArrayList<>();
while (subParts.length > 0) {
S3Path path = new S3Path(fileSystem, fileStore, subParts);
S3Path path = new S3Path(fileSystem, "/" + fileStore.name(), subParts);
String prefix = current.getPrefix();

String parentKey = path.getKey();
Expand Down Expand Up @@ -131,7 +131,7 @@ private void addParentPaths(String[] keyParts) {
private void parseObjectListing(String key, List<S3Path> listPath, ObjectListing current) {
for (String commonPrefix : current.getCommonPrefixes()) {
if (!commonPrefix.equals("/")) {
listPath.add(new S3Path(fileSystem, fileStore, fileSystem.key2Parts(commonPrefix)));
listPath.add(new S3Path(fileSystem, "/" + fileStore.name(), fileSystem.key2Parts(commonPrefix)));
}
}
// TODO: figure our a way to efficiently preprocess commonPrefix basicFileAttributes
Expand All @@ -140,7 +140,7 @@ private void parseObjectListing(String key, List<S3Path> listPath, ObjectListing
// we only want the first level
String immediateDescendantKey = getImmediateDescendant(key, objectSummaryKey);
if (immediateDescendantKey != null) {
S3Path descendentPart = new S3Path(fileSystem, fileStore, fileSystem.key2Parts(immediateDescendantKey));
S3Path descendentPart = new S3Path(fileSystem, "/" + fileStore.name(), fileSystem.key2Parts(immediateDescendantKey));
descendentPart.setFileAttributes(s3Utils.toS3FileAttributes(objectSummary, descendentPart.getKey()));
if (!listPath.contains(descendentPart)) {
listPath.add(descendentPart);
Expand Down
Loading

0 comments on commit 0ca9a15

Please sign in to comment.