Skip to content

Commit

Permalink
v2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
arnett, stu committed Jul 2, 2015
1 parent 1f54120 commit 78b987e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 19 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ apply from: "$commonBuildDir/ecs-publish.gradle"

dependencies {
compile 'com.emc.ecs:smart-client:2.0.1',
'com.emc.ecs:object-transform:1.0.0',
'com.emc.ecs:object-transform:1.0.1',
'org.jdom:jdom2:2.0.5'
testCompile 'junit:junit:4.11'
}
35 changes: 25 additions & 10 deletions src/main/java/com/emc/object/s3/jersey/GeoPinningFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
package com.emc.object.s3.jersey;

import com.emc.object.ObjectConfig;
import com.emc.object.s3.S3Constants;
import com.emc.rest.smart.ecs.Vdc;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientRequest;
Expand All @@ -49,9 +50,19 @@ public GeoPinningFilter(ObjectConfig<?> objectConfig) {
this.objectConfig = objectConfig;
}

protected String getRequestGuid(ClientRequest cr) {
String key = cr.getURI().getPath();
/**
* If this is a bucket request, the bucket is the ID.
* If this is an object request, the key is the ID.
*/
protected String getGeoId(ClientRequest request, String bucketName) {
String key = request.getURI().getPath();

if (key == null) return bucketName;

if (key.startsWith("/")) key = key.substring(1);

if (key.length() == 0) return bucketName;

return key;
}

Expand All @@ -62,18 +73,22 @@ protected int getGeoPinIndex(String guid, int vdcCount) {
}

@Override
public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
List<Vdc> healthyVdcs = new ArrayList<Vdc>();
public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
// if there's no bucket, we don't need to pin the request (there's no write or read)
String bucketName = (String) request.getProperties().get(S3Constants.PROPERTY_BUCKET_NAME);
if (bucketName != null) {
List<Vdc> healthyVdcs = new ArrayList<Vdc>();

for (Vdc vdc : objectConfig.getVdcs()) {
if (vdc.isHealthy()) healthyVdcs.add(vdc);
}
for (Vdc vdc : objectConfig.getVdcs()) {
if (vdc.isHealthy()) healthyVdcs.add(vdc);
}

int geoPinIndex = getGeoPinIndex(getRequestGuid(cr), healthyVdcs.size());
int geoPinIndex = getGeoPinIndex(getGeoId(request, bucketName), healthyVdcs.size());

cr.getProperties().put(GeoPinningRule.PROP_GEO_PINNED_VDC, healthyVdcs.get(geoPinIndex));
request.getProperties().put(GeoPinningRule.PROP_GEO_PINNED_VDC, healthyVdcs.get(geoPinIndex));
}

return getNext().handle(cr);
return getNext().handle(request);
}

public ObjectConfig getObjectConfig() {
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/com/emc/object/s3/AbstractS3ClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public void dumpLBStats() {
}
}

@After
public void shutdownClient() {
if (client != null) client.shutdown();
}

@Override
protected void createBucket(String bucketName) throws Exception {
client.createBucket(bucketName);
Expand Down
57 changes: 51 additions & 6 deletions src/test/java/com/emc/object/s3/GeoPinningTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,19 @@ public void testGuidExtraction() throws Exception {
GeoPinningTestFilter filter = new GeoPinningTestFilter(s3Config);

Assert.assertEquals("my/object/key",
filter.getRequestGuid(new ClientRequestImpl(new URI("http://foo.s3.bar.com/my/object/key"), null)));
filter.getGeoId(new ClientRequestImpl(new URI("http://foo.s3.bar.com/my/object/key"), null), getTestBucket()));
Assert.assertEquals("/my/object/key",
filter.getRequestGuid(new ClientRequestImpl(new URI("http://foo.s3.bar.com//my/object/key"), null)));
filter.getGeoId(new ClientRequestImpl(new URI("http://foo.s3.bar.com//my/object/key"), null), getTestBucket()));
Assert.assertEquals("/my/object/key",
filter.getRequestGuid(new ClientRequestImpl(new URI("http://foo.s3.bar.com/%2Fmy/object/key"), null)));
filter.getGeoId(new ClientRequestImpl(new URI("http://foo.s3.bar.com/%2Fmy/object/key"), null), getTestBucket()));

String bucketName = getTestBucket();
Assert.assertEquals(bucketName,
filter.getGeoId(new ClientRequestImpl(new URI("http://foo.s3.bar.com"), null), bucketName));
Assert.assertEquals(bucketName,
filter.getGeoId(new ClientRequestImpl(new URI("http://foo.s3.bar.com/"), null), bucketName));
Assert.assertEquals(bucketName,
filter.getGeoId(new ClientRequestImpl(new URI("http://s3.bar.com/"), null), bucketName));
}

@Test
Expand Down Expand Up @@ -130,6 +138,13 @@ public void testVdcDistribution() {
testKeyDistribution(key1, hash1 % vdcs.size());
testKeyDistribution(key2, hash2 % vdcs.size());
testKeyDistribution(key3, hash3 % vdcs.size());

String bucket1 = "my-test-bucket", bucket2 = "foo-bar3baz", bucket3 = "test-bucket-12345-xxzz-blah";

int bHash1 = 0xc6c1ae, bHash2 = 0x2d4526, bHash3 = 0x9e3f48;
testBucketDistribution(bucket1, bHash1 % vdcs.size());
testBucketDistribution(bucket2, bHash2 % vdcs.size());
testBucketDistribution(bucket3, bHash3 % vdcs.size());
}

protected void testKeyDistribution(String key, int vdcIndex) {
Expand All @@ -146,7 +161,37 @@ protected void testKeyDistribution(String key, int vdcIndex) {
Assert.assertEquals(10, loadBalancer.getTotalConnections());

for (HostStats stats : loadBalancer.getHostStats()) {
if (vdcs.get(vdcIndex) == ((VdcHost) stats).getVdc()) {
if (vdcs.get(vdcIndex).equals(((VdcHost) stats).getVdc())) {
// all hosts in the appropriate VDC should have been used at least once
Assert.assertTrue(stats.getTotalConnections() > 0);
} else {
// hosts in other VDCs should *not* be used
Assert.assertEquals(0, stats.getTotalConnections());
}
}
}

protected void testBucketDistribution(String bucket, int vdcIndex) {
LoadBalancer loadBalancer = ((S3JerseyClient) client).getLoadBalancer();
loadBalancer.resetStats();

// make some requests to the bucket
int requestCount = 8;
client.createBucket(bucket);
client.getBucketAcl(bucket);
client.getBucketLocation(bucket);
client.getBucketLocation(bucket);
client.getBucketLocation(bucket);
client.getBucketLocation(bucket);
client.getBucketLocation(bucket);
client.deleteBucket(bucket);

// check no errors and total count
Assert.assertEquals(0, loadBalancer.getTotalErrors());
Assert.assertEquals(requestCount, loadBalancer.getTotalConnections());

for (HostStats stats : loadBalancer.getHostStats()) {
if (vdcs.get(vdcIndex).equals(((VdcHost) stats).getVdc())) {
// all hosts in the appropriate VDC should have been used at least once
Assert.assertTrue(stats.getTotalConnections() > 0);
} else {
Expand All @@ -162,8 +207,8 @@ public GeoPinningTestFilter(ObjectConfig<?> objectConfig) {
}

@Override
public String getRequestGuid(ClientRequest cr) {
return super.getRequestGuid(cr);
public String getGeoId(ClientRequest cr, String bucketName) {
return super.getGeoId(cr, bucketName);
}

@Override
Expand Down
2 changes: 0 additions & 2 deletions src/test/java/com/emc/object/s3/S3JerseyClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ public void testMultipleVdcs() throws Exception {

S3JerseyClient tempClient = new S3JerseyClient(config);

Thread.sleep(500); // wait for polling daemon to finish initial poll

Assert.assertTrue(vdc1.getHosts().size() > 1);
Assert.assertTrue(vdc2.getHosts().size() > 1);
Assert.assertEquals(vdc1.getHosts().size() + vdc2.getHosts().size(),
Expand Down

0 comments on commit 78b987e

Please sign in to comment.