kopia lustrzana https://github.com/gaul/s3proxy
255 wiersze
8.4 KiB
Java
255 wiersze
8.4 KiB
Java
/*
|
|
* Copyright 2014-2021 Andrew Gaul <andrew@gaul.org>
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package org.gaul.s3proxy;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.net.URI;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.Properties;
|
|
import java.util.Random;
|
|
|
|
import com.google.common.base.Strings;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.hash.HashFunction;
|
|
import com.google.common.hash.Hashing;
|
|
import com.google.common.io.ByteSource;
|
|
import com.google.common.io.Files;
|
|
import com.google.common.io.Resources;
|
|
import com.google.inject.Module;
|
|
|
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
|
|
|
import org.jclouds.Constants;
|
|
import org.jclouds.ContextBuilder;
|
|
import org.jclouds.JcloudsVersion;
|
|
import org.jclouds.blobstore.BlobStore;
|
|
import org.jclouds.blobstore.BlobStoreContext;
|
|
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
|
|
|
final class TestUtils {
|
|
@SuppressWarnings("deprecation")
|
|
static final HashFunction MD5 = Hashing.md5();
|
|
|
|
private TestUtils() {
|
|
throw new AssertionError("intentionally unimplemented");
|
|
}
|
|
|
|
static ByteSource randomByteSource() {
|
|
return randomByteSource(0);
|
|
}
|
|
|
|
static ByteSource randomByteSource(long seed) {
|
|
return new RandomByteSource(seed);
|
|
}
|
|
|
|
private static final class RandomByteSource extends ByteSource {
|
|
private final long seed;
|
|
|
|
RandomByteSource(long seed) {
|
|
this.seed = seed;
|
|
}
|
|
|
|
@Override
|
|
public InputStream openStream() {
|
|
return new RandomInputStream(seed);
|
|
}
|
|
}
|
|
|
|
private static final class RandomInputStream extends InputStream {
|
|
private final Random random;
|
|
private boolean closed;
|
|
|
|
RandomInputStream(long seed) {
|
|
this.random = new Random(seed);
|
|
}
|
|
|
|
@Override
|
|
public synchronized int read() throws IOException {
|
|
if (closed) {
|
|
throw new IOException("Stream already closed");
|
|
}
|
|
// return value between 0 and 255
|
|
return random.nextInt() & 0xff;
|
|
}
|
|
|
|
@Override
|
|
public synchronized int read(byte[] b) throws IOException {
|
|
return read(b, 0, b.length);
|
|
}
|
|
|
|
@Override
|
|
public synchronized int read(byte[] b, int off, int len)
|
|
throws IOException {
|
|
for (int i = 0; i < len; ++i) {
|
|
b[off + i] = (byte) read();
|
|
}
|
|
return len;
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
super.close();
|
|
closed = true;
|
|
}
|
|
}
|
|
|
|
static final class S3ProxyLaunchInfo {
|
|
private S3Proxy s3Proxy;
|
|
private final Properties properties = new Properties();
|
|
private String s3Identity;
|
|
private String s3Credential;
|
|
private BlobStore blobStore;
|
|
private URI endpoint;
|
|
private URI secureEndpoint;
|
|
private String servicePath;
|
|
|
|
S3Proxy getS3Proxy() {
|
|
return s3Proxy;
|
|
}
|
|
|
|
Properties getProperties() {
|
|
return properties;
|
|
}
|
|
|
|
String getS3Identity() {
|
|
return s3Identity;
|
|
}
|
|
|
|
String getS3Credential() {
|
|
return s3Credential;
|
|
}
|
|
|
|
String getServicePath() {
|
|
return servicePath;
|
|
}
|
|
|
|
BlobStore getBlobStore() {
|
|
return blobStore;
|
|
}
|
|
|
|
URI getEndpoint() {
|
|
return endpoint;
|
|
}
|
|
|
|
URI getSecureEndpoint() {
|
|
return secureEndpoint;
|
|
}
|
|
}
|
|
|
|
static S3ProxyLaunchInfo startS3Proxy(String configFile) throws Exception {
|
|
S3ProxyLaunchInfo info = new S3ProxyLaunchInfo();
|
|
|
|
try (InputStream is = Resources.asByteSource(Resources.getResource(
|
|
configFile)).openStream()) {
|
|
info.getProperties().load(is);
|
|
}
|
|
|
|
String provider = info.getProperties().getProperty(
|
|
Constants.PROPERTY_PROVIDER);
|
|
String identity = info.getProperties().getProperty(
|
|
Constants.PROPERTY_IDENTITY);
|
|
String credential = info.getProperties().getProperty(
|
|
Constants.PROPERTY_CREDENTIAL);
|
|
if (provider.equals("google-cloud-storage")) {
|
|
File credentialFile = new File(credential);
|
|
if (credentialFile.exists()) {
|
|
credential = Files.asCharSource(credentialFile,
|
|
StandardCharsets.UTF_8).read();
|
|
}
|
|
info.getProperties().remove(Constants.PROPERTY_CREDENTIAL);
|
|
}
|
|
String endpoint = info.getProperties().getProperty(
|
|
Constants.PROPERTY_ENDPOINT);
|
|
|
|
ContextBuilder builder = ContextBuilder
|
|
.newBuilder(provider)
|
|
.credentials(identity, credential)
|
|
.modules(ImmutableList.<Module>of(new SLF4JLoggingModule()))
|
|
.overrides(info.getProperties());
|
|
if (!Strings.isNullOrEmpty(endpoint)) {
|
|
builder.endpoint(endpoint);
|
|
}
|
|
BlobStoreContext context = builder.build(BlobStoreContext.class);
|
|
info.blobStore = context.getBlobStore();
|
|
|
|
String encrypted = info.getProperties().getProperty(
|
|
S3ProxyConstants.PROPERTY_ENCRYPTED_BLOBSTORE);
|
|
if (encrypted != null && encrypted.equals("true")) {
|
|
info.blobStore =
|
|
EncryptedBlobStore.newEncryptedBlobStore(info.blobStore,
|
|
info.getProperties());
|
|
}
|
|
|
|
S3Proxy.Builder s3ProxyBuilder = S3Proxy.Builder.fromProperties(
|
|
info.getProperties());
|
|
s3ProxyBuilder.blobStore(info.blobStore);
|
|
info.endpoint = s3ProxyBuilder.getEndpoint();
|
|
info.secureEndpoint = s3ProxyBuilder.getSecureEndpoint();
|
|
info.s3Identity = s3ProxyBuilder.getIdentity();
|
|
info.s3Credential = s3ProxyBuilder.getCredential();
|
|
info.servicePath = s3ProxyBuilder.getServicePath();
|
|
info.getProperties().setProperty(Constants.PROPERTY_USER_AGENT,
|
|
String.format("s3proxy/%s jclouds/%s java/%s",
|
|
TestUtils.class.getPackage().getImplementationVersion(),
|
|
JcloudsVersion.get(),
|
|
System.getProperty("java.version")));
|
|
|
|
// resolve relative path for tests
|
|
String keyStorePath = info.getProperties().getProperty(
|
|
S3ProxyConstants.PROPERTY_KEYSTORE_PATH);
|
|
String keyStorePassword = info.getProperties().getProperty(
|
|
S3ProxyConstants.PROPERTY_KEYSTORE_PASSWORD);
|
|
if (keyStorePath != null || keyStorePassword != null) {
|
|
s3ProxyBuilder.keyStore(
|
|
Resources.getResource(keyStorePath).toString(),
|
|
keyStorePassword);
|
|
}
|
|
info.s3Proxy = s3ProxyBuilder.build();
|
|
info.s3Proxy.start();
|
|
while (!info.s3Proxy.getState().equals(AbstractLifeCycle.STARTED)) {
|
|
Thread.sleep(1);
|
|
}
|
|
|
|
// reset endpoint to handle zero port
|
|
info.endpoint = new URI(info.endpoint.getScheme(),
|
|
info.endpoint.getUserInfo(), info.endpoint.getHost(),
|
|
info.s3Proxy.getPort(), info.endpoint.getPath(),
|
|
info.endpoint.getQuery(), info.endpoint.getFragment());
|
|
if (info.secureEndpoint != null) {
|
|
info.secureEndpoint = new URI(info.secureEndpoint.getScheme(),
|
|
info.secureEndpoint.getUserInfo(),
|
|
info.secureEndpoint.getHost(),
|
|
info.s3Proxy.getSecurePort(),
|
|
info.secureEndpoint.getPath(),
|
|
info.secureEndpoint.getQuery(),
|
|
info.secureEndpoint.getFragment());
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
static String createRandomContainerName() {
|
|
return "container-" + new Random().nextInt(Integer.MAX_VALUE);
|
|
}
|
|
|
|
static String createRandomBlobName() {
|
|
return "blob-" + new Random().nextInt(Integer.MAX_VALUE);
|
|
}
|
|
}
|