Support multiple configurations

Fixes #11.
pull/246/head
Andrew Gaul 2017-10-31 15:33:51 -07:00
rodzic 6ee33b89f9
commit 251082f7e7
3 zmienionych plików z 152 dodań i 14 usunięć

Wyświetl plik

@ -25,6 +25,7 @@ import java.io.PrintStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors;
@ -32,6 +33,8 @@ import java.util.concurrent.TimeUnit;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.google.inject.Module;
@ -57,8 +60,8 @@ public final class Main {
private static final class Options {
@Option(name = "--properties",
usage = "S3Proxy configuration (required)")
private File propertiesFile;
usage = "S3Proxy configuration (required, multiple allowed)")
private List<File> propertiesFiles;
@Option(name = "--version", usage = "display version")
private boolean version;
@ -82,30 +85,78 @@ public final class Main {
System.err.println(
Main.class.getPackage().getImplementationVersion());
System.exit(0);
} else if (options.propertiesFile == null) {
} else if (options.propertiesFiles.isEmpty()) {
usage(parser);
}
Properties properties = new Properties();
try (InputStream is = new FileInputStream(options.propertiesFile)) {
properties.load(is);
S3Proxy.Builder s3ProxyBuilder = null;
ImmutableMap.Builder<String, Map.Entry<String, BlobStore>> locators =
ImmutableMap.builder();
for (File propertiesFile : options.propertiesFiles) {
Properties properties = new Properties();
try (InputStream is = new FileInputStream(propertiesFile)) {
properties.load(is);
}
properties.putAll(System.getProperties());
BlobStore blobStore = createBlobStore(properties);
blobStore = parseMiddlewareProperties(blobStore, properties);
String s3ProxyAuthorizationString = properties.getProperty(
S3ProxyConstants.PROPERTY_AUTHORIZATION);
if (AuthenticationType.fromString(s3ProxyAuthorizationString) !=
AuthenticationType.NONE) {
String localIdentity = properties.getProperty(
S3ProxyConstants.PROPERTY_IDENTITY);
String localCredential = properties.getProperty(
S3ProxyConstants.PROPERTY_CREDENTIAL);
locators.put(localIdentity, Maps.immutableEntry(
localCredential, blobStore));
}
S3Proxy.Builder s3ProxyBuilder2 = parseS3ProxyProperties(properties)
.blobStore(blobStore);
if (s3ProxyBuilder != null &&
!s3ProxyBuilder.equals(s3ProxyBuilder2)) {
System.err.println("Multiple configurations require" +
" identical s3proxy properties");
System.exit(1);
}
s3ProxyBuilder = s3ProxyBuilder2;
}
properties.putAll(System.getProperties());
BlobStore blobStore = createBlobStore(properties);
blobStore = parseMiddlewareProperties(blobStore, properties);
S3Proxy s3Proxy;
try {
S3Proxy.Builder s3ProxyBuilder = parseS3ProxyProperties(properties);
s3Proxy = s3ProxyBuilder.blobStore(blobStore)
.build();
s3Proxy = s3ProxyBuilder.build();
} catch (IllegalArgumentException | IllegalStateException e) {
System.err.println(e.getMessage());
System.exit(1);
throw e;
}
final Map<String, Map.Entry<String, BlobStore>> locator =
locators.build();
if (!locator.isEmpty()) {
s3Proxy.setBlobStoreLocator(new BlobStoreLocator() {
@Override
public Map.Entry<String, BlobStore> locateBlobStore(
String identity, String container, String blob) {
if (identity == null) {
if (locator.size() == 1) {
return locator.entrySet().iterator().next()
.getValue();
}
throw new IllegalArgumentException(
"cannot use anonymous access with multiple" +
" backends");
}
return locator.get(identity);
}
});
}
try {
s3Proxy.start();
} catch (Exception e) {

Wyświetl plik

@ -21,6 +21,7 @@ import static java.util.Objects.requireNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import java.net.URI;
import java.util.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
@ -205,6 +206,37 @@ public final class S3Proxy {
this.servicePath = path;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (!(object instanceof S3Proxy.Builder)) {
return false;
}
S3Proxy.Builder that = (S3Proxy.Builder) object;
// do not check credentials or storage backend fields
return Objects.equals(this.endpoint, that.endpoint) &&
Objects.equals(this.secureEndpoint, that.secureEndpoint) &&
Objects.equals(this.keyStorePath, that.keyStorePath) &&
Objects.equals(this.keyStorePassword,
that.keyStorePassword) &&
Objects.equals(this.virtualHost, that.virtualHost) &&
Objects.equals(this.servicePath, that.servicePath) &&
Objects.equals(this.v4MaxNonChunkedRequestSize,
that.v4MaxNonChunkedRequestSize) &&
Objects.equals(this.ignoreUnknownHeaders,
that.ignoreUnknownHeaders) &&
Objects.equals(this.corsAllowAll, that.corsAllowAll);
}
@Override
public int hashCode() {
return Objects.hash(endpoint, secureEndpoint, keyStorePath,
keyStorePassword, virtualHost, servicePath,
v4MaxNonChunkedRequestSize, ignoreUnknownHeaders,
corsAllowAll);
}
}
public static Builder builder() {

Wyświetl plik

@ -87,10 +87,13 @@ import com.amazonaws.services.s3.model.UploadPartRequest;
import com.amazonaws.services.s3.model.UploadPartResult;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.io.ByteSource;
import org.assertj.core.api.Fail;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.rest.HttpClient;
@ -1379,6 +1382,58 @@ public final class AwsSdkTest {
}
}
@Test
public void testBlobStoreLocator() throws Exception {
final BlobStore blobStore1 = context.getBlobStore();
final BlobStore blobStore2 = ContextBuilder
.newBuilder(blobStoreType)
.credentials("other-identity", "credential")
.build(BlobStoreContext.class)
.getBlobStore();
s3Proxy.setBlobStoreLocator(new BlobStoreLocator() {
@Override
public Map.Entry<String, BlobStore> locateBlobStore(
String identity, String container, String blob) {
if (identity.equals(awsCreds.getAWSAccessKeyId())) {
return Maps.immutableEntry(awsCreds.getAWSSecretKey(),
blobStore1);
} else if (identity.equals("other-identity")) {
return Maps.immutableEntry("credential", blobStore2);
} else {
return null;
}
}
});
// check first access key
List<Bucket> buckets = client.listBuckets();
assertThat(buckets).hasSize(1);
assertThat(buckets.get(0).getName()).isEqualTo(containerName);
// check second access key
client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials("other-identity",
"credential")))
.withEndpointConfiguration(s3EndpointConfig)
.build();
buckets = client.listBuckets();
assertThat(buckets).isEmpty();
// check invalid access key
client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials("bad-identity", "credential")))
.withEndpointConfiguration(s3EndpointConfig)
.build();
try {
client.listBuckets();
Fail.failBecauseExceptionWasNotThrown(AmazonS3Exception.class);
} catch (AmazonS3Exception e) {
assertThat(e.getErrorCode()).isEqualTo("InvalidAccessKeyId");
}
}
private static final class NullX509TrustManager
implements X509TrustManager {
@Override