Issue 23: added bucket logging

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2548 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-12-30 21:58:15 +00:00
parent bfd9fa8d53
commit 1e0e63ddd2
15 changed files with 819 additions and 1 deletions

View File

@ -37,9 +37,12 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.aws.s3.binders.BindACLToXMLPayload;
import org.jclouds.aws.s3.binders.BindBucketLoggingToXmlPayload;
import org.jclouds.aws.s3.binders.BindNoBucketLoggingToXmlPayload;
import org.jclouds.aws.s3.binders.BindPayerToXmlPayload;
import org.jclouds.aws.s3.binders.BindS3ObjectToPayload;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
@ -57,6 +60,7 @@ import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.aws.s3.options.PutBucketOptions;
import org.jclouds.aws.s3.options.PutObjectOptions;
import org.jclouds.aws.s3.xml.AccessControlListHandler;
import org.jclouds.aws.s3.xml.BucketLoggingHandler;
import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
@ -268,4 +272,32 @@ public interface S3AsyncClient {
Future<Boolean> putObjectACL(@HostPrefixParam String bucketName, @PathParam("key") String key,
@BinderParam(BindACLToXMLPayload.class) AccessControlList acl);
/**
* @see S3Client#getBucketLogging
*/
@GET
@QueryParams(keys = "logging")
@XMLResponseParser(BucketLoggingHandler.class)
@ExceptionParser(ThrowContainerNotFoundOn404.class)
@Path("/")
Future<BucketLogging> getBucketLogging(@HostPrefixParam String bucketName);
/**
* @see S3Client#enableBucketLogging
*/
@PUT
@Path("/")
@QueryParams(keys = "logging")
Future<Void> enableBucketLogging(@HostPrefixParam String bucketName,
@BinderParam(BindBucketLoggingToXmlPayload.class) BucketLogging logging);
/**
* @see S3Client#putBucketLogging
*/
@PUT
@Path("/")
@QueryParams(keys = "logging")
Future<Void> disableBucketLogging(
@BinderParam(BindNoBucketLoggingToXmlPayload.class) @HostPrefixParam String bucketName);
}

View File

@ -29,6 +29,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
@ -388,4 +389,40 @@ public interface S3Client {
* />
*/
void setBucketPayer(String bucketName, Payer payer);
/**
* Inspects the logging status for a bucket.
*
*
* @param bucketName
* the bucket you wish to know the logging status
* @return bucketLogging configuration or null, if not configured
*
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html"
* />
*/
BucketLogging getBucketLogging(String bucketName);
/**
* Enables logging for a bucket.
*
* @param bucketName
* the bucket you wish to enable logging for
* @param logging
* configuration including destination, prefix, and access rules
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html"
* />
*/
void enableBucketLogging(String bucketName, BucketLogging logging);
/**
* Disables logging for a bucket.
*
* @param bucketName
* the bucket you wish to disable logging for
*
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html"
* />
*/
void disableBucketLogging(String bucketName);
}

View File

@ -42,6 +42,10 @@ import org.jclouds.util.Utils;
import com.jamesmurty.utils.XMLBuilder;
/**
*
* @author James Murty
*/
public class BindACLToXMLPayload implements Binder {
public void bindToRequest(HttpRequest request, Object payload) {

View File

@ -0,0 +1,97 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.jclouds.aws.s3.binders;
import java.util.Properties;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.AccessControlList.CanonicalUserGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.AccessControlList.GroupGrantee;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
import org.jclouds.util.Utils;
import com.jamesmurty.utils.XMLBuilder;
/**
*
* @author Adrian Cole
*/
public class BindBucketLoggingToXmlPayload implements Binder {
public void bindToRequest(HttpRequest request, Object payload) {
BucketLogging from = (BucketLogging) payload;
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
try {
String stringPayload = generateBuilder(from).asString(outputProperties);
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_XML);
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringPayload.getBytes().length + "");
request.setPayload(stringPayload);
} catch (Exception e) {
Utils.rethrowIfRuntime(e);
throw new RuntimeException("error transforming bucketLogging: " + from, e);
}
}
protected XMLBuilder generateBuilder(BucketLogging bucketLogging)
throws ParserConfigurationException, FactoryConfigurationError {
XMLBuilder rootBuilder = XMLBuilder.create("BucketLoggingStatus").attr("xmlns",
S3Constants.S3_REST_API_XML_NAMESPACE).e("LoggingEnabled");
rootBuilder.e("TargetBucket").t(bucketLogging.getTargetBucket());
rootBuilder.e("TargetPrefix").t(bucketLogging.getTargetPrefix());
XMLBuilder grantsBuilder = rootBuilder.elem("TargetGrants");
for (Grant grant : bucketLogging.getTargetGrants()) {
XMLBuilder grantBuilder = grantsBuilder.elem("Grant");
XMLBuilder granteeBuilder = grantBuilder.elem("Grantee").attr("xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
if (grant.getGrantee() instanceof GroupGrantee) {
granteeBuilder.attr("xsi:type", "Group").elem("URI").text(
grant.getGrantee().getIdentifier());
} else if (grant.getGrantee() instanceof CanonicalUserGrantee) {
CanonicalUserGrantee grantee = (CanonicalUserGrantee) grant.getGrantee();
granteeBuilder.attr("xsi:type", "CanonicalUser").elem("ID").text(
grantee.getIdentifier()).up();
if (grantee.getDisplayName() != null) {
granteeBuilder.elem("DisplayName").text(grantee.getDisplayName());
}
} else if (grant.getGrantee() instanceof EmailAddressGrantee) {
granteeBuilder.attr("xsi:type", "AmazonCustomerByEmail").elem("EmailAddress").text(
grant.getGrantee().getIdentifier());
}
grantBuilder.elem("Permission").text(grant.getPermission().toString());
}
return grantsBuilder;
}
}

View File

@ -0,0 +1,45 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.jclouds.aws.s3.binders;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
*
* @author Adrian Cole
*/
public class BindNoBucketLoggingToXmlPayload implements Binder {
public void bindToRequest(HttpRequest request, Object payload) {
String stringPayload = "<BucketLoggingStatus xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"/>";
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_XML);
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, stringPayload.getBytes().length + "");
request.setPayload(stringPayload);
}
}

View File

@ -302,6 +302,37 @@ public class AccessControlList {
return myGranteeAndPermission.compareTo(otherGranteeAndPermission);
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((grantee == null) ? 0 : grantee.hashCode());
result = prime * result + ((permission == null) ? 0 : permission.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Grant other = (Grant) obj;
if (grantee == null) {
if (other.grantee != null)
return false;
} else if (!grantee.equals(other.grantee))
return false;
if (permission == null) {
if (other.permission != null)
return false;
} else if (!permission.equals(other.permission))
return false;
return true;
}
}
public abstract static class Grantee implements Comparable<Grantee> {
@ -327,6 +358,31 @@ public class AccessControlList {
public int compareTo(org.jclouds.aws.s3.domain.AccessControlList.Grantee o) {
return (this == o) ? 0 : getIdentifier().compareTo(o.getIdentifier());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Grantee other = (Grantee) obj;
if (identifier == null) {
if (other.identifier != null)
return false;
} else if (!identifier.equals(other.identifier))
return false;
return true;
}
}
public static class EmailAddressGrantee extends Grantee {

View File

@ -0,0 +1,149 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.jclouds.aws.s3.domain;
import java.util.Set;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* Each Amazon S3 bucket has an associated XML sub-resource that you can read and write in order to
* inspect or change the logging status for that bucket.
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html"/>
*/
public class BucketLogging {
private final String targetBucket;
private final String targetPrefix;
private final Set<Grant> targetGrants = Sets.newHashSet();
/**
*
* @param targetBucket
* {@link #getTargetBucket}
* @param targetPrefix
* {@link #getTargetPrefix}
* @param targetGrants
* {@link #getTargetGrants}
*/
public BucketLogging(String targetBucket, String targetPrefix, Iterable<Grant> targetGrants) {
this.targetBucket = targetBucket;
this.targetPrefix = targetPrefix;
Iterables.addAll(this.targetGrants, targetGrants);
}
/**
*
* @param targetBucket
* {@link #getTargetBucket}
* @param targetPrefix
* {@link #getTargetPrefix}
*/
public BucketLogging(String targetBucket, String targetPrefix) {
this.targetBucket = targetBucket;
this.targetPrefix = targetPrefix;
}
/**
* The bucket owner is automatically granted FULL_CONTROL to all logs delivered to the bucket.
* This optional element enables you grant access to others. Any specified TargetGrants are added
* to the default ACL. For more information about ACLs, see Access Control Lists.
*/
public Set<Grant> getTargetGrants() {
return targetGrants;
}
/**
* Specifies the bucket where server access logs will be delivered. You can have your logs
* delivered to any bucket that you own, including the same bucket that is being logged. You can
* also configure multiple buckets to deliver their logs to the same target bucket. In this case
* you should choose a different TargetPrefix for each source bucket so that the delivered log
* files can be distinguished by key.
* <p/>
* <h3>Note</h3>
*
* The source and the target buckets must be in the same location. For more information about
* bucket location constraints, see Buckets and Regions
*/
public String getTargetBucket() {
return targetBucket;
}
/**
* This element lets you specify a prefix for the keys that the delivered log files will be
* stored under. For information on how the key name for log files is constructed, see Delivery
* of Server Access Logs.
*/
public String getTargetPrefix() {
return targetPrefix;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((targetBucket == null) ? 0 : targetBucket.hashCode());
result = prime * result + ((targetGrants == null) ? 0 : targetGrants.hashCode());
result = prime * result + ((targetPrefix == null) ? 0 : targetPrefix.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BucketLogging other = (BucketLogging) obj;
if (targetBucket == null) {
if (other.targetBucket != null)
return false;
} else if (!targetBucket.equals(other.targetBucket))
return false;
if (targetGrants == null) {
if (other.targetGrants != null)
return false;
} else if (!targetGrants.equals(other.targetGrants))
return false;
if (targetPrefix == null) {
if (other.targetPrefix != null)
return false;
} else if (!targetPrefix.equals(other.targetPrefix))
return false;
return true;
}
@Override
public String toString() {
return "BucketLogging [targetBucket=" + targetBucket + ", targetGrants=" + targetGrants
+ ", targetPrefix=" + targetPrefix + "]";
}
}

View File

@ -0,0 +1,102 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.jclouds.aws.s3.xml;
import java.util.Set;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.AccessControlList.CanonicalUserGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.AccessControlList.Grantee;
import org.jclouds.aws.s3.domain.AccessControlList.GroupGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.GroupGranteeURI;
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
import com.google.common.collect.Sets;
/**
* Parses the following XML document:
* <p/>
* BucketLoggingStatus xmlns="http://s3.amazonaws.com/doc/2006-03-01/"
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html"/>
*/
public class BucketLoggingHandler extends ParseSax.HandlerWithResult<BucketLogging> {
private Set<Grant> targetGrants = Sets.newHashSet();
private StringBuilder currentText = new StringBuilder();
public BucketLogging getResult() {
if (targetBucket == null)
return null;
return new BucketLogging(targetBucket, targetPrefix, targetGrants);
}
private String currentId;
private String currentDisplayName;
private String currentGranteeType;
private String currentPermission;
private Grantee currentGrantee;
private String targetBucket;
private String targetPrefix;
public void startElement(String uri, String name, String qName, Attributes attrs) {
if (qName.equals("Grantee")) {
currentGranteeType = attrs.getValue("xsi:type");
}
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("TargetBucket")) {
this.targetBucket = currentText.toString().trim();
} else if (qName.equals("TargetPrefix")) {
this.targetPrefix = currentText.toString().trim();
} else if (qName.equals("Grantee")) {
if ("AmazonCustomerByEmail".equals(currentGranteeType)) {
currentGrantee = new EmailAddressGrantee(currentId);
} else if ("CanonicalUser".equals(currentGranteeType)) {
currentGrantee = new CanonicalUserGrantee(currentId, currentDisplayName);
} else if ("Group".equals(currentGranteeType)) {
currentGrantee = new GroupGrantee(GroupGranteeURI.fromURI(currentId));
}
} else if (qName.equals("Grant")) {
targetGrants.add(new Grant(currentGrantee, Permission.valueOf(currentPermission)));
} else if (qName.equals("ID") || qName.equals("EmailAddress") || qName.equals("URI")) {
currentId = currentText.toString().trim();
} else if (qName.equals("DisplayName")) {
currentDisplayName = currentText.toString().trim();
} else if (qName.equals("Permission")) {
currentPermission = currentText.toString().trim();
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -33,9 +33,13 @@ import java.net.URI;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
import org.jclouds.aws.s3.config.S3ObjectModule;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.domain.Payer;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
@ -47,6 +51,7 @@ import org.jclouds.aws.s3.options.PutBucketOptions;
import org.jclouds.aws.s3.options.PutObjectOptions;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.s3.xml.AccessControlListHandler;
import org.jclouds.aws.s3.xml.BucketLoggingHandler;
import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
@ -71,9 +76,11 @@ import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Jsr330;
import org.jclouds.util.Utils;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Provides;
@ -407,6 +414,60 @@ public class S3AsyncClientTest extends RestClientTest<S3AsyncClient> {
checkFilters(httpMethod);
}
public void testGetBucketLogging() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3AsyncClient.class.getMethod("getBucketLogging", String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/?logging HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
assertPayloadEquals(httpMethod, null);
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
assertSaxResponseParserClassEquals(method, BucketLoggingHandler.class);
assertExceptionParserClassEquals(method, ThrowContainerNotFoundOn404.class);
checkFilters(httpMethod);
}
public void testDisableBucketLogging() throws SecurityException, NoSuchMethodException,
IOException {
Method method = S3AsyncClient.class.getMethod("disableBucketLogging", String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/?logging HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 70\nContent-Type: text/xml\nHost: bucket.stub\n");
assertPayloadEquals(httpMethod,
"<BucketLoggingStatus xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"/>");
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
public void testEnableBucketLoggingOwner() throws SecurityException, NoSuchMethodException,
IOException {
Method method = S3AsyncClient.class.getMethod("enableBucketLogging", String.class,
BucketLogging.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
new BucketLogging("mylogs", "access_log-", ImmutableSet.<Grant> of(new Grant(
new EmailAddressGrantee("adrian@jclouds.org"), Permission.FULL_CONTROL))));
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/?logging HTTP/1.1");
assertHeadersEqual(httpMethod,
"Content-Length: 433\nContent-Type: text/xml\nHost: bucket.stub\n");
assertPayloadEquals(httpMethod, Utils.toStringAndClose(getClass().getResourceAsStream(
"/s3/bucket_logging.xml")));
assertResponseParserClassEquals(method, httpMethod, ReturnVoidIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpMethod);
}
BlobToObject blobToS3Object;
@Override

View File

@ -0,0 +1,48 @@
package org.jclouds.aws.s3.binders;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import javax.ws.rs.core.HttpHeaders;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code BindBucketLoggingToXmlPayload}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.BindBucketLoggingToXmlPayloadTest")
public class BindBucketLoggingToXmlPayloadTest extends BaseHandlerTest {
public void testApplyInputStream() throws IOException {
BucketLogging bucketLogging = new BucketLogging("mylogs", "access_log-", ImmutableSet
.<Grant> of(new Grant(new EmailAddressGrantee("adrian@jclouds.org"),
Permission.FULL_CONTROL)));
String expected = Utils.toStringAndClose(getClass().getResourceAsStream(
"/s3/bucket_logging.xml"));
HttpRequest request = new HttpRequest("GET", URI.create("http://test"));
BindBucketLoggingToXmlPayload binder = injector
.getInstance(BindBucketLoggingToXmlPayload.class);
binder.bindToRequest(request, bucketLogging);
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE), "text/xml");
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), "433");
assertEquals(request.getPayload().getRawContent(), expected);
}
}

View File

@ -0,0 +1,35 @@
package org.jclouds.aws.s3.binders;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import javax.ws.rs.core.HttpHeaders;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code BindNoBucketLoggingToXmlPayload}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.BindNoBucketLoggingToXmlPayloadTest")
public class BindNoBucketLoggingToXmlPayloadTest extends BaseHandlerTest {
public void testApplyInputStream() throws IOException {
HttpRequest request = new HttpRequest("GET", URI.create("http://test"));
BindNoBucketLoggingToXmlPayload binder = injector
.getInstance(BindNoBucketLoggingToXmlPayload.class);
binder.bindToRequest(request, null);
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE), "text/xml");
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), "70");
assertEquals(request.getPayload().getRawContent(),
"<BucketLoggingStatus xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"/>");
}
}

View File

@ -43,6 +43,7 @@ import org.jclouds.aws.s3.blobstore.functions.BucketToContainerListOptions;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
import org.jclouds.aws.s3.blobstore.functions.ResourceToBucketList;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.domain.ListBucketResponse;
@ -363,4 +364,31 @@ public class StubS3AsyncClient implements S3AsyncClient {
};
}
@Override
public Future<Void> disableBucketLogging(String bucketName) {
return new FutureBase<Void>() {
public Void get() throws InterruptedException, ExecutionException {
return null;
}
};
}
@Override
public Future<Void> enableBucketLogging(String bucketName, BucketLogging logging) {
return new FutureBase<Void>() {
public Void get() throws InterruptedException, ExecutionException {
return null;
}
};
}
@Override
public Future<BucketLogging> getBucketLogging(String bucketName) {
return new FutureBase<BucketLogging>() {
public BucketLogging get() throws InterruptedException, ExecutionException {
return null;
}
};
}
}

View File

@ -30,7 +30,7 @@ import static org.jclouds.aws.s3.options.ListBucketOptions.Builder.withPrefix;
import static org.jclouds.aws.s3.options.PutBucketOptions.Builder.createIn;
import static org.jclouds.aws.s3.options.PutBucketOptions.Builder.withBucketAcl;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.*;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@ -43,6 +43,7 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
import org.jclouds.aws.s3.domain.ListBucketResponse;
@ -50,6 +51,7 @@ import org.jclouds.aws.s3.domain.Payer;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.AccessControlList.CanonicalUserGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.AccessControlList.GroupGranteeURI;
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
import org.jclouds.aws.s3.domain.BucketMetadata.LocationConstraint;
@ -58,6 +60,8 @@ import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
*
* @author James Murty
@ -213,6 +217,64 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient,
}
}
public void testBucketLogging() throws Exception {
final String bucketName = getContainerName();
final String targetBucket = getContainerName();
try {
assertNull(context.getApi().getBucketLogging(bucketName));
setupAclForBucketLoggingTarget(targetBucket);
final BucketLogging logging = new BucketLogging(targetBucket, "access_log-", ImmutableSet
.<Grant> of(new Grant(new EmailAddressGrantee(StubS3AsyncClient.TEST_ACL_EMAIL),
Permission.FULL_CONTROL)));
context.getApi().enableBucketLogging(bucketName, logging);
assertConsistencyAware(new Runnable() {
public void run() {
try {
BucketLogging newLogging = context.getApi().getBucketLogging(bucketName);
AccessControlList acl = new AccessControlList();
for (Grant grant : newLogging.getTargetGrants()) { // TODO: add permission
// checking features to
// bucketlogging
acl.addPermission(grant.getGrantee(), grant.getPermission());
}
// EmailAddressGrantee is replaced by a CanonicalUserGrantee, so we cannot test by
// email addr
assertTrue(acl.hasPermission(StubS3AsyncClient.TEST_ACL_ID,
Permission.FULL_CONTROL), acl.toString());
assertEquals(logging.getTargetBucket(), newLogging.getTargetBucket());
assertEquals(logging.getTargetPrefix(), newLogging.getTargetPrefix());
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
}
}
});
context.getApi().disableBucketLogging(bucketName);
assertConsistencyAware(new Runnable() {
public void run() {
try {
assertNull(context.getApi().getBucketLogging(bucketName));
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
}
}
});
} finally {
destroyContainer(bucketName);
destroyContainer(targetBucket);
}
}
private void setupAclForBucketLoggingTarget(final String targetBucket) {
// http://docs.amazonwebservices.com/AmazonS3/latest/LoggingHowTo.html
AccessControlList acl = context.getApi().getBucketACL(targetBucket);
acl.addPermission(GroupGranteeURI.LOG_DELIVERY, Permission.WRITE);
acl.addPermission(GroupGranteeURI.LOG_DELIVERY, Permission.READ_ACP);
assertTrue(context.getApi().putBucketACL(targetBucket, acl));
}
/**
* using scratch bucketName as we are changing location
*/

View File

@ -0,0 +1,61 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.jclouds.aws.s3.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.aws.s3.domain.BucketLogging;
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code BucketLoggingHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.BucketLoggingHandlerTest")
public class BucketLoggingHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/s3/bucket_logging.xml");
BucketLogging expected = new BucketLogging("mylogs", "access_log-", ImmutableSet
.<Grant> of(new Grant(new EmailAddressGrantee("adrian@jclouds.org"),
Permission.FULL_CONTROL)));
BucketLoggingHandler handler = injector.getInstance(BucketLoggingHandler.class);
BucketLogging result = factory.create(handler).parse(is);
assertEquals(result.getTargetBucket(), expected.getTargetBucket());
assertEquals(result.getTargetGrants(), expected.getTargetGrants());
assertEquals(result.getTargetPrefix(), expected.getTargetPrefix());
}
}

View File

@ -0,0 +1 @@
<BucketLoggingStatus xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><LoggingEnabled><TargetBucket>mylogs</TargetBucket><TargetPrefix>access_log-</TargetPrefix><TargetGrants><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AmazonCustomerByEmail"><EmailAddress>adrian@jclouds.org</EmailAddress></Grantee><Permission>FULL_CONTROL</Permission></Grant></TargetGrants></LoggingEnabled></BucketLoggingStatus>