Skip to content

Commit affed4d

Browse files
jartmziccard
authored andcommitted
Cloud Storage Java 7 nio library
This is an import of previous work which was reviewed internally.
1 parent 1118c0e commit affed4d

37 files changed

Lines changed: 5050 additions & 1 deletion
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?xml version="1.0"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.google.gcloud</groupId>
5+
<artifactId>gcloud-java-nio</artifactId>
6+
<packaging>jar</packaging>
7+
<name>GCloud Java NIO</name>
8+
<description>
9+
FileSystemProvider for Java NIO to access GCS transparently.
10+
</description>
11+
<parent>
12+
<groupId>com.google.gcloud</groupId>
13+
<artifactId>gcloud-java-contrib</artifactId>
14+
<version>0.1.4-SNAPSHOT</version>
15+
</parent>
16+
<properties>
17+
<site.installationModule>nio</site.installationModule>
18+
</properties>
19+
<dependencies>
20+
<dependency>
21+
<groupId>${project.groupId}</groupId>
22+
<artifactId>gcloud-java</artifactId>
23+
<version>${project.version}</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>com.google.guava</groupId>
27+
<artifactId>guava</artifactId>
28+
<version>19.0</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.google.code.findbugs</groupId>
32+
<artifactId>jsr305</artifactId>
33+
<version>2.0.1</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>javax.inject</groupId>
37+
<artifactId>javax.inject</artifactId>
38+
<version>1</version>
39+
</dependency>
40+
<dependency>
41+
<groupId>com.google.auto.service</groupId>
42+
<artifactId>auto-service</artifactId>
43+
<version>1.0-rc2</version>
44+
<scope>provided</scope> <!-- to leave out of the all-deps jar -->
45+
</dependency>
46+
<dependency>
47+
<groupId>com.google.auto.value</groupId>
48+
<artifactId>auto-value</artifactId>
49+
<version>1.1</version>
50+
<scope>provided</scope> <!-- to leave out of the all-deps jar -->
51+
</dependency>
52+
<dependency>
53+
<groupId>com.google.appengine.tools</groupId>
54+
<artifactId>appengine-gcs-client</artifactId>
55+
<version>0.5</version>
56+
</dependency>
57+
<dependency>
58+
<groupId>junit</groupId>
59+
<artifactId>junit</artifactId>
60+
<version>4.12</version>
61+
<scope>test</scope>
62+
</dependency>
63+
<dependency>
64+
<groupId>com.google.guava</groupId>
65+
<artifactId>guava-testlib</artifactId>
66+
<version>19.0</version>
67+
<scope>test</scope>
68+
</dependency>
69+
<dependency>
70+
<groupId>com.google.truth</groupId>
71+
<artifactId>truth</artifactId>
72+
<version>0.27</version>
73+
<scope>test</scope>
74+
</dependency>
75+
<dependency>
76+
<groupId>org.mockito</groupId>
77+
<artifactId>mockito-core</artifactId>
78+
<version>1.9.5</version>
79+
</dependency>
80+
<dependency>
81+
<groupId>com.google.appengine</groupId>
82+
<artifactId>appengine-testing</artifactId>
83+
<version>1.9.30</version>
84+
<scope>test</scope>
85+
</dependency>
86+
<dependency>
87+
<groupId>com.google.appengine</groupId>
88+
<artifactId>appengine-api-stubs</artifactId>
89+
<version>1.9.30</version>
90+
<scope>test</scope>
91+
</dependency>
92+
<dependency>
93+
<groupId>com.google.appengine</groupId>
94+
<artifactId>appengine-local-endpoints</artifactId>
95+
<version>1.9.30</version>
96+
<scope>test</scope>
97+
</dependency>
98+
</dependencies>
99+
<build>
100+
<plugins>
101+
<plugin>
102+
<groupId>org.codehaus.mojo</groupId>
103+
<artifactId>exec-maven-plugin</artifactId>
104+
<configuration>
105+
<skip>false</skip>
106+
</configuration>
107+
</plugin>
108+
<plugin>
109+
<artifactId>maven-compiler-plugin</artifactId>
110+
<version>3.1</version>
111+
<configuration>
112+
<source>1.7</source>
113+
<target>1.7</target>
114+
<encoding>UTF-8</encoding>
115+
<compilerArgument>-Xlint:unchecked</compilerArgument>
116+
</configuration>
117+
</plugin>
118+
<plugin>
119+
<artifactId>maven-jar-plugin</artifactId>
120+
<version>2.6</version>
121+
<configuration>
122+
<archive>
123+
<addMavenDescriptor>true</addMavenDescriptor>
124+
<index>true</index>
125+
<manifest>
126+
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
127+
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
128+
</manifest>
129+
<manifestEntries>
130+
<artifactId>${project.artifactId}</artifactId>
131+
<groupId>${project.groupId}</groupId>
132+
<version>${project.version}</version>
133+
<buildNumber>${buildNumber}</buildNumber>
134+
</manifestEntries>
135+
</archive>
136+
</configuration>
137+
</plugin>
138+
</plugins>
139+
</build>
140+
</project>
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package com.google.gcloud.storage.contrib.nio;
2+
3+
import static com.google.common.base.Preconditions.checkArgument;
4+
5+
import com.google.auto.value.AutoValue;
6+
7+
import java.util.Map;
8+
9+
/** Configuration class for {@link CloudStorageFileSystem#forBucket} */
10+
@AutoValue
11+
public abstract class CloudStorageConfiguration {
12+
13+
/** Returns the path of the current working directory. Defaults to the root directory. */
14+
public abstract String workingDirectory();
15+
16+
/**
17+
* Returns {@code true} if we <i>shouldn't</i> throw an exception when encountering object names
18+
* containing superfluous slashes, e.g. {@code a//b}.
19+
*/
20+
public abstract boolean permitEmptyPathComponents();
21+
22+
/**
23+
* Returns {@code true} if '/' prefix on absolute object names should be removed before I/O.
24+
*
25+
* <p>If you disable this feature, please take into consideration that all paths created from a
26+
* URI will have the leading slash.
27+
*/
28+
public abstract boolean stripPrefixSlash();
29+
30+
/** Return {@code true} if paths with a trailing slash should be treated as fake directories. */
31+
public abstract boolean usePseudoDirectories();
32+
33+
/** Returns the block size (in bytes) used when talking to the GCS HTTP server. */
34+
public abstract int blockSize();
35+
36+
/**
37+
* Creates a new builder, initialized with the following settings:
38+
*
39+
* <ul>
40+
* <li>Performing I/O on paths with extra slashes, e.g. {@code a//b} will throw an error.
41+
* <li>The prefix slash on absolute paths will be removed when converting to an object name.
42+
* <li>Pseudo-directories are enabled, so any path with a trailing slash is a fake directory.
43+
* </ul>
44+
*/
45+
public static Builder builder() {
46+
return new Builder();
47+
}
48+
49+
/** Builder for {@link CloudStorageConfiguration}. */
50+
public static final class Builder {
51+
52+
private String workingDirectory = UnixPath.ROOT;
53+
private boolean permitEmptyPathComponents = false;
54+
private boolean stripPrefixSlash = true;
55+
private boolean usePseudoDirectories = true;
56+
private int blockSize = CloudStorageFileSystem.BLOCK_SIZE_DEFAULT;
57+
58+
/**
59+
* Changes the current working directory for a new filesystem. This cannot be changed once it's
60+
* been set. You'll need to simply create another filesystem object.
61+
*
62+
* @throws IllegalArgumentException if {@code path} is not absolute.
63+
*/
64+
public Builder workingDirectory(String path) {
65+
checkArgument(UnixPath.getPath(false, path).isAbsolute(), "not absolute: %s", path);
66+
workingDirectory = path;
67+
return this;
68+
}
69+
70+
/**
71+
* Configures whether or not we should throw an exception when encountering object names
72+
* containing superfluous slashes, e.g. {@code a//b}
73+
*/
74+
public Builder permitEmptyPathComponents(boolean value) {
75+
permitEmptyPathComponents = value;
76+
return this;
77+
}
78+
79+
/**
80+
* Configures if the '/' prefix on absolute object names should be removed before I/O.
81+
*
82+
* <p>If you disable this feature, please take into consideration that all paths created from a
83+
* URI will have the leading slash.
84+
*/
85+
public Builder stripPrefixSlash(boolean value) {
86+
stripPrefixSlash = value;
87+
return this;
88+
}
89+
90+
/** Configures if paths with a trailing slash should be treated as fake directories. */
91+
public Builder usePseudoDirectories(boolean value) {
92+
usePseudoDirectories = value;
93+
return this;
94+
}
95+
96+
/**
97+
* Sets the block size in bytes that should be used for each HTTP request to the API.
98+
*
99+
* <p>The default is {@value CloudStorageFileSystem#BLOCK_SIZE_DEFAULT}.
100+
*/
101+
public Builder blockSize(int value) {
102+
blockSize = value;
103+
return this;
104+
}
105+
106+
/** Creates a new instance, but does not destroy the builder. */
107+
public CloudStorageConfiguration build() {
108+
return new AutoValue_CloudStorageConfiguration(
109+
workingDirectory,
110+
permitEmptyPathComponents,
111+
stripPrefixSlash,
112+
usePseudoDirectories,
113+
blockSize);
114+
}
115+
116+
Builder() {}
117+
}
118+
119+
static final CloudStorageConfiguration DEFAULT = builder().build();
120+
121+
static CloudStorageConfiguration fromMap(Map<String, ?> env) {
122+
Builder builder = builder();
123+
for (Map.Entry<String, ?> entry : env.entrySet()) {
124+
switch (entry.getKey()) {
125+
case "workingDirectory":
126+
builder.workingDirectory((String) entry.getValue());
127+
break;
128+
case "permitEmptyPathComponents":
129+
builder.permitEmptyPathComponents((Boolean) entry.getValue());
130+
break;
131+
case "stripPrefixSlash":
132+
builder.stripPrefixSlash((Boolean) entry.getValue());
133+
break;
134+
case "usePseudoDirectories":
135+
builder.usePseudoDirectories((Boolean) entry.getValue());
136+
break;
137+
case "blockSize":
138+
builder.blockSize((Integer) entry.getValue());
139+
break;
140+
default:
141+
throw new IllegalArgumentException(entry.getKey());
142+
}
143+
}
144+
return builder.build();
145+
}
146+
147+
CloudStorageConfiguration() {}
148+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.google.gcloud.storage.contrib.nio;
2+
3+
import static com.google.common.base.Verify.verifyNotNull;
4+
5+
import com.google.appengine.tools.cloudstorage.GcsFileMetadata;
6+
import com.google.common.base.MoreObjects;
7+
8+
import java.io.IOException;
9+
import java.nio.file.NoSuchFileException;
10+
import java.nio.file.attribute.BasicFileAttributeView;
11+
import java.nio.file.attribute.FileTime;
12+
import java.util.Objects;
13+
14+
import javax.annotation.Nullable;
15+
import javax.annotation.concurrent.Immutable;
16+
17+
/** Metadata view for a Google Cloud Storage object. */
18+
@Immutable
19+
public final class CloudStorageFileAttributeView implements BasicFileAttributeView {
20+
21+
private final CloudStorageFileSystemProvider provider;
22+
private final CloudStoragePath path;
23+
24+
CloudStorageFileAttributeView(CloudStorageFileSystemProvider provider, CloudStoragePath path) {
25+
this.provider = verifyNotNull(provider);
26+
this.path = verifyNotNull(path);
27+
}
28+
29+
/** Returns {@value CloudStorageFileSystem#GCS_VIEW} */
30+
@Override
31+
public String name() {
32+
return CloudStorageFileSystem.GCS_VIEW;
33+
}
34+
35+
@Override
36+
public CloudStorageFileAttributes readAttributes() throws IOException {
37+
if (path.seemsLikeADirectory()
38+
&& path.getFileSystem().config().usePseudoDirectories()) {
39+
return CloudStoragePseudoDirectoryAttributes.SINGLETON_INSTANCE;
40+
}
41+
GcsFileMetadata metadata = provider.getGcsService().getMetadata(path.getGcsFilename());
42+
if (metadata == null) {
43+
throw new NoSuchFileException(path.toUri().toString());
44+
}
45+
return new CloudStorageObjectAttributes(metadata);
46+
}
47+
48+
/**
49+
* This feature is not supported, since Cloud Storage objects are immutable.
50+
*
51+
* @throws UnsupportedOperationException
52+
*/
53+
@Override
54+
public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) {
55+
throw new CloudStorageObjectImmutableException();
56+
}
57+
58+
@Override
59+
public boolean equals(@Nullable Object other) {
60+
return this == other
61+
|| other instanceof CloudStorageFileAttributeView
62+
&& Objects.equals(provider, ((CloudStorageFileAttributeView) other).provider)
63+
&& Objects.equals(path, ((CloudStorageFileAttributeView) other).path);
64+
}
65+
66+
@Override
67+
public int hashCode() {
68+
return Objects.hash(provider, path);
69+
}
70+
71+
@Override
72+
public String toString() {
73+
return MoreObjects.toStringHelper(this)
74+
.add("provider", provider)
75+
.add("path", path)
76+
.toString();
77+
}
78+
}

0 commit comments

Comments
 (0)