mirror of https://github.com/apache/jclouds.git
Issue 352: added transient blob signing
This commit is contained in:
parent
d9820c536a
commit
0e5823afad
|
@ -265,7 +265,7 @@ in another application. ex. curl"
|
|||
(doto (.newBlob blobstore path)
|
||||
(.setPayload (doto
|
||||
;; until we pass content md5
|
||||
(PhantomPayload. size nil)
|
||||
(PhantomPayload. (long size) nil)
|
||||
(.setContentType content-type)))))))
|
||||
|
||||
(defn sign-blob-request
|
||||
|
@ -284,7 +284,7 @@ in another application. ex. curl"
|
|||
(.. blobstore getContext getSigner) container-name
|
||||
(doto (.newBlob blobstore path)
|
||||
(.setPayload
|
||||
(doto (PhantomPayload. content-length content-md5)
|
||||
(doto (PhantomPayload. (long content-length) content-md5)
|
||||
(.setContentType content-type))))))))
|
||||
|
||||
(defn get-blob-stream
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.blobstore;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class TransientBlobRequestSigner implements BlobRequestSigner {
|
||||
|
||||
private final BasicAuthentication basicAuth;
|
||||
|
||||
@Inject
|
||||
public TransientBlobRequestSigner(BasicAuthentication basicAuth) {
|
||||
this.basicAuth = checkNotNull(basicAuth, "basicAuth");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest signGetBlob(String container, String name) {
|
||||
HttpRequest request = new HttpRequest("GET", URI.create(String.format("http://localhost/%s/%s", container, name)));
|
||||
basicAuth.filter(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest signPutBlob(String container, Blob blob) {
|
||||
HttpRequest request = new HttpRequest("PUT", URI.create(String.format("http://localhost/%s/%s", container, blob
|
||||
.getMetadata().getName())));
|
||||
if (blob.getPayload().getContentLength() != null)
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, blob.getPayload().getContentLength().toString());
|
||||
if (blob.getPayload().getContentType() != null)
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, blob.getPayload().getContentType());
|
||||
if (blob.getPayload().getContentMD5() != null)
|
||||
request.getHeaders().put("Content-MD5", CryptoStreams.base64(blob.getPayload().getContentMD5()));
|
||||
request.setPayload(blob.getPayload());
|
||||
basicAuth.filter(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest signRemoveBlob(String container, String name) {
|
||||
HttpRequest request = new HttpRequest("DELETE", URI.create(String.format("http://localhost/%s/%s", container,
|
||||
name)));
|
||||
basicAuth.filter(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
|
@ -26,9 +26,11 @@ import java.util.concurrent.ConcurrentMap;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.blobstore.AsyncBlobStore;
|
||||
import org.jclouds.blobstore.BlobRequestSigner;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.TransientAsyncBlobStore;
|
||||
import org.jclouds.blobstore.TransientBlobRequestSigner;
|
||||
import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
|
@ -68,6 +70,7 @@ public class TransientBlobStoreContextModule extends AbstractModule {
|
|||
install(new BlobStoreObjectModule());
|
||||
install(new BlobStoreMapModule());
|
||||
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
|
||||
bind(BlobRequestSigner.class).to(TransientBlobRequestSigner.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
(download-blob container-name name data-file)))
|
||||
(finally (.delete data-file))))))
|
||||
|
||||
;; this will fail until transient provider handles signing
|
||||
;; this will fail until somebody fixes it!
|
||||
#_
|
||||
(deftest sing-put-blob-request-test
|
||||
(let [request (sign-put-blob-request "container" "path" "text/plain" 10)]
|
||||
|
@ -117,7 +117,7 @@
|
|||
(is (= "10" (get "Content-Length" (.getHeaders request))))
|
||||
(is (= "text/plain" (get "Content-Type" (.getHeaders request))))))
|
||||
|
||||
;; this will fail until transient provider handles signing
|
||||
;; this will fail until somebody fixes it!
|
||||
#_
|
||||
(deftest sing-blob-request-test
|
||||
(let [request (sign-blob-request "container" "path" {:method :delete})]
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.blobstore;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.io.payloads.PhantomPayload;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.rest.RestContextFactory.ContextSpec;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
@Test(groups = "unit", testName = "jclouds.TransientBlobRequestSignerTest")
|
||||
public class TransientBlobRequestSignerTest extends RestClientTest<TransientAsyncBlobStore> {
|
||||
|
||||
private BlobRequestSigner signer;
|
||||
private Factory blobFactory;
|
||||
|
||||
public void testSignGetBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
|
||||
NoSuchMethodException, IOException {
|
||||
HttpRequest request = signer.signGetBlob("container", "name");
|
||||
|
||||
assertRequestLineEquals(request, "GET http://localhost/container/name HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\n");
|
||||
assertPayloadEquals(request, null, null, false);
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
||||
public void testSignRemoveBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
|
||||
NoSuchMethodException, IOException {
|
||||
HttpRequest request = signer.signRemoveBlob("container", "name");
|
||||
|
||||
assertRequestLineEquals(request, "DELETE http://localhost/container/name HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\n");
|
||||
assertPayloadEquals(request, null, null, false);
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
||||
public void testSignPutBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
|
||||
NoSuchMethodException, IOException {
|
||||
Blob blob = blobFactory.create(null);
|
||||
blob.getMetadata().setName("name");
|
||||
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
assertRequestLineEquals(request, "PUT http://localhost/container/name HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\nContent-Length: 2\nContent-MD5: AAIECA==\nContent-Type: text/plain\n");
|
||||
assertContentHeadersEqual(request, "text/plain", (long) 2l, new byte[] { 0, 2, 4, 8 });
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
protected void setupFactory() throws IOException {
|
||||
super.setupFactory();
|
||||
this.blobFactory = injector.getInstance(Blob.Factory.class);
|
||||
this.signer = injector.getInstance(BlobRequestSigner.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkFilters(HttpRequest request) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextSpec<?, ?> createContextSpec() {
|
||||
return new RestContextFactory().createContextSpec("transient", "identity", "credential", new Properties());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<TransientAsyncBlobStore>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<TransientAsyncBlobStore>>() {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue