From bffb8ea39fd16eb9c4ba39b7a624389f4e5b657d Mon Sep 17 00:00:00 2001 From: "Justin Yu (Microsoft)" Date: Tue, 6 Nov 2012 11:15:38 -0800 Subject: [PATCH 1/6] Add SendingRequestEvent in jxscl. --- .../core/storage/OperationContext.java | 25 ++++++++ .../core/storage/SendingRequestEvent.java | 63 +++++++++++++++++++ .../utils/implementation/ExecutionEngine.java | 10 +++ .../blob/client/CloudBlobContainerTests.java | 46 ++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java index 59106461ea272..9d6ce173b063f 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java @@ -53,6 +53,15 @@ public final class OperationContext { */ private ArrayList requestResults; + /** + * Represents an event that is triggered before sending a request. + * + * @see StorageEvent + * @see StorageEventMultiCaster + * @see SendingRequestEvent + */ + private StorageEventMultiCaster> sendingRequestEventHandler = new StorageEventMultiCaster>(); + /** * Represents an event that is triggered when a response is received from the storage service while processing a * request. @@ -156,6 +165,13 @@ public ArrayList getRequestResults() { return this.requestResults; } + /** + * @return the SendingRequestEvent + */ + public StorageEventMultiCaster> getSendingRequestEventHandler() { + return this.sendingRequestEventHandler; + } + /** * @return the responseReceivedEventHandler */ @@ -218,6 +234,15 @@ private void setLogger(final Logger logger) { this.logger = logger; } + /** + * @param sendingRequestEventHandler + * the sendingRequestEventHandler to set + */ + public void setSendingRequestEventHandler( + final StorageEventMultiCaster> sendingRequestEventHandler) { + this.sendingRequestEventHandler = sendingRequestEventHandler; + } + /** * @param responseReceivedEventHandler * the responseReceivedEventHandler to set diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java new file mode 100644 index 0000000000000..94efc9555634f --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java @@ -0,0 +1,63 @@ +/** + * Copyright 2011 Microsoft Corporation + * + * 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 com.microsoft.windowsazure.services.core.storage; + +/** + * Represents an event that is fired when before sending a request. + */ +public final class SendingRequestEvent { + + /** + * Represents a connection object. Currently only java.net.HttpURLConnection is supported as a + * connection object. + */ + private final Object connectionObject; + + /** + * Represents a context for the current operation. This object is used to track requests to the storage service, and + * to provide additional runtime information about the operation. + */ + private final OperationContext opContext; + + /** + * Creates an instance of the SendingRequestEvent class. + * + * @param opContext + * An {@link OperationContext} object that represents the context for the current operation. This object + * is used to track requests to the storage service, and to provide additional runtime information about + * the operation. + * @param connectionObject + * Represents a connection object. Currently only java.net.HttpURLConnection is supported as + * a connection object. + */ + public SendingRequestEvent(final OperationContext opContext, final Object connectionObject) { + this.opContext = opContext; + this.connectionObject = connectionObject; + } + + /** + * @return the connectionObject + */ + public Object getConnectionObject() { + return this.connectionObject; + } + + /** + * @return the opContext + */ + public OperationContext getOpContext() { + return this.opContext; + } +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/utils/implementation/ExecutionEngine.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/utils/implementation/ExecutionEngine.java index e30d5f1e45440..fd9ea785cffc5 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/utils/implementation/ExecutionEngine.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/utils/implementation/ExecutionEngine.java @@ -33,6 +33,7 @@ import com.microsoft.windowsazure.services.core.storage.RetryPolicy; import com.microsoft.windowsazure.services.core.storage.RetryPolicyFactory; import com.microsoft.windowsazure.services.core.storage.RetryResult; +import com.microsoft.windowsazure.services.core.storage.SendingRequestEvent; import com.microsoft.windowsazure.services.core.storage.StorageErrorCodeStrings; import com.microsoft.windowsazure.services.core.storage.StorageException; import com.microsoft.windowsazure.services.table.client.TableServiceException; @@ -223,6 +224,11 @@ public static InputStream getInputStream(final HttpURLConnection request, final opContext.setCurrentRequestObject(request); currResult.setStartDate(new Date()); opContext.getRequestResults().add(currResult); + + if (opContext.getSendingRequestEventHandler().hasListeners()) { + opContext.getSendingRequestEventHandler().fireEvent(new SendingRequestEvent(opContext, request)); + } + try { return request.getInputStream(); } @@ -295,6 +301,10 @@ public static RequestResult processRequest(final HttpURLConnection request, fina opContext.getRequestResults().add(currResult); opContext.setCurrentRequestObject(request); + if (opContext.getSendingRequestEventHandler().hasListeners()) { + opContext.getSendingRequestEventHandler().fireEvent(new SendingRequestEvent(opContext, request)); + } + // Send the request currResult.setStatusCode(request.getResponseCode()); currResult.setStatusMessage(request.getResponseMessage()); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java index d7602c93d75bc..658e878eb9cf9 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java @@ -38,8 +38,10 @@ import com.microsoft.windowsazure.services.core.storage.AccessCondition; import com.microsoft.windowsazure.services.core.storage.OperationContext; import com.microsoft.windowsazure.services.core.storage.ResultSegment; +import com.microsoft.windowsazure.services.core.storage.SendingRequestEvent; import com.microsoft.windowsazure.services.core.storage.StorageCredentialsSharedAccessSignature; import com.microsoft.windowsazure.services.core.storage.StorageErrorCodeStrings; +import com.microsoft.windowsazure.services.core.storage.StorageEvent; import com.microsoft.windowsazure.services.core.storage.StorageException; /** @@ -671,4 +673,48 @@ public void testListContainersTest() throws StorageException, URISyntaxException null); } } + + @Test + public void testSendingRequestEventBlob() throws StorageException, URISyntaxException, IOException, + InterruptedException { + String name = generateRandomContainerName(); + CloudBlobContainer newContainer = bClient.getContainerReference(name); + newContainer.create(); + + final ArrayList callList = new ArrayList(); + OperationContext sendingRequestEventContext = new OperationContext(); + sendingRequestEventContext.getSendingRequestEventHandler().addListener(new StorageEvent() { + + @Override + public void eventOccurred(SendingRequestEvent eventArg) { + callList.add(true); + } + }); + + try { + Assert.assertEquals(0, callList.size()); + + //Put blob + CloudBlob blob = newContainer.getBlockBlobReference("newblob"); + blob.upload(new ByteArrayInputStream(testData), testData.length, null, null, sendingRequestEventContext); + Assert.assertEquals(1, callList.size()); + + //Get blob + blob.download(new ByteArrayOutputStream(), null, null, sendingRequestEventContext); + Assert.assertEquals(2, callList.size()); + + //uploadMetadata + blob.uploadMetadata(null, null, sendingRequestEventContext); + Assert.assertEquals(3, callList.size()); + + //uploadMetadata + blob.downloadAttributes(null, null, sendingRequestEventContext); + Assert.assertEquals(4, callList.size()); + + } + finally { + // cleanup + newContainer.deleteIfExists(); + } + } } From 368210530a7eacd2406d9610fcfa517bd2609aba Mon Sep 17 00:00:00 2001 From: "Justin Yu (Microsoft)" Date: Tue, 6 Nov 2012 11:29:01 -0800 Subject: [PATCH 2/6] Update the useragent to 0.1.3.1 --- .../microsoft/windowsazure/services/core/storage/Constants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/Constants.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/Constants.java index 58e4d2bc8beca..61895ba9a162b 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/Constants.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/Constants.java @@ -327,7 +327,7 @@ public static class HeaderConstants { /** * Specifies the value to use for UserAgent header. */ - public static final String USER_AGENT_VERSION = "Client v0.1.3"; + public static final String USER_AGENT_VERSION = "Client v0.1.3.1"; } /** From d26abcd79f5491850d958c9ff2b93a9656aa3223 Mon Sep 17 00:00:00 2001 From: "Justin Yu (Microsoft)" Date: Wed, 7 Nov 2012 13:55:43 -0800 Subject: [PATCH 3/6] Change the file header from Copyright 2011 Microsoft Corporation and Copyright 2012 Microsoft Corporation --- .../windowsazure/services/core/storage/SendingRequestEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java index 94efc9555634f..2e86fbe6166d6 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java @@ -1,5 +1,5 @@ /** - * Copyright 2011 Microsoft Corporation + * Copyright 2012 Microsoft Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 7476d7dfdb1f55ce40f5ea3cf164ef103b94f82a Mon Sep 17 00:00:00 2001 From: "Justin Yu (Microsoft)" Date: Mon, 10 Dec 2012 15:05:18 -0800 Subject: [PATCH 4/6] CurrentOperationByteCount --- .../core/storage/OperationContext.java | 6 +-- .../blob/client/CloudBlobContainerTests.java | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java index 9d6ce173b063f..3a385289d1dd4 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/OperationContext.java @@ -92,7 +92,7 @@ public final class OperationContext { * Reserved for internal use. */ // Used internally for download resume. - private volatile int currentOperationByteCount; + private volatile long currentOperationByteCount; /** * Creates an instance of the OperationContext class. @@ -112,7 +112,7 @@ public long getClientTimeInMs() { /** * @return the currentOperationByteCount */ - public int getCurrentOperationByteCount() { + public long getCurrentOperationByteCount() { return this.currentOperationByteCount; } @@ -203,7 +203,7 @@ public void setClientTimeInMs(final long clientTimeInMs) { * @param currentOperationByteCount * the currentOperationByteCount to set */ - public void setCurrentOperationByteCount(final int currentOperationByteCount) { + public void setCurrentOperationByteCount(final long currentOperationByteCount) { this.currentOperationByteCount = currentOperationByteCount; } diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java index 658e878eb9cf9..1a360a6c62acf 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java @@ -38,6 +38,7 @@ import com.microsoft.windowsazure.services.core.storage.AccessCondition; import com.microsoft.windowsazure.services.core.storage.OperationContext; import com.microsoft.windowsazure.services.core.storage.ResultSegment; +import com.microsoft.windowsazure.services.core.storage.RetryNoRetry; import com.microsoft.windowsazure.services.core.storage.SendingRequestEvent; import com.microsoft.windowsazure.services.core.storage.StorageCredentialsSharedAccessSignature; import com.microsoft.windowsazure.services.core.storage.StorageErrorCodeStrings; @@ -50,6 +51,7 @@ public class CloudBlobContainerTests extends BlobTestBase { /** * test SharedAccess of container. + * d * * @XSCLCaseName ContainerInfoSharedAccess */ @@ -717,4 +719,56 @@ public void eventOccurred(SendingRequestEvent eventArg) { newContainer.deleteIfExists(); } } + + @Test + public void testCurrentOperationByteCount() throws URISyntaxException, StorageException, IOException { + final int blockLength = 4 * 1024 * 1024; + final Random randGenerator = new Random(); + String blobName = "testblob" + Integer.toString(randGenerator.nextInt(50000)); + blobName = blobName.replace('-', '_'); + + final CloudBlobContainer containerRef = bClient.getContainerReference(BlobTestBase.testSuiteContainerName); + + final CloudBlockBlob blobRef = containerRef.getBlockBlobReference(blobName); + + final ArrayList byteList = new ArrayList(); + final ArrayList blockList = new ArrayList(); + + int numberOfBlocks = 4; + + for (int m = 0; m < numberOfBlocks; m++) { + final byte[] buff = new byte[blockLength]; + randGenerator.nextBytes(buff); + byteList.add(buff); + blobRef.uploadBlock("ABC" + m, new ByteArrayInputStream(buff), blockLength); + + blockList.add(new BlockEntry("ABC" + m, BlockSearchMode.LATEST)); + } + + blobRef.commitBlockList(blockList); + + OperationContext operationContext = new OperationContext(); + BlobRequestOptions options = new BlobRequestOptions(); + options.setTimeoutIntervalInMs(1000); + options.setRetryPolicyFactory(new RetryNoRetry()); + try { + final ByteArrayOutputStream downloadedDataStream = new ByteArrayOutputStream(); + blobRef.download(downloadedDataStream, null, options, operationContext); + } + catch (Exception e) { + Assert.assertEquals(0, operationContext.getCurrentOperationByteCount()); + } + + operationContext = new OperationContext(); + options = new BlobRequestOptions(); + options.setTimeoutIntervalInMs(90000); + + final ByteArrayOutputStream downloadedDataStream = new ByteArrayOutputStream(); + blobRef.download(downloadedDataStream, null, options, operationContext); + + Assert.assertEquals(blockLength * numberOfBlocks, operationContext.getCurrentOperationByteCount()); + + blobRef.delete(); + } + } From 97a58bb66dea046cb1ef79db71574866a05fc4bf Mon Sep 17 00:00:00 2001 From: "Justin Yu (Microsoft)" Date: Mon, 10 Dec 2012 15:07:55 -0800 Subject: [PATCH 5/6] remove no needed "d" --- .../services/blob/client/CloudBlobContainerTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java index 1a360a6c62acf..9d945f61a53a9 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/CloudBlobContainerTests.java @@ -51,7 +51,6 @@ public class CloudBlobContainerTests extends BlobTestBase { /** * test SharedAccess of container. - * d * * @XSCLCaseName ContainerInfoSharedAccess */ From a7df73a68b000b1946fb6006244536c35cf8cab7 Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Fri, 11 Jan 2013 10:43:04 -0800 Subject: [PATCH 6/6] Updating copyright section for parity with the rest of the code. --- .../windowsazure/services/core/storage/SendingRequestEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java index 2e86fbe6166d6..8b61f7e092ff9 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/storage/SendingRequestEvent.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Microsoft Corporation + * Copyright Microsoft Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.