HDDS-444. Add rest service to the s3gateway. Contributed by Elek Marton.
This commit is contained in:
parent
29dad7d258
commit
9c3fbbc4f6
|
@ -82,7 +82,7 @@ public class GenericCli implements Callable<Void>, GenericParentCommand {
|
||||||
if (configurationOverrides != null) {
|
if (configurationOverrides != null) {
|
||||||
for (Entry<String, String> entry : configurationOverrides.entrySet()) {
|
for (Entry<String, String> entry : configurationOverrides.entrySet()) {
|
||||||
ozoneConf
|
ozoneConf
|
||||||
.set(entry.getKey(), configurationOverrides.get(entry.getValue()));
|
.set(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ozoneConf;
|
return ozoneConf;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.apache.hadoop.ozone.client;
|
package org.apache.hadoop.ozone.client;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
|
import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
|
||||||
|
@ -56,6 +57,11 @@ public class ObjectStore {
|
||||||
this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
|
this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected ObjectStore() {
|
||||||
|
proxy = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the volume with default values.
|
* Creates the volume with default values.
|
||||||
* @param volumeName Name of the volume to be created.
|
* @param volumeName Name of the volume to be created.
|
||||||
|
@ -96,7 +102,7 @@ public class ObjectStore {
|
||||||
* @param volumePrefix Volume prefix to match
|
* @param volumePrefix Volume prefix to match
|
||||||
* @return {@code Iterator<OzoneVolume>}
|
* @return {@code Iterator<OzoneVolume>}
|
||||||
*/
|
*/
|
||||||
public Iterator<OzoneVolume> listVolumes(String volumePrefix)
|
public Iterator<? extends OzoneVolume> listVolumes(String volumePrefix)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return listVolumes(volumePrefix, null);
|
return listVolumes(volumePrefix, null);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +117,7 @@ public class ObjectStore {
|
||||||
* @param prevVolume Volumes will be listed after this volume name
|
* @param prevVolume Volumes will be listed after this volume name
|
||||||
* @return {@code Iterator<OzoneVolume>}
|
* @return {@code Iterator<OzoneVolume>}
|
||||||
*/
|
*/
|
||||||
public Iterator<OzoneVolume> listVolumes(String volumePrefix,
|
public Iterator<? extends OzoneVolume> listVolumes(String volumePrefix,
|
||||||
String prevVolume) throws IOException {
|
String prevVolume) throws IOException {
|
||||||
return new VolumeIterator(null, volumePrefix, prevVolume);
|
return new VolumeIterator(null, volumePrefix, prevVolume);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +133,7 @@ public class ObjectStore {
|
||||||
* @param prevVolume Volumes will be listed after this volume name
|
* @param prevVolume Volumes will be listed after this volume name
|
||||||
* @return {@code Iterator<OzoneVolume>}
|
* @return {@code Iterator<OzoneVolume>}
|
||||||
*/
|
*/
|
||||||
public Iterator<OzoneVolume> listVolumesByUser(String user,
|
public Iterator<? extends OzoneVolume> listVolumesByUser(String user,
|
||||||
String volumePrefix, String prevVolume)
|
String volumePrefix, String prevVolume)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if(Strings.isNullOrEmpty(user)) {
|
if(Strings.isNullOrEmpty(user)) {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
package org.apache.hadoop.ozone.client;
|
package org.apache.hadoop.ozone.client;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.StorageType;
|
import org.apache.hadoop.fs.StorageType;
|
||||||
|
@ -121,6 +121,23 @@ public class OzoneBucket {
|
||||||
OzoneConfigKeys.OZONE_REPLICATION_TYPE_DEFAULT));
|
OzoneConfigKeys.OZONE_REPLICATION_TYPE_DEFAULT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
OzoneBucket(String volumeName, String name,
|
||||||
|
ReplicationFactor defaultReplication,
|
||||||
|
ReplicationType defaultReplicationType,
|
||||||
|
List<OzoneAcl> acls, StorageType storageType, Boolean versioning,
|
||||||
|
long creationTime) {
|
||||||
|
this.proxy = null;
|
||||||
|
this.volumeName = volumeName;
|
||||||
|
this.name = name;
|
||||||
|
this.defaultReplication = defaultReplication;
|
||||||
|
this.defaultReplicationType = defaultReplicationType;
|
||||||
|
this.acls = acls;
|
||||||
|
this.storageType = storageType;
|
||||||
|
this.versioning = versioning;
|
||||||
|
this.creationTime = creationTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Volume Name.
|
* Returns Volume Name.
|
||||||
*
|
*
|
||||||
|
@ -273,7 +290,7 @@ public class OzoneBucket {
|
||||||
* @param keyPrefix Bucket prefix to match
|
* @param keyPrefix Bucket prefix to match
|
||||||
* @return {@code Iterator<OzoneKey>}
|
* @return {@code Iterator<OzoneKey>}
|
||||||
*/
|
*/
|
||||||
public Iterator<OzoneKey> listKeys(String keyPrefix) {
|
public Iterator<? extends OzoneKey> listKeys(String keyPrefix) {
|
||||||
return listKeys(keyPrefix, null);
|
return listKeys(keyPrefix, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +304,8 @@ public class OzoneBucket {
|
||||||
* @param prevKey Keys will be listed after this key name
|
* @param prevKey Keys will be listed after this key name
|
||||||
* @return {@code Iterator<OzoneKey>}
|
* @return {@code Iterator<OzoneKey>}
|
||||||
*/
|
*/
|
||||||
public Iterator<OzoneKey> listKeys(String keyPrefix, String prevKey) {
|
public Iterator<? extends OzoneKey> listKeys(String keyPrefix,
|
||||||
|
String prevKey) {
|
||||||
return new KeyIterator(keyPrefix, prevKey);
|
return new KeyIterator(keyPrefix, prevKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OzoneClient connects to Ozone Cluster and
|
* OzoneClient connects to Ozone Cluster and
|
||||||
* perform basic operations.
|
* perform basic operations.
|
||||||
|
@ -84,6 +86,11 @@ public class OzoneClient implements Closeable {
|
||||||
this.objectStore = new ObjectStore(conf, this.proxy);
|
this.objectStore = new ObjectStore(conf, this.proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected OzoneClient(ObjectStore objectStore) {
|
||||||
|
this.objectStore = objectStore;
|
||||||
|
this.proxy = null;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Returns the object store associated with the Ozone Cluster.
|
* Returns the object store associated with the Ozone Cluster.
|
||||||
* @return ObjectStore
|
* @return ObjectStore
|
||||||
|
|
|
@ -18,17 +18,19 @@
|
||||||
|
|
||||||
package org.apache.hadoop.ozone.client;
|
package org.apache.hadoop.ozone.client;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hdds.client.OzoneQuota;
|
import org.apache.hadoop.hdds.client.OzoneQuota;
|
||||||
import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
|
import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
|
||||||
import org.apache.hadoop.ozone.OzoneAcl;
|
import org.apache.hadoop.ozone.OzoneAcl;
|
||||||
import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
|
import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import java.util.Iterator;
|
import com.google.common.base.Preconditions;
|
||||||
import java.util.List;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that encapsulates OzoneVolume.
|
* A class that encapsulates OzoneVolume.
|
||||||
|
@ -94,6 +96,19 @@ public class OzoneVolume {
|
||||||
this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
|
this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected OzoneVolume(String name, String admin, String owner,
|
||||||
|
long quotaInBytes,
|
||||||
|
long creationTime, List<OzoneAcl> acls) {
|
||||||
|
this.proxy = null;
|
||||||
|
this.name = name;
|
||||||
|
this.admin = admin;
|
||||||
|
this.owner = owner;
|
||||||
|
this.quotaInBytes = quotaInBytes;
|
||||||
|
this.creationTime = creationTime;
|
||||||
|
this.acls = acls;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Volume name.
|
* Returns Volume name.
|
||||||
*
|
*
|
||||||
|
@ -208,12 +223,13 @@ public class OzoneVolume {
|
||||||
* @param bucketPrefix Bucket prefix to match
|
* @param bucketPrefix Bucket prefix to match
|
||||||
* @return {@code Iterator<OzoneBucket>}
|
* @return {@code Iterator<OzoneBucket>}
|
||||||
*/
|
*/
|
||||||
public Iterator<OzoneBucket> listBuckets(String bucketPrefix) {
|
public Iterator<? extends OzoneBucket> listBuckets(String bucketPrefix) {
|
||||||
return listBuckets(bucketPrefix, null);
|
return listBuckets(bucketPrefix, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Iterator to iterate over all buckets after prevBucket in the volume.
|
* Returns Iterator to iterate over all buckets after prevBucket in the
|
||||||
|
* volume.
|
||||||
* If prevBucket is null it iterates from the first bucket in the volume.
|
* If prevBucket is null it iterates from the first bucket in the volume.
|
||||||
* The result can be restricted using bucket prefix, will return all
|
* The result can be restricted using bucket prefix, will return all
|
||||||
* buckets if bucket prefix is null.
|
* buckets if bucket prefix is null.
|
||||||
|
@ -222,7 +238,7 @@ public class OzoneVolume {
|
||||||
* @param prevBucket Buckets are listed after this bucket
|
* @param prevBucket Buckets are listed after this bucket
|
||||||
* @return {@code Iterator<OzoneBucket>}
|
* @return {@code Iterator<OzoneBucket>}
|
||||||
*/
|
*/
|
||||||
public Iterator<OzoneBucket> listBuckets(String bucketPrefix,
|
public Iterator<? extends OzoneBucket> listBuckets(String bucketPrefix,
|
||||||
String prevBucket) {
|
String prevBucket) {
|
||||||
return new BucketIterator(bucketPrefix, prevBucket);
|
return new BucketIterator(bucketPrefix, prevBucket);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ services:
|
||||||
image: apache/hadoop-runner
|
image: apache/hadoop-runner
|
||||||
volumes:
|
volumes:
|
||||||
- ../..:/opt/hadoop
|
- ../..:/opt/hadoop
|
||||||
|
ports:
|
||||||
|
- 9878:9878
|
||||||
env_file:
|
env_file:
|
||||||
- ./docker-config
|
- ./docker-config
|
||||||
command: ["ozone","s3g"]
|
command: ["ozone","s3g"]
|
||||||
|
|
|
@ -701,26 +701,29 @@ public class TestOzoneRpcClient {
|
||||||
store.createVolume(
|
store.createVolume(
|
||||||
volBaseNameB + i + "-" + RandomStringUtils.randomNumeric(5));
|
volBaseNameB + i + "-" + RandomStringUtils.randomNumeric(5));
|
||||||
}
|
}
|
||||||
Iterator<OzoneVolume> volIterator = store.listVolumes(volBase);
|
Iterator<? extends OzoneVolume> volIterator = store.listVolumes(volBase);
|
||||||
int totalVolumeCount = 0;
|
int totalVolumeCount = 0;
|
||||||
while(volIterator.hasNext()) {
|
while(volIterator.hasNext()) {
|
||||||
volIterator.next();
|
volIterator.next();
|
||||||
totalVolumeCount++;
|
totalVolumeCount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(20, totalVolumeCount);
|
Assert.assertEquals(20, totalVolumeCount);
|
||||||
Iterator<OzoneVolume> volAIterator = store.listVolumes(volBaseNameA);
|
Iterator<? extends OzoneVolume> volAIterator = store.listVolumes(
|
||||||
|
volBaseNameA);
|
||||||
for(int i = 0; i < 10; i++) {
|
for(int i = 0; i < 10; i++) {
|
||||||
Assert.assertTrue(volAIterator.next().getName()
|
Assert.assertTrue(volAIterator.next().getName()
|
||||||
.startsWith(volBaseNameA + i + "-"));
|
.startsWith(volBaseNameA + i + "-"));
|
||||||
}
|
}
|
||||||
Assert.assertFalse(volAIterator.hasNext());
|
Assert.assertFalse(volAIterator.hasNext());
|
||||||
Iterator<OzoneVolume> volBIterator = store.listVolumes(volBaseNameB);
|
Iterator<? extends OzoneVolume> volBIterator = store.listVolumes(
|
||||||
|
volBaseNameB);
|
||||||
for(int i = 0; i < 10; i++) {
|
for(int i = 0; i < 10; i++) {
|
||||||
Assert.assertTrue(volBIterator.next().getName()
|
Assert.assertTrue(volBIterator.next().getName()
|
||||||
.startsWith(volBaseNameB + i + "-"));
|
.startsWith(volBaseNameB + i + "-"));
|
||||||
}
|
}
|
||||||
Assert.assertFalse(volBIterator.hasNext());
|
Assert.assertFalse(volBIterator.hasNext());
|
||||||
Iterator<OzoneVolume> iter = store.listVolumes(volBaseNameA + "1-");
|
Iterator<? extends OzoneVolume> iter = store.listVolumes(volBaseNameA +
|
||||||
|
"1-");
|
||||||
Assert.assertTrue(iter.next().getName().startsWith(volBaseNameA + "1-"));
|
Assert.assertTrue(iter.next().getName().startsWith(volBaseNameA + "1-"));
|
||||||
Assert.assertFalse(iter.hasNext());
|
Assert.assertFalse(iter.hasNext());
|
||||||
}
|
}
|
||||||
|
@ -751,7 +754,7 @@ public class TestOzoneRpcClient {
|
||||||
volB.createBucket(
|
volB.createBucket(
|
||||||
bucketBaseNameB + i + "-" + RandomStringUtils.randomNumeric(5));
|
bucketBaseNameB + i + "-" + RandomStringUtils.randomNumeric(5));
|
||||||
}
|
}
|
||||||
Iterator<OzoneBucket> volABucketIter =
|
Iterator<? extends OzoneBucket> volABucketIter =
|
||||||
volA.listBuckets("bucket-");
|
volA.listBuckets("bucket-");
|
||||||
int volABucketCount = 0;
|
int volABucketCount = 0;
|
||||||
while(volABucketIter.hasNext()) {
|
while(volABucketIter.hasNext()) {
|
||||||
|
@ -759,7 +762,7 @@ public class TestOzoneRpcClient {
|
||||||
volABucketCount++;
|
volABucketCount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(20, volABucketCount);
|
Assert.assertEquals(20, volABucketCount);
|
||||||
Iterator<OzoneBucket> volBBucketIter =
|
Iterator<? extends OzoneBucket> volBBucketIter =
|
||||||
volA.listBuckets("bucket-");
|
volA.listBuckets("bucket-");
|
||||||
int volBBucketCount = 0;
|
int volBBucketCount = 0;
|
||||||
while(volBBucketIter.hasNext()) {
|
while(volBBucketIter.hasNext()) {
|
||||||
|
@ -768,7 +771,7 @@ public class TestOzoneRpcClient {
|
||||||
}
|
}
|
||||||
Assert.assertEquals(20, volBBucketCount);
|
Assert.assertEquals(20, volBBucketCount);
|
||||||
|
|
||||||
Iterator<OzoneBucket> volABucketAIter =
|
Iterator<? extends OzoneBucket> volABucketAIter =
|
||||||
volA.listBuckets("bucket-a-");
|
volA.listBuckets("bucket-a-");
|
||||||
int volABucketACount = 0;
|
int volABucketACount = 0;
|
||||||
while(volABucketAIter.hasNext()) {
|
while(volABucketAIter.hasNext()) {
|
||||||
|
@ -776,7 +779,7 @@ public class TestOzoneRpcClient {
|
||||||
volABucketACount++;
|
volABucketACount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(10, volABucketACount);
|
Assert.assertEquals(10, volABucketACount);
|
||||||
Iterator<OzoneBucket> volBBucketBIter =
|
Iterator<? extends OzoneBucket> volBBucketBIter =
|
||||||
volA.listBuckets("bucket-b-");
|
volA.listBuckets("bucket-b-");
|
||||||
int volBBucketBCount = 0;
|
int volBBucketBCount = 0;
|
||||||
while(volBBucketBIter.hasNext()) {
|
while(volBBucketBIter.hasNext()) {
|
||||||
|
@ -784,13 +787,15 @@ public class TestOzoneRpcClient {
|
||||||
volBBucketBCount++;
|
volBBucketBCount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(10, volBBucketBCount);
|
Assert.assertEquals(10, volBBucketBCount);
|
||||||
Iterator<OzoneBucket> volABucketBIter = volA.listBuckets("bucket-b-");
|
Iterator<? extends OzoneBucket> volABucketBIter = volA.listBuckets(
|
||||||
|
"bucket-b-");
|
||||||
for(int i = 0; i < 10; i++) {
|
for(int i = 0; i < 10; i++) {
|
||||||
Assert.assertTrue(volABucketBIter.next().getName()
|
Assert.assertTrue(volABucketBIter.next().getName()
|
||||||
.startsWith(bucketBaseNameB + i + "-"));
|
.startsWith(bucketBaseNameB + i + "-"));
|
||||||
}
|
}
|
||||||
Assert.assertFalse(volABucketBIter.hasNext());
|
Assert.assertFalse(volABucketBIter.hasNext());
|
||||||
Iterator<OzoneBucket> volBBucketAIter = volB.listBuckets("bucket-a-");
|
Iterator<? extends OzoneBucket> volBBucketAIter = volB.listBuckets(
|
||||||
|
"bucket-a-");
|
||||||
for(int i = 0; i < 10; i++) {
|
for(int i = 0; i < 10; i++) {
|
||||||
Assert.assertTrue(volBBucketAIter.next().getName()
|
Assert.assertTrue(volBBucketAIter.next().getName()
|
||||||
.startsWith(bucketBaseNameA + i + "-"));
|
.startsWith(bucketBaseNameA + i + "-"));
|
||||||
|
@ -805,7 +810,7 @@ public class TestOzoneRpcClient {
|
||||||
String volume = "vol-" + RandomStringUtils.randomNumeric(5);
|
String volume = "vol-" + RandomStringUtils.randomNumeric(5);
|
||||||
store.createVolume(volume);
|
store.createVolume(volume);
|
||||||
OzoneVolume vol = store.getVolume(volume);
|
OzoneVolume vol = store.getVolume(volume);
|
||||||
Iterator<OzoneBucket> buckets = vol.listBuckets("");
|
Iterator<? extends OzoneBucket> buckets = vol.listBuckets("");
|
||||||
while(buckets.hasNext()) {
|
while(buckets.hasNext()) {
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
}
|
}
|
||||||
|
@ -889,7 +894,7 @@ public class TestOzoneRpcClient {
|
||||||
four.write(value);
|
four.write(value);
|
||||||
four.close();
|
four.close();
|
||||||
}
|
}
|
||||||
Iterator<OzoneKey> volABucketAIter =
|
Iterator<? extends OzoneKey> volABucketAIter =
|
||||||
volAbucketA.listKeys("key-");
|
volAbucketA.listKeys("key-");
|
||||||
int volABucketAKeyCount = 0;
|
int volABucketAKeyCount = 0;
|
||||||
while(volABucketAIter.hasNext()) {
|
while(volABucketAIter.hasNext()) {
|
||||||
|
@ -897,7 +902,7 @@ public class TestOzoneRpcClient {
|
||||||
volABucketAKeyCount++;
|
volABucketAKeyCount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(20, volABucketAKeyCount);
|
Assert.assertEquals(20, volABucketAKeyCount);
|
||||||
Iterator<OzoneKey> volABucketBIter =
|
Iterator<? extends OzoneKey> volABucketBIter =
|
||||||
volAbucketB.listKeys("key-");
|
volAbucketB.listKeys("key-");
|
||||||
int volABucketBKeyCount = 0;
|
int volABucketBKeyCount = 0;
|
||||||
while(volABucketBIter.hasNext()) {
|
while(volABucketBIter.hasNext()) {
|
||||||
|
@ -905,7 +910,7 @@ public class TestOzoneRpcClient {
|
||||||
volABucketBKeyCount++;
|
volABucketBKeyCount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(20, volABucketBKeyCount);
|
Assert.assertEquals(20, volABucketBKeyCount);
|
||||||
Iterator<OzoneKey> volBBucketAIter =
|
Iterator<? extends OzoneKey> volBBucketAIter =
|
||||||
volBbucketA.listKeys("key-");
|
volBbucketA.listKeys("key-");
|
||||||
int volBBucketAKeyCount = 0;
|
int volBBucketAKeyCount = 0;
|
||||||
while(volBBucketAIter.hasNext()) {
|
while(volBBucketAIter.hasNext()) {
|
||||||
|
@ -913,7 +918,7 @@ public class TestOzoneRpcClient {
|
||||||
volBBucketAKeyCount++;
|
volBBucketAKeyCount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(20, volBBucketAKeyCount);
|
Assert.assertEquals(20, volBBucketAKeyCount);
|
||||||
Iterator<OzoneKey> volBBucketBIter =
|
Iterator<? extends OzoneKey> volBBucketBIter =
|
||||||
volBbucketB.listKeys("key-");
|
volBbucketB.listKeys("key-");
|
||||||
int volBBucketBKeyCount = 0;
|
int volBBucketBKeyCount = 0;
|
||||||
while(volBBucketBIter.hasNext()) {
|
while(volBBucketBIter.hasNext()) {
|
||||||
|
@ -921,7 +926,7 @@ public class TestOzoneRpcClient {
|
||||||
volBBucketBKeyCount++;
|
volBBucketBKeyCount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(20, volBBucketBKeyCount);
|
Assert.assertEquals(20, volBBucketBKeyCount);
|
||||||
Iterator<OzoneKey> volABucketAKeyAIter =
|
Iterator<? extends OzoneKey> volABucketAKeyAIter =
|
||||||
volAbucketA.listKeys("key-a-");
|
volAbucketA.listKeys("key-a-");
|
||||||
int volABucketAKeyACount = 0;
|
int volABucketAKeyACount = 0;
|
||||||
while(volABucketAKeyAIter.hasNext()) {
|
while(volABucketAKeyAIter.hasNext()) {
|
||||||
|
@ -929,7 +934,7 @@ public class TestOzoneRpcClient {
|
||||||
volABucketAKeyACount++;
|
volABucketAKeyACount++;
|
||||||
}
|
}
|
||||||
Assert.assertEquals(10, volABucketAKeyACount);
|
Assert.assertEquals(10, volABucketAKeyACount);
|
||||||
Iterator<OzoneKey> volABucketAKeyBIter =
|
Iterator<? extends OzoneKey> volABucketAKeyBIter =
|
||||||
volAbucketA.listKeys("key-b-");
|
volAbucketA.listKeys("key-b-");
|
||||||
for(int i = 0; i < 10; i++) {
|
for(int i = 0; i < 10; i++) {
|
||||||
Assert.assertTrue(volABucketAKeyBIter.next().getName()
|
Assert.assertTrue(volABucketAKeyBIter.next().getName()
|
||||||
|
@ -947,7 +952,7 @@ public class TestOzoneRpcClient {
|
||||||
OzoneVolume vol = store.getVolume(volume);
|
OzoneVolume vol = store.getVolume(volume);
|
||||||
vol.createBucket(bucket);
|
vol.createBucket(bucket);
|
||||||
OzoneBucket buc = vol.getBucket(bucket);
|
OzoneBucket buc = vol.getBucket(bucket);
|
||||||
Iterator<OzoneKey> keys = buc.listKeys("");
|
Iterator<? extends OzoneKey> keys = buc.listKeys("");
|
||||||
while(keys.hasNext()) {
|
while(keys.hasNext()) {
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,7 +305,7 @@ public class TestBuckets {
|
||||||
.build();
|
.build();
|
||||||
vol.createBucket(bucketName, bucketArgs);
|
vol.createBucket(bucketName, bucketArgs);
|
||||||
}
|
}
|
||||||
Iterator<OzoneBucket> bucketIterator = vol.listBuckets(null);
|
Iterator<? extends OzoneBucket> bucketIterator = vol.listBuckets(null);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
while (bucketIterator.hasNext()) {
|
while (bucketIterator.hasNext()) {
|
||||||
|
@ -324,7 +324,7 @@ public class TestBuckets {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getSize(Iterator<OzoneBucket> bucketIterator) {
|
private static int getSize(Iterator<? extends OzoneBucket> bucketIterator) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (bucketIterator.hasNext()) {
|
while (bucketIterator.hasNext()) {
|
||||||
count++;
|
count++;
|
||||||
|
|
|
@ -88,7 +88,8 @@ public class ListBucketHandler extends Handler {
|
||||||
|
|
||||||
|
|
||||||
OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
|
OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
|
||||||
Iterator<OzoneBucket> bucketIterator = vol.listBuckets(prefix, startBucket);
|
Iterator<? extends OzoneBucket> bucketIterator =
|
||||||
|
vol.listBuckets(prefix, startBucket);
|
||||||
List<BucketInfo> bucketList = new ArrayList<>();
|
List<BucketInfo> bucketList = new ArrayList<>();
|
||||||
while (maxBuckets > 0 && bucketIterator.hasNext()) {
|
while (maxBuckets > 0 && bucketIterator.hasNext()) {
|
||||||
BucketInfo bucketInfo =
|
BucketInfo bucketInfo =
|
||||||
|
|
|
@ -91,7 +91,8 @@ public class ListKeyHandler extends Handler {
|
||||||
|
|
||||||
OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
|
OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
|
||||||
OzoneBucket bucket = vol.getBucket(bucketName);
|
OzoneBucket bucket = vol.getBucket(bucketName);
|
||||||
Iterator<OzoneKey> keyIterator = bucket.listKeys(prefix, startKey);
|
Iterator<? extends OzoneKey> keyIterator = bucket.listKeys(prefix,
|
||||||
|
startKey);
|
||||||
List<KeyInfo> keyInfos = new ArrayList<>();
|
List<KeyInfo> keyInfos = new ArrayList<>();
|
||||||
|
|
||||||
while (maxKeys > 0 && keyIterator.hasNext()) {
|
while (maxKeys > 0 && keyIterator.hasNext()) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class ListVolumeHandler extends Handler {
|
||||||
"the length should be a positive number");
|
"the length should be a positive number");
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator<OzoneVolume> volumeIterator;
|
Iterator<? extends OzoneVolume> volumeIterator;
|
||||||
if(userName != null) {
|
if(userName != null) {
|
||||||
volumeIterator = client.getObjectStore()
|
volumeIterator = client.getObjectStore()
|
||||||
.listVolumesByUser(userName, prefix, startVolume);
|
.listVolumesByUser(userName, prefix, startVolume);
|
||||||
|
|
|
@ -638,7 +638,7 @@ public class OzoneFileSystem extends FileSystem {
|
||||||
private final Path path;
|
private final Path path;
|
||||||
private final FileStatus status;
|
private final FileStatus status;
|
||||||
private String pathKey;
|
private String pathKey;
|
||||||
private Iterator<OzoneKey> keyIterator;
|
private Iterator<? extends OzoneKey> keyIterator;
|
||||||
|
|
||||||
OzoneListingIterator(Path path)
|
OzoneListingIterator(Path path)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
|
@ -183,6 +183,17 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>test-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import javax.ws.rs.container.ContainerRequestContext;
|
||||||
|
import javax.ws.rs.container.ContainerResponseContext;
|
||||||
|
import javax.ws.rs.container.ContainerResponseFilter;
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class adds common header responses for all the requests.
|
||||||
|
*/
|
||||||
|
@Provider
|
||||||
|
public class CommonHeadersContainerResponseFilter implements
|
||||||
|
ContainerResponseFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void filter(ContainerRequestContext containerRequestContext,
|
||||||
|
ContainerResponseContext containerResponseContext) throws IOException {
|
||||||
|
containerResponseContext.getHeaders().add("Server", "Ozone");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneBucket;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneClient;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneVolume;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic helpers for all the REST endpoints.
|
||||||
|
*/
|
||||||
|
public class EndpointBase {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OzoneClient client;
|
||||||
|
|
||||||
|
protected OzoneBucket getBucket(String volumeName, String bucketName)
|
||||||
|
throws IOException {
|
||||||
|
return getVolume(volumeName).getBucket(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OzoneBucket getBucket(OzoneVolume volume, String bucketName)
|
||||||
|
throws IOException {
|
||||||
|
OzoneBucket bucket = null;
|
||||||
|
try {
|
||||||
|
bucket = volume.getBucket(bucketName);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
if (ex.getMessage().contains("NOT_FOUND")) {
|
||||||
|
throw new NotFoundException("Bucket" + bucketName + " is not found");
|
||||||
|
} else {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OzoneVolume getVolume(String volumeName) throws IOException {
|
||||||
|
OzoneVolume volume = null;
|
||||||
|
try {
|
||||||
|
volume = client.getObjectStore().getVolume(volumeName);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
if (ex.getMessage().contains("NOT_FOUND")) {
|
||||||
|
throw new NotFoundException("Volume " + volumeName + " is not found");
|
||||||
|
} else {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void setClient(OzoneClient ozoneClient) {
|
||||||
|
this.client = ozoneClient;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,8 +17,11 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.ozone.s3;
|
package org.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.hadoop.hdds.cli.GenericCli;
|
import org.apache.hadoop.hdds.cli.GenericCli;
|
||||||
import org.apache.hadoop.hdds.cli.HddsVersionProvider;
|
import org.apache.hadoop.hdds.cli.HddsVersionProvider;
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -35,21 +38,29 @@ public class Gateway extends GenericCli {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Gateway.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Gateway.class);
|
||||||
|
|
||||||
|
private S3GatewayHttpServer httpServer;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
new Gateway().run(args);
|
new Gateway().run(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
|
OzoneConfiguration ozoneConfiguration = createOzoneConfiguration();
|
||||||
|
OzoneConfigurationHolder.setConfiguration(ozoneConfiguration);
|
||||||
|
httpServer = new S3GatewayHttpServer(ozoneConfiguration, "s3gateway");
|
||||||
start();
|
start();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() throws IOException {
|
||||||
LOG.info("Starting Ozone S3 gateway");
|
LOG.info("Starting Ozone S3 gateway");
|
||||||
|
httpServer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() throws Exception {
|
||||||
LOG.info("Stoping Ozone S3 gateway");
|
LOG.info("Stopping Ozone S3 gateway");
|
||||||
|
httpServer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JaxRS resource definition.
|
||||||
|
*/
|
||||||
|
public class GatewayApplication extends ResourceConfig {
|
||||||
|
public GatewayApplication() {
|
||||||
|
packages("org.apache.hadoop.ozone.s3");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneClient;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneClientFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class creates the OzoneClient for the Rest endpoints.
|
||||||
|
*/
|
||||||
|
@ApplicationScoped
|
||||||
|
public class OzoneClientProducer {
|
||||||
|
|
||||||
|
private OzoneConfiguration ozoneConfiguration;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public OzoneClientProducer(
|
||||||
|
OzoneConfiguration ozoneConfiguration) {
|
||||||
|
this.ozoneConfiguration = ozoneConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public OzoneClient createClient() throws IOException {
|
||||||
|
return OzoneClientFactory.getClient(ozoneConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ozone Configuration factory.
|
||||||
|
* <p>
|
||||||
|
* As the OzoneConfiguration is created by the CLI application here we inject
|
||||||
|
* it via a singleton instance to the Jax-RS/CDI instances.
|
||||||
|
*/
|
||||||
|
public class OzoneConfigurationHolder {
|
||||||
|
|
||||||
|
private static OzoneConfiguration configuration;
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public OzoneConfiguration configuration() {
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setConfiguration(
|
||||||
|
OzoneConfiguration conf) {
|
||||||
|
OzoneConfigurationHolder.configuration = conf;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class contains constants for configuration keys used in S3G.
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.Public
|
||||||
|
@InterfaceStability.Unstable
|
||||||
|
public final class S3GatewayConfigKeys {
|
||||||
|
|
||||||
|
public static final String OZONE_S3G_HTTP_ENABLED_KEY =
|
||||||
|
"ozone.s3g.http.enabled";
|
||||||
|
public static final String OZONE_S3G_HTTP_BIND_HOST_KEY =
|
||||||
|
"ozone.s3g.http-bind-host";
|
||||||
|
public static final String OZONE_S3G_HTTPS_BIND_HOST_KEY =
|
||||||
|
"ozone.s3g.https-bind-host";
|
||||||
|
public static final String OZONE_S3G_HTTP_ADDRESS_KEY =
|
||||||
|
"ozone.s3g.http-address";
|
||||||
|
public static final String OZONE_S3G_HTTPS_ADDRESS_KEY =
|
||||||
|
"ozone.s3g.https-address";
|
||||||
|
public static final String OZONE_S3G_KEYTAB_FILE =
|
||||||
|
"ozone.s3g.keytab.file";
|
||||||
|
public static final String OZONE_S3G_HTTP_BIND_HOST_DEFAULT = "0.0.0.0";
|
||||||
|
public static final int OZONE_S3G_HTTP_BIND_PORT_DEFAULT = 9878;
|
||||||
|
public static final int OZONE_S3G_HTTPS_BIND_PORT_DEFAULT = 9879;
|
||||||
|
public static final String OZONE_S3G_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL =
|
||||||
|
"ozone.s3g.authentication.kerberos.principal";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Never constructed.
|
||||||
|
*/
|
||||||
|
private S3GatewayConfigKeys() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.hdds.server.BaseHttpServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* S3 Gateway specific configuration keys.
|
||||||
|
*/
|
||||||
|
public class S3GatewayHttpServer extends BaseHttpServer {
|
||||||
|
|
||||||
|
public S3GatewayHttpServer(Configuration conf,
|
||||||
|
String name) throws IOException {
|
||||||
|
super(conf, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getHttpAddressKey() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTP_ADDRESS_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getHttpBindHostKey() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTP_BIND_HOST_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getHttpsAddressKey() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTPS_ADDRESS_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getHttpsBindHostKey() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTPS_BIND_HOST_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getBindHostDefault() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTP_BIND_HOST_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getHttpBindPortDefault() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTP_BIND_PORT_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getHttpsBindPortDefault() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTPS_BIND_PORT_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getKeytabFile() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_KEYTAB_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getSpnegoPrincipal() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getEnabledKey() {
|
||||||
|
return S3GatewayConfigKeys.OZONE_S3G_HTTP_ENABLED_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.bucket;
|
||||||
|
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.s3.EndpointBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a bucket.
|
||||||
|
*/
|
||||||
|
@Path("/{volume}/{bucket}")
|
||||||
|
public class DeleteBucket extends EndpointBase {
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Produces(MediaType.APPLICATION_XML)
|
||||||
|
public void put(
|
||||||
|
@PathParam("volume") String volumeName,
|
||||||
|
@PathParam("bucket") String bucketName) throws IOException {
|
||||||
|
|
||||||
|
getVolume(volumeName).deleteBucket(bucketName);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.bucket;
|
||||||
|
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.s3.EndpointBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new bucket.
|
||||||
|
*/
|
||||||
|
@Path("/{volume}/{bucket}")
|
||||||
|
public class PutBucket extends EndpointBase {
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Produces(MediaType.APPLICATION_XML)
|
||||||
|
public void put(
|
||||||
|
@PathParam("volume") String volumeName,
|
||||||
|
@PathParam("bucket") String bucketName) throws IOException {
|
||||||
|
|
||||||
|
getVolume(volumeName).createBucket(bucketName);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rest endpoint implementation for the bucket specific methods.
|
||||||
|
*/
|
||||||
|
@javax.xml.bind.annotation.XmlSchema(
|
||||||
|
namespace = "http://s3.amazonaws"
|
||||||
|
+ ".com/doc/2006-03-01/", elementFormDefault =
|
||||||
|
javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
|
||||||
|
xmlns = {
|
||||||
|
@javax.xml.bind.annotation.XmlNs(namespaceURI = "http://s3.amazonaws"
|
||||||
|
+ ".com/doc/2006-03-01/", prefix = "")})
|
||||||
|
|
||||||
|
package org.apache.hadoop.ozone.s3.bucket;
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.commontypes;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory name ("key prefix") in case of listing.
|
||||||
|
*/
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class CommonPrefix {
|
||||||
|
|
||||||
|
@XmlElement(name = "Prefix")
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
public CommonPrefix(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommonPrefix() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrefix(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.commontypes;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A converter to convert Instant to standard date string.
|
||||||
|
*/
|
||||||
|
public class IsoDateAdapter extends XmlAdapter<String, Instant> {
|
||||||
|
|
||||||
|
private DateTimeFormatter iso8861Formatter;
|
||||||
|
|
||||||
|
public IsoDateAdapter() {
|
||||||
|
iso8861Formatter =
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
|
||||||
|
.withZone(ZoneOffset.UTC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Instant unmarshal(String v) throws Exception {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String marshal(Instant v) throws Exception {
|
||||||
|
return iso8861Formatter.format(v);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.commontypes;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata object represents one key in the object store.
|
||||||
|
*/
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class KeyMetadata {
|
||||||
|
|
||||||
|
@XmlElement(name = "Key")
|
||||||
|
private String key; // or the Object Name
|
||||||
|
|
||||||
|
@XmlJavaTypeAdapter(IsoDateAdapter.class)
|
||||||
|
@XmlElement(name = "LastModified")
|
||||||
|
private Instant lastModified;
|
||||||
|
|
||||||
|
@XmlElement(name = "ETag")
|
||||||
|
private String eTag;
|
||||||
|
|
||||||
|
@XmlElement(name = "Size")
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
@XmlElement(name = "StorageClass")
|
||||||
|
private String storageClass;
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getLastModified() {
|
||||||
|
return lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastModified(Instant lastModified) {
|
||||||
|
this.lastModified = lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getETag() {
|
||||||
|
return eTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setETag(String tag) {
|
||||||
|
this.eTag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStorageClass() {
|
||||||
|
return storageClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStorageClass(String storageClass) {
|
||||||
|
this.storageClass = storageClass;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common classes required for S3 rest API's.
|
||||||
|
*/
|
||||||
|
@javax.xml.bind.annotation.XmlSchema(
|
||||||
|
namespace = "http://s3.amazonaws"
|
||||||
|
+ ".com/doc/2006-03-01/", elementFormDefault =
|
||||||
|
javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
|
||||||
|
xmlns = {
|
||||||
|
@javax.xml.bind.annotation.XmlNs(namespaceURI = "http://s3.amazonaws"
|
||||||
|
+ ".com/doc/2006-03-01/", prefix = "")})
|
||||||
|
package org.apache.hadoop.ozone.s3.commontypes;
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.object;
|
||||||
|
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneBucket;
|
||||||
|
import org.apache.hadoop.ozone.s3.EndpointBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Object rest endpoint.
|
||||||
|
*/
|
||||||
|
@Path("/{volume}/{bucket}/{path:.+}")
|
||||||
|
public class DeleteObject extends EndpointBase {
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Produces(MediaType.APPLICATION_XML)
|
||||||
|
public Response delete(
|
||||||
|
@PathParam("volume") String volumeName,
|
||||||
|
@PathParam("bucket") String bucketName,
|
||||||
|
@PathParam("path") String keyPath) throws IOException {
|
||||||
|
|
||||||
|
OzoneBucket bucket = getBucket(volumeName, bucketName);
|
||||||
|
bucket.deleteKey(keyPath);
|
||||||
|
return Response.
|
||||||
|
ok()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.object;
|
||||||
|
|
||||||
|
import javax.ws.rs.HEAD;
|
||||||
|
import javax.ws.rs.HeaderParam;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneBucket;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneKeyDetails;
|
||||||
|
import org.apache.hadoop.ozone.s3.EndpointBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object info rest endpoint.
|
||||||
|
*/
|
||||||
|
@Path("/{volume}/{bucket}/{path:.+}")
|
||||||
|
public class HeadObject extends EndpointBase {
|
||||||
|
|
||||||
|
@HEAD
|
||||||
|
@Produces(MediaType.APPLICATION_XML)
|
||||||
|
public Response head(
|
||||||
|
@PathParam("volume") String volumeName,
|
||||||
|
@PathParam("bucket") String bucketName,
|
||||||
|
@PathParam("path") String keyPath,
|
||||||
|
@HeaderParam("Content-Length") long length,
|
||||||
|
InputStream body) throws IOException {
|
||||||
|
|
||||||
|
OzoneBucket bucket = getBucket(volumeName, bucketName);
|
||||||
|
OzoneKeyDetails key = bucket.getKey(keyPath);
|
||||||
|
|
||||||
|
return Response.
|
||||||
|
ok()
|
||||||
|
.header("Content-Length", key.getDataSize())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.object;
|
||||||
|
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneBucket;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneKey;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneVolume;
|
||||||
|
import org.apache.hadoop.ozone.s3.EndpointBase;
|
||||||
|
import org.apache.hadoop.ozone.s3.commontypes.KeyMetadata;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Object Rest endpoint.
|
||||||
|
*/
|
||||||
|
@Path("/{volume}/{bucket}")
|
||||||
|
public class ListObject extends EndpointBase {
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_XML)
|
||||||
|
public ListObjectResponse get(
|
||||||
|
@PathParam("volume") String volumeName,
|
||||||
|
@PathParam("bucket") String bucketName,
|
||||||
|
@QueryParam("delimiter") String delimiter,
|
||||||
|
@QueryParam("encoding-type") String encodingType,
|
||||||
|
@QueryParam("marker") String marker,
|
||||||
|
@DefaultValue("1000") @QueryParam("max-keys") int maxKeys,
|
||||||
|
@QueryParam("prefix") String prefix,
|
||||||
|
@Context HttpHeaders hh) throws IOException {
|
||||||
|
|
||||||
|
if (delimiter == null) {
|
||||||
|
delimiter = "/";
|
||||||
|
}
|
||||||
|
if (prefix == null) {
|
||||||
|
prefix = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
OzoneVolume volume = getVolume(volumeName);
|
||||||
|
OzoneBucket bucket = getBucket(volume, bucketName);
|
||||||
|
|
||||||
|
Iterator<? extends OzoneKey> ozoneKeyIterator = bucket.listKeys(prefix);
|
||||||
|
|
||||||
|
ListObjectResponse response = new ListObjectResponse();
|
||||||
|
response.setDelimiter(delimiter);
|
||||||
|
response.setName(bucketName);
|
||||||
|
response.setPrefix(prefix);
|
||||||
|
response.setMarker("");
|
||||||
|
response.setMaxKeys(1000);
|
||||||
|
response.setEncodingType("url");
|
||||||
|
response.setTruncated(false);
|
||||||
|
|
||||||
|
String prevDir = null;
|
||||||
|
while (ozoneKeyIterator.hasNext()) {
|
||||||
|
OzoneKey next = ozoneKeyIterator.next();
|
||||||
|
String relativeKeyName = next.getName().substring(prefix.length());
|
||||||
|
|
||||||
|
int depth =
|
||||||
|
StringUtils.countMatches(relativeKeyName, delimiter);
|
||||||
|
|
||||||
|
if (prefix.length() > 0 && !prefix.endsWith(delimiter)
|
||||||
|
&& relativeKeyName.length() > 0) {
|
||||||
|
response.addPrefix(prefix + "/");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (depth > 0) {
|
||||||
|
String dirName = relativeKeyName
|
||||||
|
.substring(0, relativeKeyName.indexOf(delimiter));
|
||||||
|
if (!dirName.equals(prevDir)) {
|
||||||
|
response.addPrefix(
|
||||||
|
prefix + dirName + delimiter);
|
||||||
|
prevDir = dirName;
|
||||||
|
}
|
||||||
|
} else if (relativeKeyName.endsWith(delimiter)) {
|
||||||
|
response.addPrefix(relativeKeyName);
|
||||||
|
} else if (relativeKeyName.length() > 0) {
|
||||||
|
KeyMetadata keyMetadata = new KeyMetadata();
|
||||||
|
keyMetadata.setKey(next.getName());
|
||||||
|
keyMetadata.setSize(next.getDataSize());
|
||||||
|
keyMetadata.setETag("" + next.getModificationTime());
|
||||||
|
keyMetadata.setStorageClass("STANDARD");
|
||||||
|
keyMetadata
|
||||||
|
.setLastModified(Instant.ofEpochMilli(next.getModificationTime()));
|
||||||
|
response.addKey(keyMetadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.object;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.s3.commontypes.CommonPrefix;
|
||||||
|
import org.apache.hadoop.ozone.s3.commontypes.KeyMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response from the ListObject RPC Call.
|
||||||
|
*/
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlRootElement(name = "ListBucketResult", namespace = "http://s3.amazonaws"
|
||||||
|
+ ".com/doc/2006-03-01/")
|
||||||
|
public class ListObjectResponse {
|
||||||
|
|
||||||
|
@XmlElement(name = "Name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XmlElement(name = "Prefix")
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
@XmlElement(name = "Marker")
|
||||||
|
private String marker;
|
||||||
|
|
||||||
|
@XmlElement(name = "MaxKeys")
|
||||||
|
private int maxKeys;
|
||||||
|
|
||||||
|
@XmlElement(name = "Delimiter")
|
||||||
|
private String delimiter = "/";
|
||||||
|
|
||||||
|
@XmlElement(name = "EncodingType")
|
||||||
|
private String encodingType = "url";
|
||||||
|
|
||||||
|
@XmlElement(name = "IsTruncated")
|
||||||
|
private boolean isTruncated;
|
||||||
|
|
||||||
|
@XmlElement(name = "Contents")
|
||||||
|
private List<KeyMetadata> contents = new ArrayList<>();
|
||||||
|
|
||||||
|
@XmlElement(name = "CommonPrefixes")
|
||||||
|
private List<CommonPrefix> commonPrefixes = new ArrayList<>();
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrefix(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMarker() {
|
||||||
|
return marker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMarker(String marker) {
|
||||||
|
this.marker = marker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxKeys() {
|
||||||
|
return maxKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxKeys(int maxKeys) {
|
||||||
|
this.maxKeys = maxKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDelimiter() {
|
||||||
|
return delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelimiter(String delimiter) {
|
||||||
|
this.delimiter = delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncodingType() {
|
||||||
|
return encodingType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncodingType(String encodingType) {
|
||||||
|
this.encodingType = encodingType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTruncated() {
|
||||||
|
return isTruncated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTruncated(boolean truncated) {
|
||||||
|
isTruncated = truncated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<KeyMetadata> getContents() {
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContents(
|
||||||
|
List<KeyMetadata> contents) {
|
||||||
|
this.contents = contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CommonPrefix> getCommonPrefixes() {
|
||||||
|
return commonPrefixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommonPrefixes(
|
||||||
|
List<CommonPrefix> commonPrefixes) {
|
||||||
|
this.commonPrefixes = commonPrefixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addKey(KeyMetadata keyMetadata) {
|
||||||
|
contents.add(keyMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPrefix(String relativeKeyName) {
|
||||||
|
commonPrefixes.add(new CommonPrefix(relativeKeyName));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.object;
|
||||||
|
|
||||||
|
import javax.ws.rs.HeaderParam;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.client.ReplicationFactor;
|
||||||
|
import org.apache.hadoop.hdds.client.ReplicationType;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneBucket;
|
||||||
|
import org.apache.hadoop.ozone.client.io.OzoneOutputStream;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.hadoop.ozone.s3.EndpointBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File upload.
|
||||||
|
*/
|
||||||
|
@Path("/{volume}/{bucket}/{path:.+}")
|
||||||
|
public class PutObject extends EndpointBase {
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Produces(MediaType.APPLICATION_XML)
|
||||||
|
public void put(
|
||||||
|
@PathParam("volume") String volumeName,
|
||||||
|
@PathParam("bucket") String bucketName,
|
||||||
|
@PathParam("path") String keyPath,
|
||||||
|
@HeaderParam("Content-Length") long length,
|
||||||
|
InputStream body) throws IOException {
|
||||||
|
|
||||||
|
OzoneBucket bucket = getBucket(volumeName, bucketName);
|
||||||
|
|
||||||
|
OzoneOutputStream output = bucket
|
||||||
|
.createKey(keyPath, length, ReplicationType.STAND_ALONE,
|
||||||
|
ReplicationFactor.ONE);
|
||||||
|
|
||||||
|
IOUtils.copy(body, output);
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rest endpoint implementation for the Object specific methods.
|
||||||
|
*/
|
||||||
|
@javax.xml.bind.annotation.XmlSchema(
|
||||||
|
namespace = "http://s3.amazonaws"
|
||||||
|
+ ".com/doc/2006-03-01/", elementFormDefault =
|
||||||
|
javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
|
||||||
|
xmlns = {
|
||||||
|
@javax.xml.bind.annotation.XmlNs(namespaceURI = "http://s3.amazonaws"
|
||||||
|
+ ".com/doc/2006-03-01/", prefix = "")})
|
||||||
|
package org.apache.hadoop.ozone.s3.object;
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This package contains the top level generic classes of s3 gateway.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.s3;
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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
|
||||||
|
|
||||||
|
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.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License. See accompanying LICENSE file.
|
||||||
|
-->
|
||||||
|
<beans xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://java.sun.com/xml/ns/javaee
|
||||||
|
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
|
||||||
|
</beans>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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
|
||||||
|
|
||||||
|
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.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License. See accompanying LICENSE file.
|
||||||
|
-->
|
||||||
|
<beans xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://java.sun.com/xml/ns/javaee
|
||||||
|
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
|
||||||
|
</beans>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!--
|
||||||
|
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
|
||||||
|
|
||||||
|
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.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License. See accompanying LICENSE file.
|
||||||
|
-->
|
||||||
|
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>jaxrs</servlet-name>
|
||||||
|
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>javax.ws.rs.Application</param-name>
|
||||||
|
<param-value>org.apache.hadoop.ozone.s3.GatewayApplication</param-value>
|
||||||
|
</init-param>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>jaxrs</servlet-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<listener>
|
||||||
|
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
|
||||||
|
</listener>
|
||||||
|
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ObjectStore implementation with in-memory state.
|
||||||
|
*/
|
||||||
|
public class ObjectStoreStub extends ObjectStore {
|
||||||
|
|
||||||
|
public ObjectStoreStub() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, OzoneVolumeStub> volumes = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createVolume(String volumeName) throws IOException {
|
||||||
|
createVolume(volumeName,
|
||||||
|
VolumeArgs.newBuilder()
|
||||||
|
.setAdmin("root")
|
||||||
|
.setOwner("root")
|
||||||
|
.setQuota("" + Integer.MAX_VALUE)
|
||||||
|
.setAcls(new ArrayList<>()).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createVolume(String volumeName, VolumeArgs volumeArgs)
|
||||||
|
throws IOException {
|
||||||
|
OzoneVolumeStub volume =
|
||||||
|
new OzoneVolumeStub(volumeName,
|
||||||
|
volumeArgs.getAdmin(),
|
||||||
|
volumeArgs.getOwner(),
|
||||||
|
Long.parseLong(volumeArgs.getQuota()),
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
volumeArgs.getAcls());
|
||||||
|
volumes.put(volumeName, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OzoneVolume getVolume(String volumeName) throws IOException {
|
||||||
|
if (volumes.containsKey(volumeName)) {
|
||||||
|
return volumes.get(volumeName);
|
||||||
|
} else {
|
||||||
|
throw new IOException("VOLUME_NOT_FOUND");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<? extends OzoneVolume> listVolumes(String volumePrefix)
|
||||||
|
throws IOException {
|
||||||
|
return volumes.values()
|
||||||
|
.stream()
|
||||||
|
.filter(volume -> volume.getName().startsWith(volumePrefix))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.iterator();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<? extends OzoneVolume> listVolumes(String volumePrefix,
|
||||||
|
String prevVolume) throws IOException {
|
||||||
|
return volumes.values()
|
||||||
|
.stream()
|
||||||
|
.filter(volume -> volume.getName().compareTo(prevVolume) > 0)
|
||||||
|
.filter(volume -> volume.getName().startsWith(volumePrefix))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<? extends OzoneVolume> listVolumesByUser(String user,
|
||||||
|
String volumePrefix, String prevVolume) throws IOException {
|
||||||
|
return volumes.values()
|
||||||
|
.stream()
|
||||||
|
.filter(volume -> volume.getOwner().equals(user))
|
||||||
|
.filter(volume -> volume.getName().compareTo(prevVolume) < 0)
|
||||||
|
.filter(volume -> volume.getName().startsWith(volumePrefix))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteVolume(String volumeName) throws IOException {
|
||||||
|
volumes.remove(volumeName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.client;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.hadoop.fs.StorageType;
|
||||||
|
import org.apache.hadoop.hdds.client.ReplicationFactor;
|
||||||
|
import org.apache.hadoop.hdds.client.ReplicationType;
|
||||||
|
import org.apache.hadoop.ozone.OzoneAcl;
|
||||||
|
import org.apache.hadoop.ozone.client.io.OzoneInputStream;
|
||||||
|
import org.apache.hadoop.ozone.client.io.OzoneOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In-memory ozone bucket for testing.
|
||||||
|
*/
|
||||||
|
public class OzoneBucketStub extends OzoneBucket {
|
||||||
|
|
||||||
|
private Map<String, OzoneKeyDetails> keyDetails = new HashMap<>();
|
||||||
|
|
||||||
|
private Map<String, byte[]> keyContents = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs OzoneBucket instance.
|
||||||
|
*
|
||||||
|
* @param volumeName Name of the volume the bucket belongs to.
|
||||||
|
* @param bucketName Name of the bucket.
|
||||||
|
* @param acls ACLs associated with the bucket.
|
||||||
|
* @param storageType StorageType of the bucket.
|
||||||
|
* @param versioning versioning status of the bucket.
|
||||||
|
* @param creationTime creation time of the bucket.
|
||||||
|
*/
|
||||||
|
public OzoneBucketStub(
|
||||||
|
String volumeName,
|
||||||
|
String bucketName,
|
||||||
|
List<OzoneAcl> acls,
|
||||||
|
StorageType storageType, Boolean versioning,
|
||||||
|
long creationTime) {
|
||||||
|
super(volumeName,
|
||||||
|
bucketName,
|
||||||
|
ReplicationFactor.ONE,
|
||||||
|
ReplicationType.STAND_ALONE,
|
||||||
|
acls,
|
||||||
|
storageType,
|
||||||
|
versioning,
|
||||||
|
creationTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OzoneOutputStream createKey(String key, long size) throws IOException {
|
||||||
|
return createKey(key, size, ReplicationType.STAND_ALONE,
|
||||||
|
ReplicationFactor.ONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OzoneOutputStream createKey(String key, long size,
|
||||||
|
ReplicationType type, ReplicationFactor factor) throws IOException {
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream =
|
||||||
|
new ByteArrayOutputStream((int) size) {
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
keyContents.put(key, toByteArray());
|
||||||
|
keyDetails.put(key, new OzoneKeyDetails(
|
||||||
|
getVolumeName(),
|
||||||
|
getName(),
|
||||||
|
key,
|
||||||
|
size,
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
new ArrayList<>()
|
||||||
|
));
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new OzoneOutputStream(byteArrayOutputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OzoneInputStream readKey(String key) throws IOException {
|
||||||
|
return new OzoneInputStream(new ByteArrayInputStream(keyContents.get(key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OzoneKeyDetails getKey(String key) throws IOException {
|
||||||
|
return keyDetails.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<? extends OzoneKey> listKeys(String keyPrefix) {
|
||||||
|
return keyDetails.values()
|
||||||
|
.stream()
|
||||||
|
.filter(key -> key.getName().startsWith(keyPrefix))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<? extends OzoneKey> listKeys(String keyPrefix,
|
||||||
|
String prevKey) {
|
||||||
|
return keyDetails.values()
|
||||||
|
.stream()
|
||||||
|
.filter(key -> key.getName().compareTo(prevKey) > 0)
|
||||||
|
.filter(key -> key.getName().startsWith(keyPrefix))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteKey(String key) throws IOException {
|
||||||
|
keyDetails.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renameKey(String fromKeyName, String toKeyName)
|
||||||
|
throws IOException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In-memory OzoneClient for testing.
|
||||||
|
*/
|
||||||
|
public class OzoneClientStub extends OzoneClient {
|
||||||
|
|
||||||
|
public OzoneClientStub() {
|
||||||
|
super(new ObjectStoreStub());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
//NOOP.
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.hadoop.fs.StorageType;
|
||||||
|
import org.apache.hadoop.ozone.OzoneAcl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ozone volume with in-memory state for testing.
|
||||||
|
*/
|
||||||
|
public class OzoneVolumeStub extends OzoneVolume {
|
||||||
|
|
||||||
|
private Map<String, OzoneBucketStub> buckets = new HashMap<>();
|
||||||
|
|
||||||
|
public OzoneVolumeStub(String name, String admin, String owner,
|
||||||
|
long quotaInBytes,
|
||||||
|
long creationTime, List<OzoneAcl> acls) {
|
||||||
|
super(name, admin, owner, quotaInBytes, creationTime, acls);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createBucket(String bucketName) throws IOException {
|
||||||
|
createBucket(bucketName, new BucketArgs.Builder()
|
||||||
|
.setStorageType(StorageType.DEFAULT)
|
||||||
|
.setVersioning(false)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createBucket(String bucketName, BucketArgs bucketArgs)
|
||||||
|
throws IOException {
|
||||||
|
buckets.put(bucketName, new OzoneBucketStub(
|
||||||
|
getName(),
|
||||||
|
bucketName,
|
||||||
|
bucketArgs.getAcls(),
|
||||||
|
bucketArgs.getStorageType(),
|
||||||
|
bucketArgs.getVersioning(),
|
||||||
|
System.currentTimeMillis()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OzoneBucket getBucket(String bucketName) throws IOException {
|
||||||
|
return buckets.get(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<? extends OzoneBucket> listBuckets(String bucketPrefix) {
|
||||||
|
return buckets.values()
|
||||||
|
.stream()
|
||||||
|
.filter(bucket -> bucket.getName().startsWith(bucketPrefix))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<? extends OzoneBucket> listBuckets(String bucketPrefix,
|
||||||
|
String prevBucket) {
|
||||||
|
return buckets.values()
|
||||||
|
.stream()
|
||||||
|
.filter(bucket -> bucket.getName().compareTo(prevBucket) > 0)
|
||||||
|
.filter(bucket -> bucket.getName().startsWith(bucketPrefix))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteBucket(String bucketName) throws IOException {
|
||||||
|
buckets.remove(bucketName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* In-memory OzoneClient implementation to test REST endpoints.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.client;
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.bucket;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.s3.object.ListObjectResponse;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing JAXB serialization.
|
||||||
|
*/
|
||||||
|
public class TestBucketResponse {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serialize() throws JAXBException {
|
||||||
|
JAXBContext context = JAXBContext.newInstance(ListObjectResponse.class);
|
||||||
|
context.createMarshaller().marshal(new ListObjectResponse(), System.out);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.bucket;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneBucket;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneClient;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneClientStub;
|
||||||
|
import org.apache.hadoop.ozone.s3.object.ListObject;
|
||||||
|
import org.apache.hadoop.ozone.s3.object.ListObjectResponse;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing basic object list browsing.
|
||||||
|
*/
|
||||||
|
public class TestGetBucket {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listRoot() throws IOException {
|
||||||
|
|
||||||
|
ListObject getBucket = new ListObject();
|
||||||
|
|
||||||
|
OzoneClient client = createClientWithKeys("file1", "dir1/file2");
|
||||||
|
|
||||||
|
getBucket.setClient(client);
|
||||||
|
|
||||||
|
ListObjectResponse getBucketResponse =
|
||||||
|
getBucket.get("vol1", "b1", "/", null, null, 100, "", null);
|
||||||
|
|
||||||
|
Assert.assertEquals(1, getBucketResponse.getCommonPrefixes().size());
|
||||||
|
Assert.assertEquals("dir1/",
|
||||||
|
getBucketResponse.getCommonPrefixes().get(0).getPrefix());
|
||||||
|
|
||||||
|
Assert.assertEquals(1, getBucketResponse.getContents().size());
|
||||||
|
Assert.assertEquals("file1",
|
||||||
|
getBucketResponse.getContents().get(0).getKey());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listDir() throws IOException {
|
||||||
|
|
||||||
|
ListObject getBucket = new ListObject();
|
||||||
|
|
||||||
|
OzoneClient client = createClientWithKeys("dir1/file2", "dir1/dir2/file2");
|
||||||
|
|
||||||
|
getBucket.setClient(client);
|
||||||
|
|
||||||
|
ListObjectResponse getBucketResponse =
|
||||||
|
getBucket.get("vol1", "b1", "/", null, null, 100, "dir1", null);
|
||||||
|
|
||||||
|
Assert.assertEquals(1, getBucketResponse.getCommonPrefixes().size());
|
||||||
|
Assert.assertEquals("dir1/",
|
||||||
|
getBucketResponse.getCommonPrefixes().get(0).getPrefix());
|
||||||
|
|
||||||
|
Assert.assertEquals(0, getBucketResponse.getContents().size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listSubDir() throws IOException {
|
||||||
|
|
||||||
|
ListObject getBucket = new ListObject();
|
||||||
|
OzoneClient ozoneClient =
|
||||||
|
createClientWithKeys("dir1/file2", "dir1/dir2/file2");
|
||||||
|
|
||||||
|
getBucket.setClient(ozoneClient);
|
||||||
|
|
||||||
|
ListObjectResponse getBucketResponse =
|
||||||
|
getBucket.get("vol1", "b1", "/", null, null, 100, "dir1/", null);
|
||||||
|
|
||||||
|
Assert.assertEquals(1, getBucketResponse.getCommonPrefixes().size());
|
||||||
|
Assert.assertEquals("dir1/dir2/",
|
||||||
|
getBucketResponse.getCommonPrefixes().get(0).getPrefix());
|
||||||
|
|
||||||
|
Assert.assertEquals(1, getBucketResponse.getContents().size());
|
||||||
|
Assert.assertEquals("dir1/file2",
|
||||||
|
getBucketResponse.getContents().get(0).getKey());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private OzoneClient createClientWithKeys(String... keys) throws IOException {
|
||||||
|
OzoneClient client = new OzoneClientStub();
|
||||||
|
client.getObjectStore().createVolume("vol1");
|
||||||
|
client.getObjectStore().getVolume("vol1").createBucket("b1");
|
||||||
|
OzoneBucket bucket =
|
||||||
|
client.getObjectStore().getVolume("vol1").getBucket("b1");
|
||||||
|
for (String key : keys) {
|
||||||
|
bucket.createKey(key, 0).close();
|
||||||
|
}
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Unit tests for the bucket related rest endpoints.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.s3.bucket;
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.apache.hadoop.ozone.s3.object;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneBucket;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneClient;
|
||||||
|
import org.apache.hadoop.ozone.client.OzoneClientStub;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test delete object.
|
||||||
|
*/
|
||||||
|
public class TestDeleteObject {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void delete() throws IOException {
|
||||||
|
//GIVEN
|
||||||
|
OzoneClient client = new OzoneClientStub();
|
||||||
|
client.getObjectStore().createVolume("vol1");
|
||||||
|
client.getObjectStore().getVolume("vol1").createBucket("b1");
|
||||||
|
OzoneBucket bucket =
|
||||||
|
client.getObjectStore().getVolume("vol1").getBucket("b1");
|
||||||
|
bucket.createKey("key1", 0).close();
|
||||||
|
|
||||||
|
DeleteObject rest = new DeleteObject();
|
||||||
|
rest.setClient(client);
|
||||||
|
|
||||||
|
//WHEN
|
||||||
|
rest.delete("vol1", "b1", "key1");
|
||||||
|
|
||||||
|
//THEN
|
||||||
|
Assert.assertFalse("Bucket Should not contain any key after delete",
|
||||||
|
bucket.listKeys("").hasNext());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Unit tests for the object related rest endpoints.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.s3.object;
|
Loading…
Reference in New Issue