From 6ba7d12a55d2c610184b0f101c3d1449371104b4 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Tue, 7 Aug 2012 13:44:26 -0700 Subject: [PATCH 01/16] Fixing client tests so they pull credentials from env vars --- .../windowsazure/services/blob/client/BlobTestBase.java | 6 +++++- .../windowsazure/services/queue/client/QueueTestBase.java | 6 +++++- .../windowsazure/services/table/client/TableTestBase.java | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java index bd0671e3ece19..938db64c06d4a 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java @@ -51,7 +51,11 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK httpAcc = CloudStorageAccount.getDevelopmentStorageAccount(); } else { - httpAcc = CloudStorageAccount.parse(CLOUD_ACCOUNT_HTTP); + String cloudAccount = CLOUD_ACCOUNT_HTTP; + cloudAccount = cloudAccount.replace("[ACCOUNT NAME]", System.getenv("blob.accountName")); + cloudAccount = cloudAccount.replace("[ACCOUNT KEY]", System.getenv("blob.accountKey")); + + httpAcc = CloudStorageAccount.parse(cloudAccount); } bClient = httpAcc.createCloudBlobClient(); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java index feb5b1ceb4a10..8144378d8577b 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java @@ -52,7 +52,11 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK httpAcc = CloudStorageAccount.getDevelopmentStorageAccount(); } else { - httpAcc = CloudStorageAccount.parse(CLOUD_ACCOUNT_HTTP); + String cloudAccount = CLOUD_ACCOUNT_HTTP; + cloudAccount = cloudAccount.replace("[ACCOUNT NAME]", System.getenv("queue.accountName")); + cloudAccount = cloudAccount.replace("[ACCOUNT KEY]", System.getenv("queue.accountKey")); + + httpAcc = CloudStorageAccount.parse(cloudAccount); } qClient = httpAcc.createCloudQueueClient(); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java index d235ed326cc69..7ba57b75322c8 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java @@ -577,7 +577,11 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK httpAcc = CloudStorageAccount.getDevelopmentStorageAccount(); } else { - httpAcc = CloudStorageAccount.parse(CLOUD_ACCOUNT_HTTP); + String cloudAccount = CLOUD_ACCOUNT_HTTP; + cloudAccount = cloudAccount.replace("[ACCOUNT NAME]", System.getenv("table.accountName")); + cloudAccount = cloudAccount.replace("[ACCOUNT KEY]", System.getenv("table.accountKey")); + + httpAcc = CloudStorageAccount.parse(cloudAccount); } bClient = httpAcc.createCloudBlobClient(); From 40f629b74e363136537ec1baf1754f2f9c65d2a9 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Mon, 24 Sep 2012 17:34:31 -0700 Subject: [PATCH 02/16] Adding support for setting timeout in configuration --- .../services/core/Configuration.java | 27 +++++----- .../services/core/utils/pipeline/Exports.java | 18 +++++-- .../pipeline/HttpURLConnectionClient.java | 18 +++---- .../HttpURLConnectionClientHandler.java | 40 ++++++++++++--- .../table/TableServiceIntegrationTest.java | 49 +++++++++++++++++++ 5 files changed, 116 insertions(+), 36 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java index 1664dec987818..67f30dfe880e4 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java @@ -2,15 +2,15 @@ * 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 + * 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. + * 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; @@ -23,8 +23,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.sun.jersey.api.client.config.ClientConfig; - public class Configuration { private static Configuration instance; @@ -36,17 +34,11 @@ public class Configuration { public Configuration() { this.properties = new HashMap(); this.builder = DefaultBuilder.create(); - init(); } public Configuration(Builder builder) { this.properties = new HashMap(); this.builder = builder; - init(); - } - - private void init() { - setProperty("ClientConfig", builder.build("", ClientConfig.class, properties)); } public static Configuration getInstance() { @@ -102,4 +94,7 @@ public void setProperty(String name, Object value) { properties.put(name, value); } + public Map getProperties() { + return properties; + } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java index 234581b023fb8..026a4254de70b 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java @@ -32,7 +32,19 @@ public void register(Registry registry) { public ClientConfig create(String profile, Builder builder, Map properties) { ClientConfig clientConfig = new DefaultClientConfig(); for (Entry entry : properties.entrySet()) { - clientConfig.getProperties().put(entry.getKey(), entry.getValue()); + Object propertyValue = entry.getValue(); + + // ClientConfig requires instance of Integer to properly set + // timeouts, but config file will deliver strings. Special + // case these timeout properties and convert them to Integer + // if necessary. + if (entry.getKey().equals(ClientConfig.PROPERTY_CONNECT_TIMEOUT) + || entry.getKey().equals(ClientConfig.PROPERTY_READ_TIMEOUT)) { + if (propertyValue instanceof String) { + propertyValue = Integer.valueOf((String) propertyValue); + } + } + clientConfig.getProperties().put(entry.getKey(), propertyValue); } return clientConfig; } @@ -41,7 +53,7 @@ public ClientConfig create(String profile, Builder builder, Map registry.add(new Builder.Factory() { @Override public Client create(String profile, Builder builder, Map properties) { - ClientConfig clientConfig = (ClientConfig) properties.get("ClientConfig"); + ClientConfig clientConfig = builder.build(profile, ClientConfig.class, properties); Client client = Client.create(clientConfig); return client; } @@ -50,7 +62,7 @@ public Client create(String profile, Builder builder, Map proper registry.add(new Builder.Factory() { @Override public HttpURLConnectionClient create(String profile, Builder builder, Map properties) { - ClientConfig clientConfig = (ClientConfig) properties.get("ClientConfig"); + ClientConfig clientConfig = builder.build(profile, ClientConfig.class, properties); HttpURLConnectionClient client = HttpURLConnectionClient.create(clientConfig); //client.addFilter(new LoggingFilter()); return client; diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClient.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClient.java index 9b7ca1dd32482..f996e5edc6421 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClient.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClient.java @@ -2,15 +2,15 @@ * 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 + * 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. + * 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.utils.pipeline; @@ -26,7 +26,7 @@ public HttpURLConnectionClient(HttpURLConnectionClientHandler handler, ClientCon } public static HttpURLConnectionClient create(ClientConfig config) { - return new HttpURLConnectionClient(new HttpURLConnectionClientHandler(), config); + return new HttpURLConnectionClient(new HttpURLConnectionClientHandler(config), config); } public HttpURLConnectionClientHandler getRootHandler() { diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java index 20d9046c5358c..21b1f3c0b3c3b 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java @@ -2,15 +2,15 @@ * 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 + * 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. + * 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.utils.pipeline; @@ -37,10 +37,28 @@ import com.sun.jersey.core.header.InBoundHeaders; public class HttpURLConnectionClientHandler extends TerminatingClientHandler { + + private final int connectionTimeoutMS; + private final int readTimeoutMS; + + public HttpURLConnectionClientHandler(ClientConfig clientConfig) { + connectionTimeoutMS = readTimeoutFromConfig(clientConfig, ClientConfig.PROPERTY_CONNECT_TIMEOUT); + readTimeoutMS = readTimeoutFromConfig(clientConfig, ClientConfig.PROPERTY_READ_TIMEOUT); + } + + private static int readTimeoutFromConfig(ClientConfig config, String propertyName) { + Integer property = (Integer) config.getProperty(propertyName); + if (property != null) { + return property.intValue(); + } + return 0; + } + /** * Empty "no-op" listener if none registered */ private static final EntityStreamingListener EMPTY_STREAMING_LISTENER = new EntityStreamingListener() { + @Override public void onBeforeStreamingEntity(ClientRequest clientRequest) { } }; @@ -164,6 +182,7 @@ public String toString() { } } + @Override public ClientResponse handle(final ClientRequest ro) throws ClientHandlerException { try { return doHandle(ro); @@ -176,6 +195,9 @@ public ClientResponse handle(final ClientRequest ro) throws ClientHandlerExcepti private ClientResponse doHandle(final ClientRequest clientRequest) throws IOException, MalformedURLException, ProtocolException { final HttpURLConnection urlConnection = (HttpURLConnection) clientRequest.getURI().toURL().openConnection(); + urlConnection.setReadTimeout(readTimeoutMS); + urlConnection.setConnectTimeout(connectionTimeoutMS); + final EntityStreamingListener entityStreamingListener = getEntityStreamingListener(clientRequest); urlConnection.setRequestMethod(clientRequest.getMethod()); @@ -202,6 +224,7 @@ private ClientResponse doHandle(final ClientRequest clientRequest) throws IOExce writeRequestEntity(clientRequest, new RequestEntityWriterListener() { private boolean inStreamingMode; + @Override public void onRequestEntitySize(long size) { if (size != -1 && size < Integer.MAX_VALUE) { inStreamingMode = true; @@ -222,6 +245,7 @@ public void onRequestEntitySize(long size) { } } + @Override public OutputStream onGetOutputStream() throws IOException { if (inStreamingMode) return new StreamingOutputStream(urlConnection, clientRequest); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java index 4651f71acf0d6..05cc34eafae09 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java @@ -47,6 +47,7 @@ import com.microsoft.windowsazure.services.table.models.QueryTablesResult; import com.microsoft.windowsazure.services.table.models.ServiceProperties; import com.microsoft.windowsazure.services.table.models.TableEntry; +import com.sun.jersey.api.client.config.ClientConfig; public class TableServiceIntegrationTest extends IntegrationTestBase { private static final String testTablesPrefix = "sdktest"; @@ -1139,4 +1140,52 @@ public void batchNegativeWorks() throws Exception { assertEquals("Second result status code", 412, error.getError().getHttpStatusCode()); assertNull("Third result should be null", result.getEntries().get(2)); } + + @Test + public void settingTimeoutWorks() throws Exception { + Configuration config = createConfiguration(); + + // Set timeout to very short to force failure + config.setProperty(ClientConfig.PROPERTY_CONNECT_TIMEOUT, new Integer(1)); + config.setProperty(ClientConfig.PROPERTY_READ_TIMEOUT, new Integer(1)); + + TableContract service = TableService.create(config); + + try { + service.queryTables(); + fail("Exception should have been thrown"); + } + catch (ServiceException ex) { + assertNotNull(ex.getCause()); + } + finally { + // Clean up timeouts, they interfere with other tests otherwise + config.getProperties().remove(ClientConfig.PROPERTY_CONNECT_TIMEOUT); + config.getProperties().remove(ClientConfig.PROPERTY_READ_TIMEOUT); + } + } + + @Test + public void settingTimeoutFromStringWorks() throws Exception { + Configuration config = createConfiguration(); + + // Set timeout to very short to force failure + config.setProperty(ClientConfig.PROPERTY_CONNECT_TIMEOUT, "1"); + config.setProperty(ClientConfig.PROPERTY_READ_TIMEOUT, "1"); + + TableContract service = TableService.create(config); + + try { + service.queryTables(); + fail("Exception should have been thrown"); + } + catch (ServiceException ex) { + assertNotNull(ex.getCause()); + } + finally { + // Clean up timeouts, they interfere with other tests otherwise + config.getProperties().remove(ClientConfig.PROPERTY_CONNECT_TIMEOUT); + config.getProperties().remove(ClientConfig.PROPERTY_READ_TIMEOUT); + } + } } From e1bafa873026d2f4812d7f48d9a0f78393745123 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Tue, 25 Sep 2012 16:07:54 -0700 Subject: [PATCH 03/16] Setting default timeout at 90 seconds --- .../windowsazure/services/core/Configuration.java | 9 +++++++++ .../pipeline/HttpURLConnectionClientHandler.java | 14 +++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java index 67f30dfe880e4..a3308a0cf0505 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java @@ -23,6 +23,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.sun.jersey.api.client.config.ClientConfig; + public class Configuration { private static Configuration instance; @@ -34,11 +36,18 @@ public class Configuration { public Configuration() { this.properties = new HashMap(); this.builder = DefaultBuilder.create(); + init(); } public Configuration(Builder builder) { this.properties = new HashMap(); this.builder = builder; + init(); + } + + private void init() { + setProperty(ClientConfig.PROPERTY_READ_TIMEOUT, new Integer(90 * 1000)); + setProperty(ClientConfig.PROPERTY_CONNECT_TIMEOUT, new Integer(90 * 1000)); } public static Configuration getInstance() { diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java index 21b1f3c0b3c3b..83e0822264e45 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/HttpURLConnectionClientHandler.java @@ -38,12 +38,12 @@ public class HttpURLConnectionClientHandler extends TerminatingClientHandler { - private final int connectionTimeoutMS; - private final int readTimeoutMS; + private final int connectionTimeoutMillis; + private final int readTimeoutMillis; public HttpURLConnectionClientHandler(ClientConfig clientConfig) { - connectionTimeoutMS = readTimeoutFromConfig(clientConfig, ClientConfig.PROPERTY_CONNECT_TIMEOUT); - readTimeoutMS = readTimeoutFromConfig(clientConfig, ClientConfig.PROPERTY_READ_TIMEOUT); + connectionTimeoutMillis = readTimeoutFromConfig(clientConfig, ClientConfig.PROPERTY_CONNECT_TIMEOUT); + readTimeoutMillis = readTimeoutFromConfig(clientConfig, ClientConfig.PROPERTY_READ_TIMEOUT); } private static int readTimeoutFromConfig(ClientConfig config, String propertyName) { @@ -51,7 +51,7 @@ private static int readTimeoutFromConfig(ClientConfig config, String propertyNam if (property != null) { return property.intValue(); } - return 0; + throw new IllegalArgumentException(propertyName); } /** @@ -195,8 +195,8 @@ public ClientResponse handle(final ClientRequest ro) throws ClientHandlerExcepti private ClientResponse doHandle(final ClientRequest clientRequest) throws IOException, MalformedURLException, ProtocolException { final HttpURLConnection urlConnection = (HttpURLConnection) clientRequest.getURI().toURL().openConnection(); - urlConnection.setReadTimeout(readTimeoutMS); - urlConnection.setConnectTimeout(connectionTimeoutMS); + urlConnection.setReadTimeout(readTimeoutMillis); + urlConnection.setConnectTimeout(connectionTimeoutMillis); final EntityStreamingListener entityStreamingListener = getEntityStreamingListener(clientRequest); From 2b5455ca80369b1c3ec464158d45513084d67857 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Wed, 26 Sep 2012 17:57:29 -0700 Subject: [PATCH 04/16] Throwing ServiceTimeoutException on socket timeout. Also fixed bug in default timeout setting --- .../services/core/Configuration.java | 9 -- .../core/ServiceTimeoutException.java | 50 +++++++++++ .../core/utils/ServiceExceptionFactory.java | 90 ++++++++++++++++--- .../services/core/utils/pipeline/Exports.java | 7 ++ .../table/TableServiceIntegrationTest.java | 15 +++- .../utils/ServiceExceptionFactoryTest.java | 46 ++++++---- 6 files changed, 176 insertions(+), 41 deletions(-) create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java index a3308a0cf0505..67f30dfe880e4 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java @@ -23,8 +23,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.sun.jersey.api.client.config.ClientConfig; - public class Configuration { private static Configuration instance; @@ -36,18 +34,11 @@ public class Configuration { public Configuration() { this.properties = new HashMap(); this.builder = DefaultBuilder.create(); - init(); } public Configuration(Builder builder) { this.properties = new HashMap(); this.builder = builder; - init(); - } - - private void init() { - setProperty(ClientConfig.PROPERTY_READ_TIMEOUT, new Integer(90 * 1000)); - setProperty(ClientConfig.PROPERTY_CONNECT_TIMEOUT, new Integer(90 * 1000)); } public static Configuration getInstance() { diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java new file mode 100644 index 0000000000000..6de101f3d93d3 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java @@ -0,0 +1,50 @@ +/** + * + */ +package com.microsoft.windowsazure.services.core; + +/** + * Exception indicating a service operation has timed out. + */ +public class ServiceTimeoutException extends ServiceException { + + private static final long serialVersionUID = 6612846403178749361L; + + /** + * Construct a ServiceTimeoutException instance + */ + public ServiceTimeoutException() { + } + + /** + * Construct a ServiceTimeoutException instance + * + * @param message + * Exception message + */ + public ServiceTimeoutException(String message) { + super(message); + } + + /** + * Construct a ServiceTimeoutException instance + * + * @param message + * Exception message + * @param cause + * Exception that caused this exception to occur + */ + public ServiceTimeoutException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Construct a ServiceTimeoutException instance + * + * @param cause + * Exception that caused this exception to occur + */ + public ServiceTimeoutException(Throwable cause) { + super(cause); + } +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java index 90210ac0e6254..dd593322c2073 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java @@ -2,19 +2,23 @@ * 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 + * 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. + * 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.utils; +import java.net.SocketTimeoutException; + import com.microsoft.windowsazure.services.core.ServiceException; +import com.microsoft.windowsazure.services.core.ServiceTimeoutException; +import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse.Status; import com.sun.jersey.api.client.UniformInterfaceException; @@ -22,14 +26,69 @@ public class ServiceExceptionFactory { public static ServiceException process(String serviceName, ServiceException exception) { + // State machine for figuring out what to do with the exception + // + // Input is the type of the current exception cause. + // FSM starts in state 0. + // + // State | Input | New State | Action + //--------------------------------------------------------------------------- + // 0 | ServiceException | None | populate and return + // | | | + // 0 | UniformInterfaceException | None | populate and return + // | | | + // 0 | ClientHandlerException | 1 | None + // | | | + // 0 | Any other | 0 | None + // | | | + // 1 | ServiceException | None | populate and return + // | | | + // 1 | UniformInterfaceException | None | populate and return + // | | | + // 1 | ClientHandlerException | 1 | None + // | | | + // 1 | SocketTimeoutException | None | populate and return + // | | | + // 1 | Any other | 0 | None + + int state = 0; Throwable cause = exception.getCause(); for (Throwable scan = cause; scan != null; scan = scan.getCause()) { - if (ServiceException.class.isAssignableFrom(scan.getClass())) { - return populate(exception, serviceName, (ServiceException) scan); - } - else if (UniformInterfaceException.class.isAssignableFrom(scan.getClass())) { - return populate(exception, serviceName, (UniformInterfaceException) scan); + Class scanClass = scan.getClass(); + + switch (state) { + case 0: + if (ServiceException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (ServiceException) scan); + } + else if (UniformInterfaceException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (UniformInterfaceException) scan); + } + else if (ClientHandlerException.class.isAssignableFrom(scanClass)) { + state = 1; + } + else { + state = 0; + } + break; + + case 1: + if (ServiceException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (ServiceException) scan); + } + else if (UniformInterfaceException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (UniformInterfaceException) scan); + } + else if (SocketTimeoutException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (SocketTimeoutException) scan); + } + else if (ClientHandlerException.class.isAssignableFrom(scanClass)) { + state = 1; + } + else { + state = 0; + } } } @@ -83,4 +142,9 @@ static ServiceException populate(ServiceException exception, String serviceName, return exception; } + static ServiceException populate(ServiceException exception, String serviceName, SocketTimeoutException cause) { + ServiceTimeoutException newException = new ServiceTimeoutException(cause.getMessage(), cause); + newException.setServiceName(serviceName); + return newException; + } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java index 026a4254de70b..e8de5bd31606e 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java @@ -31,6 +31,13 @@ public void register(Registry registry) { @Override public ClientConfig create(String profile, Builder builder, Map properties) { ClientConfig clientConfig = new DefaultClientConfig(); + // Lower levels of the stack assume timeouts are set. + // Set default timeout on clientConfig in case user + // hasn't set it yet in their configuration + + clientConfig.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, new Integer(90 * 1000)); + clientConfig.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, new Integer(90 * 1000)); + for (Entry entry : properties.entrySet()) { Object propertyValue = entry.getValue(); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java index 05cc34eafae09..0faee5e7603ca 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java @@ -29,6 +29,7 @@ import com.microsoft.windowsazure.services.core.ExponentialRetryPolicy; import com.microsoft.windowsazure.services.core.RetryPolicyFilter; import com.microsoft.windowsazure.services.core.ServiceException; +import com.microsoft.windowsazure.services.core.ServiceTimeoutException; import com.microsoft.windowsazure.services.table.models.BatchOperations; import com.microsoft.windowsazure.services.table.models.BatchResult; import com.microsoft.windowsazure.services.table.models.BatchResult.DeleteEntity; @@ -1155,8 +1156,11 @@ public void settingTimeoutWorks() throws Exception { service.queryTables(); fail("Exception should have been thrown"); } - catch (ServiceException ex) { - assertNotNull(ex.getCause()); + catch (ServiceTimeoutException ex) { + // No need to assert, test is if correct assertion type is thrown. + } + catch (Exception ex) { + fail("unexpected exception was thrown"); } finally { // Clean up timeouts, they interfere with other tests otherwise @@ -1179,8 +1183,11 @@ public void settingTimeoutFromStringWorks() throws Exception { service.queryTables(); fail("Exception should have been thrown"); } - catch (ServiceException ex) { - assertNotNull(ex.getCause()); + catch (ServiceTimeoutException ex) { + // No need to assert, test is if correct assertion type is thrown. + } + catch (Exception ex) { + fail("unexpected exception was thrown"); } finally { // Clean up timeouts, they interfere with other tests otherwise diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/utils/ServiceExceptionFactoryTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/utils/ServiceExceptionFactoryTest.java index 3cc8639eb849c..54c5b84aab75a 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/utils/ServiceExceptionFactoryTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/utils/ServiceExceptionFactoryTest.java @@ -2,25 +2,27 @@ * 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 + * 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. + * 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.utils; import static org.junit.Assert.*; import java.io.ByteArrayInputStream; +import java.net.SocketTimeoutException; import org.junit.Test; import com.microsoft.windowsazure.services.core.ServiceException; +import com.microsoft.windowsazure.services.core.ServiceTimeoutException; import com.microsoft.windowsazure.services.core.utils.ServiceExceptionFactory; import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.ClientResponse; @@ -31,11 +33,11 @@ public class ServiceExceptionFactoryTest { public void serviceNameAndMessageAndCauseAppearInException() { // Arrange ClientResponse response = new ClientResponse(404, null, new ByteArrayInputStream(new byte[0]), null); - UniformInterfaceException cause = new UniformInterfaceException( - response); + UniformInterfaceException cause = new UniformInterfaceException(response); // Act - ServiceException exception = ServiceExceptionFactory.process("testing", new ServiceException("this is a test", cause)); + ServiceException exception = ServiceExceptionFactory.process("testing", new ServiceException("this is a test", + cause)); // Assert assertNotNull(exception); @@ -48,11 +50,11 @@ public void serviceNameAndMessageAndCauseAppearInException() { public void httpStatusCodeAndReasonPhraseAppearInException() { // Arrange ClientResponse response = new ClientResponse(404, null, new ByteArrayInputStream(new byte[0]), null); - UniformInterfaceException cause = new UniformInterfaceException( - response); + UniformInterfaceException cause = new UniformInterfaceException(response); // Act - ServiceException exception = ServiceExceptionFactory.process("testing", new ServiceException("this is a test", cause)); + ServiceException exception = ServiceExceptionFactory.process("testing", new ServiceException("this is a test", + cause)); // Assert assertNotNull(exception); @@ -65,7 +67,8 @@ public void informationWillPassUpIfServiceExceptionIsRootCauseOfClientHandlerExc // Arrange ClientResponse response = new ClientResponse(503, null, new ByteArrayInputStream(new byte[0]), null); UniformInterfaceException rootCause = new UniformInterfaceException(response); - ServiceException originalDescription = ServiceExceptionFactory.process("underlying", new ServiceException(rootCause)); + ServiceException originalDescription = ServiceExceptionFactory.process("underlying", new ServiceException( + rootCause)); ClientHandlerException wrappingException = new ClientHandlerException(originalDescription); // Act @@ -76,4 +79,17 @@ public void informationWillPassUpIfServiceExceptionIsRootCauseOfClientHandlerExc assertEquals("underlying", exception.getServiceName()); } + @Test + public void socketTimeoutWillPassUpIfInsideClientHandlerException() { + String expectedMessage = "connect timeout"; + SocketTimeoutException rootCause = new SocketTimeoutException(expectedMessage); + ClientHandlerException wrappingException = new ClientHandlerException(rootCause); + + ServiceException exception = ServiceExceptionFactory + .process("testing", new ServiceException(wrappingException)); + + assertSame(ServiceTimeoutException.class, exception.getClass()); + assertEquals(expectedMessage, exception.getMessage()); + assertEquals("testing", exception.getServiceName()); + } } From 45cec57ca38afbb076e9fd04d0306e7bcb3ee911 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Thu, 27 Sep 2012 12:45:29 -0700 Subject: [PATCH 05/16] Code review feedback applied --- .../core/ServiceTimeoutException.java | 21 ++++-- .../core/utils/ServiceExceptionFactory.java | 68 +++---------------- 2 files changed, 25 insertions(+), 64 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java index 6de101f3d93d3..9c3c5f7fcd134 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/ServiceTimeoutException.java @@ -1,6 +1,18 @@ /** + * 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. + * 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; /** @@ -11,13 +23,13 @@ public class ServiceTimeoutException extends ServiceException { private static final long serialVersionUID = 6612846403178749361L; /** - * Construct a ServiceTimeoutException instance + * Construct a ServiceTimeoutException instance with default parameters. */ public ServiceTimeoutException() { } /** - * Construct a ServiceTimeoutException instance + * Construct a ServiceTimeoutException instance with the specified message. * * @param message * Exception message @@ -27,7 +39,8 @@ public ServiceTimeoutException(String message) { } /** - * Construct a ServiceTimeoutException instance + * Construct a ServiceTimeoutException instance with specified + * message and cause * * @param message * Exception message @@ -39,7 +52,7 @@ public ServiceTimeoutException(String message, Throwable cause) { } /** - * Construct a ServiceTimeoutException instance + * Construct a ServiceTimeoutException instance with the specified cause. * * @param cause * Exception that caused this exception to occur diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java index dd593322c2073..d11feceb6d20b 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ServiceExceptionFactory.java @@ -18,7 +18,6 @@ import com.microsoft.windowsazure.services.core.ServiceException; import com.microsoft.windowsazure.services.core.ServiceTimeoutException; -import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse.Status; import com.sun.jersey.api.client.UniformInterfaceException; @@ -26,69 +25,18 @@ public class ServiceExceptionFactory { public static ServiceException process(String serviceName, ServiceException exception) { - // State machine for figuring out what to do with the exception - // - // Input is the type of the current exception cause. - // FSM starts in state 0. - // - // State | Input | New State | Action - //--------------------------------------------------------------------------- - // 0 | ServiceException | None | populate and return - // | | | - // 0 | UniformInterfaceException | None | populate and return - // | | | - // 0 | ClientHandlerException | 1 | None - // | | | - // 0 | Any other | 0 | None - // | | | - // 1 | ServiceException | None | populate and return - // | | | - // 1 | UniformInterfaceException | None | populate and return - // | | | - // 1 | ClientHandlerException | 1 | None - // | | | - // 1 | SocketTimeoutException | None | populate and return - // | | | - // 1 | Any other | 0 | None - - int state = 0; Throwable cause = exception.getCause(); for (Throwable scan = cause; scan != null; scan = scan.getCause()) { Class scanClass = scan.getClass(); - - switch (state) { - case 0: - if (ServiceException.class.isAssignableFrom(scanClass)) { - return populate(exception, serviceName, (ServiceException) scan); - } - else if (UniformInterfaceException.class.isAssignableFrom(scanClass)) { - return populate(exception, serviceName, (UniformInterfaceException) scan); - } - else if (ClientHandlerException.class.isAssignableFrom(scanClass)) { - state = 1; - } - else { - state = 0; - } - break; - - case 1: - if (ServiceException.class.isAssignableFrom(scanClass)) { - return populate(exception, serviceName, (ServiceException) scan); - } - else if (UniformInterfaceException.class.isAssignableFrom(scanClass)) { - return populate(exception, serviceName, (UniformInterfaceException) scan); - } - else if (SocketTimeoutException.class.isAssignableFrom(scanClass)) { - return populate(exception, serviceName, (SocketTimeoutException) scan); - } - else if (ClientHandlerException.class.isAssignableFrom(scanClass)) { - state = 1; - } - else { - state = 0; - } + if (ServiceException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (ServiceException) scan); + } + else if (UniformInterfaceException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (UniformInterfaceException) scan); + } + else if (SocketTimeoutException.class.isAssignableFrom(scanClass)) { + return populate(exception, serviceName, (SocketTimeoutException) scan); } } From ab94bb7d7771fa374075aad307fa35f66c1472e4 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Thu, 27 Sep 2012 14:07:53 -0700 Subject: [PATCH 06/16] Using sdk specific timeout property string, rather than Jersey's. Fixed issues with prefixed client creates. --- .../services/core/Configuration.java | 10 +++++ .../services/core/utils/pipeline/Exports.java | 29 +++++++++++-- .../table/TableServiceIntegrationTest.java | 43 +++++++++++++++---- .../com.microsoft.windowsazure.properties | 4 +- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java index 67f30dfe880e4..e5afff9047a29 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/Configuration.java @@ -25,6 +25,16 @@ public class Configuration { + /** + * Property name for socket connection timeout used by services created with this configuration. + */ + public static final String PROPERTY_CONNECT_TIMEOUT = "com.microsoft.windowsazure.services.core.Configuration.connectTimeout"; + + /** + * Property name for socket read timeout used by services created with this configuration. + */ + public static final String PROPERTY_READ_TIMEOUT = "com.microsoft.windowsazure.services.core.Configuration.readTimeout"; + private static Configuration instance; Map properties; Builder builder; diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java index e8de5bd31606e..d5b9ddc05ce9f 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java @@ -19,6 +19,7 @@ import com.microsoft.windowsazure.services.core.Builder; import com.microsoft.windowsazure.services.core.Builder.Registry; +import com.microsoft.windowsazure.services.core.Configuration; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; @@ -31,6 +32,8 @@ public void register(Registry registry) { @Override public ClientConfig create(String profile, Builder builder, Map properties) { ClientConfig clientConfig = new DefaultClientConfig(); + profile = normalizeProfile(profile); + // Lower levels of the stack assume timeouts are set. // Set default timeout on clientConfig in case user // hasn't set it yet in their configuration @@ -40,18 +43,26 @@ public ClientConfig create(String profile, Builder builder, Map for (Entry entry : properties.entrySet()) { Object propertyValue = entry.getValue(); + String propertyKey = entry.getKey(); + + if (propertyKey.equals(profile + Configuration.PROPERTY_CONNECT_TIMEOUT)) { + propertyKey = ClientConfig.PROPERTY_CONNECT_TIMEOUT; + } + if (propertyKey.equals(profile + Configuration.PROPERTY_READ_TIMEOUT)) { + propertyKey = ClientConfig.PROPERTY_READ_TIMEOUT; + } // ClientConfig requires instance of Integer to properly set // timeouts, but config file will deliver strings. Special // case these timeout properties and convert them to Integer // if necessary. - if (entry.getKey().equals(ClientConfig.PROPERTY_CONNECT_TIMEOUT) - || entry.getKey().equals(ClientConfig.PROPERTY_READ_TIMEOUT)) { + if (propertyKey.equals(ClientConfig.PROPERTY_CONNECT_TIMEOUT) + || propertyKey.equals(ClientConfig.PROPERTY_READ_TIMEOUT)) { if (propertyValue instanceof String) { propertyValue = Integer.valueOf((String) propertyValue); } } - clientConfig.getProperties().put(entry.getKey(), propertyValue); + clientConfig.getProperties().put(propertyKey, propertyValue); } return clientConfig; } @@ -76,4 +87,16 @@ public HttpURLConnectionClient create(String profile, Builder builder, Map Date: Tue, 7 Aug 2012 13:44:26 -0700 Subject: [PATCH 07/16] Fixing client tests so they pull credentials from env vars --- .../windowsazure/services/blob/client/BlobTestBase.java | 6 +++++- .../windowsazure/services/queue/client/QueueTestBase.java | 6 +++++- .../windowsazure/services/table/client/TableTestBase.java | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java index bd0671e3ece19..938db64c06d4a 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/client/BlobTestBase.java @@ -51,7 +51,11 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK httpAcc = CloudStorageAccount.getDevelopmentStorageAccount(); } else { - httpAcc = CloudStorageAccount.parse(CLOUD_ACCOUNT_HTTP); + String cloudAccount = CLOUD_ACCOUNT_HTTP; + cloudAccount = cloudAccount.replace("[ACCOUNT NAME]", System.getenv("blob.accountName")); + cloudAccount = cloudAccount.replace("[ACCOUNT KEY]", System.getenv("blob.accountKey")); + + httpAcc = CloudStorageAccount.parse(cloudAccount); } bClient = httpAcc.createCloudBlobClient(); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java index feb5b1ceb4a10..8144378d8577b 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/queue/client/QueueTestBase.java @@ -52,7 +52,11 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK httpAcc = CloudStorageAccount.getDevelopmentStorageAccount(); } else { - httpAcc = CloudStorageAccount.parse(CLOUD_ACCOUNT_HTTP); + String cloudAccount = CLOUD_ACCOUNT_HTTP; + cloudAccount = cloudAccount.replace("[ACCOUNT NAME]", System.getenv("queue.accountName")); + cloudAccount = cloudAccount.replace("[ACCOUNT KEY]", System.getenv("queue.accountKey")); + + httpAcc = CloudStorageAccount.parse(cloudAccount); } qClient = httpAcc.createCloudQueueClient(); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java index d235ed326cc69..7ba57b75322c8 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/client/TableTestBase.java @@ -577,7 +577,11 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK httpAcc = CloudStorageAccount.getDevelopmentStorageAccount(); } else { - httpAcc = CloudStorageAccount.parse(CLOUD_ACCOUNT_HTTP); + String cloudAccount = CLOUD_ACCOUNT_HTTP; + cloudAccount = cloudAccount.replace("[ACCOUNT NAME]", System.getenv("table.accountName")); + cloudAccount = cloudAccount.replace("[ACCOUNT KEY]", System.getenv("table.accountKey")); + + httpAcc = CloudStorageAccount.parse(cloudAccount); } bClient = httpAcc.createCloudBlobClient(); From 028e9f543fb49b0990e113db56db93263afc9273 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Tue, 9 Oct 2012 16:22:12 -0700 Subject: [PATCH 08/16] Added error checking to list blob call to defend against missing headers --- .../blob/implementation/BlobRestProxy.java | 15 +++++++-- .../blob/BlobServiceIntegrationTest.java | 32 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java index 1366704cf2d81..1a8d830c20dfc 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java @@ -976,8 +976,19 @@ else if (options.isUncommittedList()) { ListBlobBlocksResult result = response.getEntity(ListBlobBlocksResult.class); result.setEtag(response.getHeaders().getFirst("ETag")); result.setContentType(response.getHeaders().getFirst("Content-Type")); - result.setContentLength(Long.parseLong(response.getHeaders().getFirst("x-ms-blob-content-length"))); - result.setLastModified(dateMapper.parse(response.getHeaders().getFirst("Last-Modified"))); + + String blobContentLength = response.getHeaders().getFirst("x-ms-blob-content-length"); + if (blobContentLength != null) { + result.setContentLength(Long.parseLong(blobContentLength)); + } + else { + result.setContentLength(0); + } + + String lastModified = response.getHeaders().getFirst("Last-Modified"); + if (lastModified != null) { + result.setLastModified(dateMapper.parse(lastModified)); + } return result; } diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java index 28e5d990ec7ce..23ebb100ed1c5 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java @@ -650,6 +650,38 @@ public void listBlobsWithDelimiterWorks() throws Exception { assertEquals(0, results6.getBlobPrefixes().size()); } + // Repro case for https://github.com/WindowsAzure/azure-sdk-for-java-pr/issues/295 + @Test + public void listBlockBlobWithNoCommittedBlocksWorks() throws Exception { + Configuration config = createConfiguration(); + BlobContract service = BlobService.create(config); + + String container = "mysample2"; + String blob = "test14"; + + try { + service.createContainer(container); + service.listBlobs(container); + service.createBlockBlob(container, blob, null); + service.createBlobBlock(container, blob, "01", new ByteArrayInputStream(new byte[] { 0x00 })); + service.listBlobBlocks(container, blob, new ListBlobBlocksOptions().setCommittedList(true) + .setUncommittedList(true)); + service.listBlobs(container); + service.deleteContainer(container); + Thread.sleep(40000); + service.createContainer(container); + service.listBlobs(container); + service.createBlobBlock(container, blob, "01", new ByteArrayInputStream(new byte[] { 0x00 })); + // The next line throws + service.listBlobBlocks(container, blob, new ListBlobBlocksOptions().setCommittedList(true) + .setUncommittedList(true)); + service.listBlobs(container); + } + finally { + deleteContainers(service, null, new String[] { container }); + } + } + @Test public void createPageBlobWorks() throws Exception { // Arrange From be88add052740bec4112a9c744bd96ad79a3ceb5 Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 10 Oct 2012 12:59:51 -0700 Subject: [PATCH 09/16] Cleanup of the listBlockBlobWithNoCommittedBlocksWorks test. Found a simpler repro that removes the need for the 40 second sleep (the blob tests only take 20 seconds now). Added regression-proofing in case the Blob service starts returning 404 when accessing blobs that are gone. --- .../blob/BlobServiceIntegrationTest.java | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java index 23ebb100ed1c5..ffbe670dee1e5 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java @@ -650,35 +650,28 @@ public void listBlobsWithDelimiterWorks() throws Exception { assertEquals(0, results6.getBlobPrefixes().size()); } - // Repro case for https://github.com/WindowsAzure/azure-sdk-for-java-pr/issues/295 @Test public void listBlockBlobWithNoCommittedBlocksWorks() throws Exception { Configuration config = createConfiguration(); BlobContract service = BlobService.create(config); - String container = "mysample2"; - String blob = "test14"; + String container = TEST_CONTAINER_FOR_BLOBS; + String blob = "listBlockBlobWithNoCommittedBlocksWorks"; + + service.createBlockBlob(container, blob, null); + service.createBlobBlock(container, blob, "01", new ByteArrayInputStream(new byte[] { 0x00 })); + service.deleteBlob(container, blob); try { - service.createContainer(container); - service.listBlobs(container); - service.createBlockBlob(container, blob, null); - service.createBlobBlock(container, blob, "01", new ByteArrayInputStream(new byte[] { 0x00 })); - service.listBlobBlocks(container, blob, new ListBlobBlocksOptions().setCommittedList(true) - .setUncommittedList(true)); - service.listBlobs(container); - service.deleteContainer(container); - Thread.sleep(40000); - service.createContainer(container); - service.listBlobs(container); + // Note: This next two lines should give a 404, because the blob no longer + // exists. However, the service sometimes allow this improper access, so + // the SDK has to handle the situation gracefully. service.createBlobBlock(container, blob, "01", new ByteArrayInputStream(new byte[] { 0x00 })); - // The next line throws - service.listBlobBlocks(container, blob, new ListBlobBlocksOptions().setCommittedList(true) - .setUncommittedList(true)); - service.listBlobs(container); + ListBlobBlocksResult result = service.listBlobBlocks(container, blob); + assertEquals(0, result.getCommittedBlocks().size()); } - finally { - deleteContainers(service, null, new String[] { container }); + catch (ServiceException ex) { + assertEquals(404, ex.getHttpStatusCode()); } } From f10499526c70f72d53004b56a5cd5bc35d566cf2 Mon Sep 17 00:00:00 2001 From: Alex Rios Date: Thu, 11 Oct 2012 00:28:00 -0300 Subject: [PATCH 10/16] Added 'Fluent Setters' for blob models ServiceProperties and ContainerACL --- .../services/blob/models/ContainerACL.java | 94 ++++++++----- .../blob/models/ServiceProperties.java | 132 ++++++++++++------ 2 files changed, 148 insertions(+), 78 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java index d5f6005b41ea2..9e28d344d099f 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java @@ -1,11 +1,11 @@ /** * 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. @@ -46,7 +46,7 @@ public class ContainerACL { * Gets the Etag value associated with this {@link ContainerACL} instance. This is the value * returned for a container by a Blob service REST API Get Container ACL operation, or the value to set on a * container with a Set Container ACL operation. - * + * * @return * A {@link String} containing the Etag value associated with this {@link ContainerACL} * instance. @@ -61,20 +61,24 @@ public String getEtag() { * This value is only set on a container when this {@link ContainerACL} instance is passed as a parameter to a call * to an implementation of {@link BlobContract#setContainerACL(String, ContainerACL)} or * {@link BlobContract#setContainerACL(String, ContainerACL, BlobServiceOptions)}. - * + * * @param etag * A {@link String} containing the Etag value to associate with this * {@link ContainerACL} instance. + * + * @return + * A reference to this {@link ContainerACL} instance. */ - public void setEtag(String etag) { + public ContainerACL setEtag(String etag) { this.etag = etag; + return this; } /** * Gets the last modified time associated with this {@link ContainerACL} instance. This is the value * returned for a container by a Blob service REST API Get Container ACL operation, or the value to set on a * container with a Set Container ACL operation. - * + * * @return * A {@link Date} containing the last modified time associated with this {@link ContainerACL} instance. */ @@ -88,19 +92,22 @@ public Date getLastModified() { * This value is only set on a container when this {@link ContainerACL} instance is passed as a parameter to a call * to an implementation of {@link BlobContract#setContainerACL(String, ContainerACL)} or * {@link BlobContract#setContainerACL(String, ContainerACL, BlobServiceOptions)}. - * + * * @param lastModified - * A {@link Date} containing the last modified time to associate with this {@link ContainerACL} instance. + * A {@link Date} containing the last modified time to associate with this {@link com.microsoft.windowsazure.services.blob.models.ContainerACL} instance. + * @return + * A reference to this {@link ContainerACL} instance. */ - public void setLastModified(Date lastModified) { + public ContainerACL setLastModified(Date lastModified) { this.lastModified = lastModified; + return this; } /** * Gets the public access level associated with this {@link ContainerACL} instance. This is the value * returned for a container by a Blob service REST API Get Container ACL operation, or the value to set on a * container with a Set Container ACL operation. - * + * * @return * A {@link PublicAccessType} value representing the public access level associated with this * {@link ContainerACL} instance. @@ -115,20 +122,23 @@ public PublicAccessType getPublicAccess() { * This value is only set on a container when this {@link ContainerACL} instance is passed as a parameter to a call * to an implementation of {@link BlobContract#setContainerACL(String, ContainerACL)} or * {@link BlobContract#setContainerACL(String, ContainerACL, BlobServiceOptions)}. - * + * * @param publicAccess * A {@link PublicAccessType} value representing the public access level to associate with this * {@link ContainerACL} instance. + * @return + * A reference to this {@link ContainerACL} instance. */ - public void setPublicAccess(PublicAccessType publicAccess) { + public ContainerACL setPublicAccess(PublicAccessType publicAccess) { this.publicAccess = publicAccess; + return this; } /** * Gets the list of container-level access policies associated with this {@link ContainerACL} instance. This is the * value returned for a container by a Blob service REST API Get Container ACL operation, or the value to set on a * container with a Set Container ACL operation. - * + * * @return * A {@link List} of {@link SignedIdentifier} instances containing up to five container-level access * policies associated with this {@link ContainerACL} instance. @@ -143,13 +153,16 @@ public List getSignedIdentifiers() { * This value is only set on a container when this {@link ContainerACL} instance is passed as a parameter to a call * to an implementation of {@link BlobContract#setContainerACL(String, ContainerACL)} or * {@link BlobContract#setContainerACL(String, ContainerACL, BlobServiceOptions)}. - * + * * @param signedIdentifiers * A {@link List} of {@link SignedIdentifier} instances containing up to five container-level access * policies to associate with this {@link ContainerACL} instance. + * @return + * A reference to this {@link ContainerACL} instance. */ - public void setSignedIdentifiers(List signedIdentifiers) { + public ContainerACL setSignedIdentifiers(List signedIdentifiers) { this.signedIdentifiers = signedIdentifiers; + return this; } /** @@ -176,7 +189,7 @@ public void setSignedIdentifiers(List signedIdentifiers) { * This value is only set on a container when this {@link ContainerACL} instance is passed as a parameter to a call * to an implementation of {@link BlobContract#setContainerACL(String, ContainerACL)} or * {@link BlobContract#setContainerACL(String, ContainerACL, BlobServiceOptions)}. - * + * * @param id * A {@link String} containing the name for the access policy. * @param start @@ -213,7 +226,7 @@ public static class SignedIdentifiers { /** * Gets the list of container-level access policies associated with this {@link SignedIdentifiers} instance. - * + * * @return * A {@link List} of {@link SignedIdentifier} instances containing container-level access policies. */ @@ -224,7 +237,7 @@ public List getSignedIdentifiers() { /** * Sets the list of container-level access policies associated with this {@link SignedIdentifiers} instance. - * + * * @param signedIdentifiers * A {@link List} of {@link SignedIdentifier} instances containing container-level access policies. */ @@ -243,7 +256,7 @@ public static class SignedIdentifier { /** * Gets the name of the container-level access policy. The name may be up to 64 characters in * length and must be unique within the container. - * + * * @return * A {@link String} containing the name for the access policy. */ @@ -255,18 +268,21 @@ public String getId() { /** * Sets the name of the container-level access policy. The name may be up to 64 characters in * length and must be unique within the container. - * + * * @param id * A {@link String} containing the name for the access policy. + * @return + * A reference to this {@link SignedIdentifier} instance. */ - public void setId(String id) { + public SignedIdentifier setId(String id) { this.id = id; + return this; } /** * Gets an {@link AccessPolicy} reference containing the start time, expiration time, and permissions associated * with the container-level access policy. - * + * * @return * An {@link AccessPolicy} reference containing the start time, expiration time, and permissions * associated with the access policy. @@ -279,13 +295,16 @@ public AccessPolicy getAccessPolicy() { /** * Sets an {@link AccessPolicy} reference containing the start time, expiration time, and permissions to * associate with the container-level access policy. - * + * * @param accessPolicy * An {@link AccessPolicy} reference containing the start time, expiration time, and permissions * to associate with the access policy. + * @return + * A reference to this {@link SignedIdentifier} instance. */ - public void setAccessPolicy(AccessPolicy accessPolicy) { + public SignedIdentifier setAccessPolicy(AccessPolicy accessPolicy) { this.accessPolicy = accessPolicy; + return this; } } @@ -301,7 +320,7 @@ public static class AccessPolicy { * Gets the start time for valid access to a resource using the access policy. If this value is * null, the start time for any resource request using the access policy is assumed to be the time * when the Blob service receives the request. - * + * * @return * A {@link Date} representing the start time for the access policy, or null if none is * specified. @@ -316,20 +335,23 @@ public Date getStart() { * Sets the start time for valid access to a resource using the access policy. If this value is * null, the start time for any resource request using the access policy is assumed to be the time * when the Blob service receives the request. - * + * * @param start * A {@link Date} representing the start time for the access policy, or null to leave * the time unspecified. + * @return + * A reference to this {@link AccessPolicy} instance. */ - public void setStart(Date start) { + public AccessPolicy setStart(Date start) { this.start = start; + return this; } /** * Gets the expiration time for valid access to a resource using the access policy. If this value is * null, any Shared Access Signature that refers to this access policy must specify the expiry * value. - * + * * @return * A {@link Date} representing the expiration time for the access policy, or null if none * is specified. @@ -344,13 +366,16 @@ public Date getExpiry() { * Sets the expiration time for valid access to a resource using the access policy. If this value is * null, any Shared Access Signature that refers to this access policy must specify the expiry * value. - * + * * @param expiry * A {@link Date} representing the expiration time for the access policy, or null to * leave the time unspecified. + * @return + * A reference to this {@link AccessPolicy} instance. */ - public void setExpiry(Date expiry) { + public AccessPolicy setExpiry(Date expiry) { this.expiry = expiry; + return this; } /** @@ -359,7 +384,7 @@ public void setExpiry(Date expiry) { * operations to be performed with the access policy. For example, if all permissions to a resource are granted, * the method returns "rwdl" as the result. If only read/write permissions are granted, the method returns "rw" * as the result. - * + * * @return * A {@link String} containing the permissions specified for the access policy. */ @@ -373,12 +398,15 @@ public String getPermission() { * include read (r), write (w), delete (d), and list (l). Permissions may be grouped so as to allow multiple * operations to be performed with the access policy. For example, to grant all permissions to a resource, * specify "rwdl" for the parameter. To grant only read/write permissions, specify "rw" for the parameter. - * + * * @param permission * A {@link String} containing the permissions specified for the access policy. + * @return + * A reference to this {@link AccessPolicy} instance. */ - public void setPermission(String permission) { + public AccessPolicy setPermission(String permission) { this.permission = permission; + return this; } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java index cdca5eee0e01b..4666a293b1202 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java @@ -1,11 +1,11 @@ /** * 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. @@ -34,7 +34,7 @@ public class ServiceProperties { /** * Gets the value of the logging options on the storage account. - * + * * @return * A {@link Logging} instance containing the logging options. */ @@ -45,17 +45,20 @@ public Logging getLogging() { /** * Sets the value of the logging options on the storage account. - * + * * @param logging * A {@link Logging} instance containing the logging options. + * @return + * A reference to this {@link ServiceProperties} instance. */ - public void setLogging(Logging logging) { + public ServiceProperties setLogging(Logging logging) { this.logging = logging; + return this; } /** * Gets the value of the metrics options on the storage account. - * + * * @return * A {@link Metrics} instance containing the metrics options. */ @@ -66,17 +69,20 @@ public Metrics getMetrics() { /** * Sets the value of the metrics options on the storage account. - * + * * @param metrics * A {@link Metrics} instance containing the metrics options. + * @return + * A reference to this {@link ServiceProperties} instance. */ - public void setMetrics(Metrics metrics) { + public ServiceProperties setMetrics(Metrics metrics) { this.metrics = metrics; + return this; } /** * Gets the default service version string used for operations on the storage account. - * + * * @return * A {@link String} containing the default service version string used for operations on the storage * account. @@ -92,13 +98,16 @@ public String getDefaultServiceVersion() { *

* See Storage Services Versioning * on MSDN for more information on applicable versions. - * + * * @param defaultServiceVersion * A {@link String} containing the default service version string used for operations on the storage * account. + * @return + * A reference to this {@link ServiceProperties} instance. */ - public void setDefaultServiceVersion(String defaultServiceVersion) { + public ServiceProperties setDefaultServiceVersion(String defaultServiceVersion) { this.defaultServiceVersion = defaultServiceVersion; + return this; } /** @@ -113,7 +122,7 @@ public static class Logging { /** * Gets the retention policy for logging data set on the storage account. - * + * * @return * The {@link RetentionPolicy} set on the storage account. */ @@ -124,17 +133,20 @@ public RetentionPolicy getRetentionPolicy() { /** * Sets the retention policy to use for logging data on the storage account. - * + * * @param retentionPolicy * The {@link RetentionPolicy} to set on the storage account. + * @return + * A reference to this {@link Logging} instance. */ - public void setRetentionPolicy(RetentionPolicy retentionPolicy) { + public Logging setRetentionPolicy(RetentionPolicy retentionPolicy) { this.retentionPolicy = retentionPolicy; + return this; } /** * Gets a flag indicating whether all write requests are logged. - * + * * @return * A flag value of true if all write operations are logged; otherwise, false. */ @@ -145,17 +157,20 @@ public boolean isWrite() { /** * Sets a flag indicating whether all write requests should be logged. - * + * * @param write * Set a flag value of true to log all write operations; otherwise, false. + * @return + * A reference to this {@link Logging} instance. */ - public void setWrite(boolean write) { + public Logging setWrite(boolean write) { this.write = write; + return this; } /** * Gets a flag indicating whether all read requests are logged. - * + * * @return * A flag value of true if all read operations are logged; otherwise, false. */ @@ -166,17 +181,20 @@ public boolean isRead() { /** * Sets a flag indicating whether all read requests should be logged. - * + * * @param read * Set a flag value of true to log all read operations; otherwise, false. + * @return + * A reference to this {@link Logging} instance. */ - public void setRead(boolean read) { + public Logging setRead(boolean read) { this.read = read; + return this; } /** * Gets a flag indicating whether all delete requests are logged. - * + * * @return * A flag value of true if all delete operations are logged; otherwise, false. */ @@ -187,17 +205,20 @@ public boolean isDelete() { /** * Sets a flag indicating whether all delete requests should be logged. - * + * * @param delete * Set a flag value of true to log all delete operations; otherwise, false. + * @return + * A reference to this {@link Logging} instance. */ - public void setDelete(boolean delete) { + public Logging setDelete(boolean delete) { this.delete = delete; + return this; } /** * Gets the version of logging configured on the storage account. - * + * * @return * A {@link String} containing the version of logging configured on the storage account. */ @@ -208,12 +229,15 @@ public String getVersion() { /** * Sets the version of logging configured on the storage account. - * + * * @param version * A {@link String} containing the version of logging configured on the storage account. + * @return + * A reference to this {@link Logging} instance. */ - public void setVersion(String version) { + public Logging setVersion(String version) { this.version = version; + return this; } } @@ -228,7 +252,7 @@ public static class Metrics { /** * Gets the retention policy for metrics data set on the storage account. - * + * * @return * The {@link RetentionPolicy} set on the storage account. */ @@ -239,17 +263,20 @@ public RetentionPolicy getRetentionPolicy() { /** * Sets the retention policy to use for metrics data on the storage account. - * + * * @param retentionPolicy * The {@link RetentionPolicy} to set on the storage account. + * @return + * A reference to this {@link Metrics} instance. */ - public void setRetentionPolicy(RetentionPolicy retentionPolicy) { + public Metrics setRetentionPolicy(RetentionPolicy retentionPolicy) { this.retentionPolicy = retentionPolicy; + return this; } /** * Gets a flag indicating whether metrics generates summary statistics for called API operations. - * + * * @return * A flag value of true if metrics generates summary statistics for called API operations; * otherwise, false. @@ -262,18 +289,21 @@ public Boolean isIncludeAPIs() { /** * Sets a flag indicating whether metrics should generate summary statistics for called API operations. This * flag is optional if metrics is not enabled. - * + * * @param includeAPIs * Set a flag value of true to generate summary statistics for called API operations; * otherwise, false. + * @return + * A reference to this {@link Metrics} instance. */ - public void setIncludeAPIs(Boolean includeAPIs) { + public Metrics setIncludeAPIs(Boolean includeAPIs) { this.includeAPIs = includeAPIs; + return this; } /** * Gets a flag indicating whether metrics is enabled for the storage account. - * + * * @return * A flag value of true if metrics is enabled for the storage account; otherwise, * false. @@ -285,18 +315,21 @@ public boolean isEnabled() { /** * Sets a flag indicating whether to enable metrics for the storage account. - * + * * @param enabled * Set a flag value of true to enable metrics for the storage account; otherwise, * false. + * @return + * A reference to this {@link Metrics} instance. */ - public void setEnabled(boolean enabled) { + public Metrics setEnabled(boolean enabled) { this.enabled = enabled; + return this; } /** * Gets the version of Storage Analytics configured on the storage account. - * + * * @return * A {@link String} containing the version of Storage Analytics configured on the storage account. */ @@ -307,12 +340,15 @@ public String getVersion() { /** * Sets the version of Storage Analytics configured on the storage account. - * + * * @param version * A {@link String} containing the version of Storage Analytics configured on the storage account. + * @return + * A reference to this {@link Metrics} instance. */ - public void setVersion(String version) { + public Metrics setVersion(String version) { this.version = version; + return this; } } @@ -325,7 +361,7 @@ public static class RetentionPolicy { /** * Gets the number of days that metrics or logging data should be retained, if logging is enabled. - * + * * @return * The number of days to retain logging or metrics data if logging is enabled, or null. */ @@ -338,17 +374,20 @@ public Integer getDays() { * Sets the number of days that metrics or logging data should be retained. The minimum value you can specify is * 1; the largest value is 365 (one year). This value must be specified even if the enabled flag is set * to false. - * + * * @param days * The number of days to retain logging or metrics data. + * @return + * A reference to this {@link RetentionPolicy} instance. */ - public void setDays(Integer days) { + public RetentionPolicy setDays(Integer days) { this.days = days; + return this; } /** * Gets a flag indicating whether a retention policy is enabled. - * + * * @return * A flag value of true if a retention policy is enabled; otherwise, false. */ @@ -359,12 +398,15 @@ public boolean isEnabled() { /** * Sets a flag indicating whether to enable a retention policy. - * + * * @param enabled * Set a flag value of true to enable a retention policy; otherwise, false. + * @return + * A reference to this {@link RetentionPolicy} instance. */ - public void setEnabled(boolean enabled) { + public RetentionPolicy setEnabled(boolean enabled) { this.enabled = enabled; + return this; } } -} +} \ No newline at end of file From 2b99d1e84fdccbf07b3e80c065278ce723f69799 Mon Sep 17 00:00:00 2001 From: Alex Rios Date: Thu, 11 Oct 2012 00:59:20 -0300 Subject: [PATCH 11/16] Added 'Fluent Setters' for queue model ServiceProperties --- .../queue/models/ServiceProperties.java | 121 ++++++++++++------ 1 file changed, 80 insertions(+), 41 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/models/ServiceProperties.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/models/ServiceProperties.java index 9f2715a7fe0d6..a914ac2279975 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/models/ServiceProperties.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/models/ServiceProperties.java @@ -1,11 +1,11 @@ /** * 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. @@ -45,7 +45,7 @@ public class ServiceProperties { *

* Note that changes to this value are not reflected in the Queue service properties until they have been set on the * storage account with a call to {@link QueueContract}.setServiceProperties. - * + * * @return * A reference to the {@link Logging} instance in this {@link ServiceProperties} instance. */ @@ -59,12 +59,15 @@ public Logging getLogging() { *

* Note that changes to this value are not reflected in the Queue service properties until they have been set on the * storage account with a call to {@link QueueContract}.setServiceProperties. - * + * * @param logging * The {@link Logging} instance to set in this {@link ServiceProperties} instance. + * @return + * A reference to this {@link ServiceProperties} instance. */ - public void setLogging(Logging logging) { + public ServiceProperties setLogging(Logging logging) { this.logging = logging; + return this; } /** @@ -75,7 +78,7 @@ public void setLogging(Logging logging) { *

* Note that changes to this value are not reflected in the Queue service properties until they have been set on the * storage account with a call to {@link QueueContract}.setServiceProperties. - * + * * @return * A reference to the {@link Metrics} instance in this {@link ServiceProperties} instance. */ @@ -89,12 +92,15 @@ public Metrics getMetrics() { *

* Note that changes to this value are not reflected in the Queue service properties until they have been set on the * storage account with a call to {@link QueueContract}.setServiceProperties. - * + * * @param metrics * The {@link Metrics} instance to set in this {@link ServiceProperties} instance. + * @return + * A reference to this {@link ServiceProperties} instance. */ - public void setMetrics(Metrics metrics) { + public ServiceProperties setMetrics(Metrics metrics) { this.metrics = metrics; + return this; } /** @@ -111,7 +117,7 @@ public static class Logging { /** * Gets a reference to the {@link RetentionPolicy} instance in this {@link Logging} instance. - * + * * @return * A reference to the {@link RetentionPolicy} instance in this {@link Logging} instance. */ @@ -122,19 +128,22 @@ public RetentionPolicy getRetentionPolicy() { /** * Sets the {@link RetentionPolicy} instance in this {@link Logging} instance. - * + * * @param retentionPolicy * The {@link RetentionPolicy} instance to set in this {@link Logging} instance. + * @return + * A reference to this {@link Logging} instance. */ - public void setRetentionPolicy(RetentionPolicy retentionPolicy) { + public Logging setRetentionPolicy(RetentionPolicy retentionPolicy) { this.retentionPolicy = retentionPolicy; + return this; } /** * Gets a flag indicating whether queue write operations are logged. If this value is true then all * requests that write to the Queue service will be logged. These requests include adding a message, updating a * message, setting queue metadata, and creating a queue. - * + * * @return * true if queue write operations are logged, otherwise false. */ @@ -147,19 +156,22 @@ public boolean isWrite() { * Sets a flag indicating whether queue write operations are logged. If this value is true then all * requests that write to the Queue service will be logged. These requests include adding a message, updating a * message, setting queue metadata, and creating a queue. - * + * * @param write * true to enable logging of queue write operations, otherwise false. + * @return + * A reference to this {@link Logging} instance. */ - public void setWrite(boolean write) { + public Logging setWrite(boolean write) { this.write = write; + return this; } /** * Gets a flag indicating whether queue read operations are logged. If this value is true then all * requests that read from the Queue service will be logged. These requests include listing queues, getting * queue metadata, listing messages, and peeking messages. - * + * * @return * true if queue read operations are logged, otherwise false. */ @@ -172,19 +184,22 @@ public boolean isRead() { * Sets a flag indicating whether queue read operations are logged. If this value is true then all * requests that read from the Queue service will be logged. These requests include listing queues, getting * queue metadata, listing messages, and peeking messages. - * + * * @param read * true to enable logging of queue read operations, otherwise false. + * @return + * A reference to this {@link Logging} instance. */ - public void setRead(boolean read) { + public Logging setRead(boolean read) { this.read = read; + return this; } /** * Gets a flag indicating whether queue delete operations are logged. If this value is true then * all requests that delete from the Queue service will be logged. These requests include deleting queues, * deleting messages, and clearing messages. - * + * * @return * true if queue delete operations are logged, otherwise false. */ @@ -197,17 +212,20 @@ public boolean isDelete() { * Sets a flag indicating whether queue delete operations are logged. If this value is true then * all requests that delete from the Queue service will be logged. These requests include deleting queues, * deleting messages, and clearing messages. - * + * * @param delete * true to enable logging of queue delete operations, otherwise false. + * @return + * A reference to this {@link Logging} instance. */ - public void setDelete(boolean delete) { + public Logging setDelete(boolean delete) { this.delete = delete; + return this; } /** * Gets the Storage Analytics version number associated with this {@link Logging} instance. - * + * * @return * A {@link String} containing the Storage Analytics version number. */ @@ -223,12 +241,15 @@ public String getVersion() { *

* See the Storage Analytics * Overview documentation on MSDN for more information. - * + * * @param version * A {@link String} containing the Storage Analytics version number to set. + * @return + * A reference to this {@link Logging} instance. */ - public void setVersion(String version) { + public Logging setVersion(String version) { this.version = version; + return this; } } @@ -245,7 +266,7 @@ public static class Metrics { /** * Gets a reference to the {@link RetentionPolicy} instance in this {@link Metrics} instance. - * + * * @return * A reference to the {@link RetentionPolicy} instance in this {@link Metrics} instance. */ @@ -256,18 +277,21 @@ public RetentionPolicy getRetentionPolicy() { /** * Sets the {@link RetentionPolicy} instance in this {@link Metrics} instance. - * + * * @param retentionPolicy * The {@link RetentionPolicy} instance to set in this {@link Metrics} instance. + * @return + * A reference to this {@link Metrics} instance. */ - public void setRetentionPolicy(RetentionPolicy retentionPolicy) { + public Metrics setRetentionPolicy(RetentionPolicy retentionPolicy) { this.retentionPolicy = retentionPolicy; + return this; } /** * Gets a flag indicating whether metrics should generate summary statistics for called API operations. If this * value is true then all Queue service REST API operations will be included in the metrics. - * + * * @return * true if Queue service REST API operations are included in metrics, otherwise * false. @@ -280,18 +304,21 @@ public Boolean isIncludeAPIs() { /** * Sets a flag indicating whether metrics should generate summary statistics for called API operations. If this * value is true then all Queue service REST API operations will be included in the metrics. - * + * * @param includeAPIs * true to include Queue service REST API operations in metrics, otherwise * false. + * @return + * A reference to this {@link Metrics} instance. */ - public void setIncludeAPIs(Boolean includeAPIs) { + public Metrics setIncludeAPIs(Boolean includeAPIs) { this.includeAPIs = includeAPIs; + return this; } /** * Gets a flag indicating whether metrics is enabled for the Queue storage service. - * + * * @return * A flag indicating whether metrics is enabled for the Queue storage service. */ @@ -302,17 +329,20 @@ public boolean isEnabled() { /** * Sets a flag indicating whether to enable metrics for the Queue storage service. - * + * * @param enabled * true to enable metrics for the Queue storage service, otherwise false. + * @return + * A reference to this {@link Metrics} instance. */ - public void setEnabled(boolean enabled) { + public Metrics setEnabled(boolean enabled) { this.enabled = enabled; + return this; } /** * Gets the Storage Analytics version number associated with this {@link Metrics} instance. - * + * * @return * A {@link String} containing the Storage Analytics version number. */ @@ -327,12 +357,15 @@ public String getVersion() { *

* See the Storage Analytics * Overview documentation on MSDN for more information. - * + * * @param version * A {@link String} containing the Storage Analytics version number to set. + * @return + * A reference to this {@link Metrics} instance. */ - public void setVersion(String version) { + public Metrics setVersion(String version) { this.version = version; + return this; } } @@ -348,7 +381,7 @@ public static class RetentionPolicy { /** * Gets the number of days that metrics or logging data should be retained. All data older than this value will * be deleted. The value may be null if a retention policy is not enabled. - * + * * @return * The number of days that metrics or logging data should be retained. */ @@ -361,17 +394,20 @@ public Integer getDays() { * Sets the number of days that metrics or logging data should be retained. All data older than this value will * be deleted. The value must be in the range from 1 to 365. This value must be set if a retention policy is * enabled, but is not required if a retention policy is not enabled. - * + * * @param days * The number of days that metrics or logging data should be retained. + * @return + * A reference to this {@link RetentionPolicy} instance. */ - public void setDays(Integer days) { + public RetentionPolicy setDays(Integer days) { this.days = days; + return this; } /** * Gets a flag indicating whether a retention policy is enabled for the storage service. - * + * * @return * true if data retention is enabled, otherwise false. */ @@ -382,12 +418,15 @@ public boolean isEnabled() { /** * Sets a flag indicating whether a retention policy is enabled for the storage service. - * + * * @param enabled * Set true to enable data retention. + * @return + * A reference to this {@link RetentionPolicy} instance. */ - public void setEnabled(boolean enabled) { + public RetentionPolicy setEnabled(boolean enabled) { this.enabled = enabled; + return this; } } } From 270a4aecd64e2f0a61fdc6ff45bc653a97f9c446 Mon Sep 17 00:00:00 2001 From: Alex Rios Date: Thu, 11 Oct 2012 14:56:11 -0300 Subject: [PATCH 12/16] Adding some formatting in javadocs --- .../services/blob/models/ContainerACL.java | 20 +++++++------- .../blob/models/ServiceProperties.java | 26 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java index 9e28d344d099f..4fb40c1285537 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ContainerACL.java @@ -67,7 +67,7 @@ public String getEtag() { * {@link ContainerACL} instance. * * @return - * A reference to this {@link ContainerACL} instance. + * A reference to this {@link ContainerACL} instance. */ public ContainerACL setEtag(String etag) { this.etag = etag; @@ -94,9 +94,9 @@ public Date getLastModified() { * {@link BlobContract#setContainerACL(String, ContainerACL, BlobServiceOptions)}. * * @param lastModified - * A {@link Date} containing the last modified time to associate with this {@link com.microsoft.windowsazure.services.blob.models.ContainerACL} instance. + * A {@link java.util.Date} containing the last modified time to associate with this {@link ContainerACL} instance. * @return - * A reference to this {@link ContainerACL} instance. + * A reference to this {@link ContainerACL} instance. */ public ContainerACL setLastModified(Date lastModified) { this.lastModified = lastModified; @@ -127,7 +127,7 @@ public PublicAccessType getPublicAccess() { * A {@link PublicAccessType} value representing the public access level to associate with this * {@link ContainerACL} instance. * @return - * A reference to this {@link ContainerACL} instance. + * A reference to this {@link ContainerACL} instance. */ public ContainerACL setPublicAccess(PublicAccessType publicAccess) { this.publicAccess = publicAccess; @@ -158,7 +158,7 @@ public List getSignedIdentifiers() { * A {@link List} of {@link SignedIdentifier} instances containing up to five container-level access * policies to associate with this {@link ContainerACL} instance. * @return - * A reference to this {@link ContainerACL} instance. + * A reference to this {@link ContainerACL} instance. */ public ContainerACL setSignedIdentifiers(List signedIdentifiers) { this.signedIdentifiers = signedIdentifiers; @@ -272,7 +272,7 @@ public String getId() { * @param id * A {@link String} containing the name for the access policy. * @return - * A reference to this {@link SignedIdentifier} instance. + * A reference to this {@link SignedIdentifier} instance. */ public SignedIdentifier setId(String id) { this.id = id; @@ -300,7 +300,7 @@ public AccessPolicy getAccessPolicy() { * An {@link AccessPolicy} reference containing the start time, expiration time, and permissions * to associate with the access policy. * @return - * A reference to this {@link SignedIdentifier} instance. + * A reference to this {@link SignedIdentifier} instance. */ public SignedIdentifier setAccessPolicy(AccessPolicy accessPolicy) { this.accessPolicy = accessPolicy; @@ -340,7 +340,7 @@ public Date getStart() { * A {@link Date} representing the start time for the access policy, or null to leave * the time unspecified. * @return - * A reference to this {@link AccessPolicy} instance. + * A reference to this {@link AccessPolicy} instance. */ public AccessPolicy setStart(Date start) { this.start = start; @@ -371,7 +371,7 @@ public Date getExpiry() { * A {@link Date} representing the expiration time for the access policy, or null to * leave the time unspecified. * @return - * A reference to this {@link AccessPolicy} instance. + * A reference to this {@link AccessPolicy} instance. */ public AccessPolicy setExpiry(Date expiry) { this.expiry = expiry; @@ -402,7 +402,7 @@ public String getPermission() { * @param permission * A {@link String} containing the permissions specified for the access policy. * @return - * A reference to this {@link AccessPolicy} instance. + * A reference to this {@link AccessPolicy} instance. */ public AccessPolicy setPermission(String permission) { this.permission = permission; diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java index 4666a293b1202..24f92c559b2f6 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/ServiceProperties.java @@ -49,7 +49,7 @@ public Logging getLogging() { * @param logging * A {@link Logging} instance containing the logging options. * @return - * A reference to this {@link ServiceProperties} instance. + * A reference to this {@link ServiceProperties} instance. */ public ServiceProperties setLogging(Logging logging) { this.logging = logging; @@ -73,7 +73,7 @@ public Metrics getMetrics() { * @param metrics * A {@link Metrics} instance containing the metrics options. * @return - * A reference to this {@link ServiceProperties} instance. + * A reference to this {@link ServiceProperties} instance. */ public ServiceProperties setMetrics(Metrics metrics) { this.metrics = metrics; @@ -103,7 +103,7 @@ public String getDefaultServiceVersion() { * A {@link String} containing the default service version string used for operations on the storage * account. * @return - * A reference to this {@link ServiceProperties} instance. + * A reference to this {@link ServiceProperties} instance. */ public ServiceProperties setDefaultServiceVersion(String defaultServiceVersion) { this.defaultServiceVersion = defaultServiceVersion; @@ -137,7 +137,7 @@ public RetentionPolicy getRetentionPolicy() { * @param retentionPolicy * The {@link RetentionPolicy} to set on the storage account. * @return - * A reference to this {@link Logging} instance. + * A reference to this {@link Logging} instance. */ public Logging setRetentionPolicy(RetentionPolicy retentionPolicy) { this.retentionPolicy = retentionPolicy; @@ -185,7 +185,7 @@ public boolean isRead() { * @param read * Set a flag value of true to log all read operations; otherwise, false. * @return - * A reference to this {@link Logging} instance. + * A reference to this {@link Logging} instance. */ public Logging setRead(boolean read) { this.read = read; @@ -209,7 +209,7 @@ public boolean isDelete() { * @param delete * Set a flag value of true to log all delete operations; otherwise, false. * @return - * A reference to this {@link Logging} instance. + * A reference to this {@link Logging} instance. */ public Logging setDelete(boolean delete) { this.delete = delete; @@ -233,7 +233,7 @@ public String getVersion() { * @param version * A {@link String} containing the version of logging configured on the storage account. * @return - * A reference to this {@link Logging} instance. + * A reference to this {@link Logging} instance. */ public Logging setVersion(String version) { this.version = version; @@ -267,7 +267,7 @@ public RetentionPolicy getRetentionPolicy() { * @param retentionPolicy * The {@link RetentionPolicy} to set on the storage account. * @return - * A reference to this {@link Metrics} instance. + * A reference to this {@link Metrics} instance. */ public Metrics setRetentionPolicy(RetentionPolicy retentionPolicy) { this.retentionPolicy = retentionPolicy; @@ -294,7 +294,7 @@ public Boolean isIncludeAPIs() { * Set a flag value of true to generate summary statistics for called API operations; * otherwise, false. * @return - * A reference to this {@link Metrics} instance. + * A reference to this {@link Metrics} instance. */ public Metrics setIncludeAPIs(Boolean includeAPIs) { this.includeAPIs = includeAPIs; @@ -320,7 +320,7 @@ public boolean isEnabled() { * Set a flag value of true to enable metrics for the storage account; otherwise, * false. * @return - * A reference to this {@link Metrics} instance. + * A reference to this {@link Metrics} instance. */ public Metrics setEnabled(boolean enabled) { this.enabled = enabled; @@ -344,7 +344,7 @@ public String getVersion() { * @param version * A {@link String} containing the version of Storage Analytics configured on the storage account. * @return - * A reference to this {@link Metrics} instance. + * A reference to this {@link Metrics} instance. */ public Metrics setVersion(String version) { this.version = version; @@ -378,7 +378,7 @@ public Integer getDays() { * @param days * The number of days to retain logging or metrics data. * @return - * A reference to this {@link RetentionPolicy} instance. + * A reference to this {@link RetentionPolicy} instance. */ public RetentionPolicy setDays(Integer days) { this.days = days; @@ -402,7 +402,7 @@ public boolean isEnabled() { * @param enabled * Set a flag value of true to enable a retention policy; otherwise, false. * @return - * A reference to this {@link RetentionPolicy} instance. + * A reference to this {@link RetentionPolicy} instance. */ public RetentionPolicy setEnabled(boolean enabled) { this.enabled = enabled; From ce5a57258b20091efec873fdeb62010d85b5e073 Mon Sep 17 00:00:00 2001 From: Joost de Nijs Date: Tue, 16 Oct 2012 10:16:12 -0700 Subject: [PATCH 13/16] README and pom.xml changes for 0.3.2 --- ChangeLog.txt | 5 +++++ microsoft-azure-api/pom.xml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 17345e70ce1af..ec57d7e0d2140 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,8 @@ +2012.10.16 Version 0.3.2 + * Implemented a more graceful timeout Exception + * Implemented a better Exception for an empty header returned by the Azure Storage Service + * Added Fluent setters for Blob Models + 2012.09.11 Version 0.3.1 * Added Javadocs to 1.7 Storage Support from 0.3.0 release * Fixed bug where getqueue for an invalid queue returns 200 and the exception is not wrapped in a ServiceException diff --git a/microsoft-azure-api/pom.xml b/microsoft-azure-api/pom.xml index a728300dac54a..b8ed0c41ecb6f 100644 --- a/microsoft-azure-api/pom.xml +++ b/microsoft-azure-api/pom.xml @@ -17,7 +17,7 @@ 4.0.0 com.microsoft.windowsazure microsoft-windowsazure-api - 0.3.1 + 0.3.2 jar Microsoft Windows Azure Client API From 4bf6b5d484d4548aeb524148b9fd96cd80852b66 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Wed, 17 Oct 2012 13:49:43 -0700 Subject: [PATCH 14/16] Fix for #165 - ServiceBusIntegrationTest.rulesMayHaveActionAndFilter unit test failure --- .../services/serviceBus/models/RuleInfo.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/models/RuleInfo.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/models/RuleInfo.java index 35e30ae716508..7889fdc900a35 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/models/RuleInfo.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/models/RuleInfo.java @@ -2,15 +2,15 @@ * 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 + * 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. + * 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.serviceBus.models; @@ -149,12 +149,14 @@ public RuleInfo withSqlExpressionFilter(String sqlExpression) { public RuleInfo withTrueFilter() { TrueFilter filter = new TrueFilter(); filter.setCompatibilityLevel(20); + filter.setSqlExpression("1=1"); return setFilter(filter); } public RuleInfo withFalseFilter() { FalseFilter filter = new FalseFilter(); filter.setCompatibilityLevel(20); + filter.setSqlExpression("1=0"); return setFilter(filter); } From 853bb1bc76aef8515d169de402869d93d4d24f36 Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 17 Oct 2012 14:07:39 -0700 Subject: [PATCH 15/16] Fix unit test to work correctly even if the test machine has clock skew from server --- .../services/blob/BlobServiceIntegrationTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java index ffbe670dee1e5..853132a00da13 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java @@ -1346,14 +1346,14 @@ public void getBlobPropertiesIfNotModified() throws Exception { // Arrange Configuration config = createConfiguration(); BlobContract service = BlobService.create(config); - Date currentLastModifiedDate = new Date(); // Act String container = TEST_CONTAINER_FOR_BLOBS; String blob = "test"; - service.createPageBlob(container, blob, 4096); - GetBlobPropertiesResult result = service.getBlobProperties(container, blob, new GetBlobPropertiesOptions() - .setAccessCondition(AccessCondition.ifModifiedSince(currentLastModifiedDate))); + CreateBlobResult result = service.createPageBlob(container, blob, 4096); + Date tenSecondsFromNow = new Date(result.getLastModified().getTime() + 10000); + service.getBlobProperties(container, blob, + new GetBlobPropertiesOptions().setAccessCondition(AccessCondition.ifModifiedSince(tenSecondsFromNow))); // Assert assertTrue(false); From ca16a5acfdac9851c97af0b5cd242bb32b60bafd Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 17 Oct 2012 10:02:08 -0700 Subject: [PATCH 16/16] Fix #144 by moving $root create/delete to the Before/After class method. --- .../blob/BlobServiceIntegrationTest.java | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java index 853132a00da13..d1fbb29871d6b 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java @@ -91,6 +91,7 @@ public class BlobServiceIntegrationTest extends IntegrationTestBase { private static String TEST_CONTAINER_FOR_LISTING; private static String[] creatableContainers; private static String[] testContainers; + private static boolean createdRoot; @BeforeClass public static void setup() throws Exception { @@ -120,6 +121,14 @@ public static void setup() throws Exception { BlobContract service = BlobService.create(config); createContainers(service, testContainersPrefix, testContainers); + + try { + service.createContainer("$root"); + createdRoot = true; + } + catch (ServiceException e) { + e.printStackTrace(); + } } @AfterClass @@ -129,6 +138,17 @@ public static void cleanup() throws Exception { deleteContainers(service, testContainersPrefix, testContainers); deleteContainers(service, createableContainersPrefix, creatableContainers); + + // If container was created, delete it + if (createdRoot) { + try { + service.deleteContainer("$root"); + createdRoot = false; + } + catch (ServiceException e) { + e.printStackTrace(); + } + } } private static void createContainers(BlobContract service, String prefix, String[] list) throws Exception { @@ -464,20 +484,6 @@ public void workingWithRootContainersWorks() throws Exception { Configuration config = createConfiguration(); BlobContract service = BlobService.create(config); - // - // Ensure root container exists - // - ServiceException error = null; - try { - service.createContainer("$root"); - } - catch (ServiceException e) { - error = e; - } - - // Assert - assertTrue(error == null || error.getHttpStatusCode() == 409); - // // Work with root container explicitly ("$root") // @@ -518,11 +524,6 @@ public void workingWithRootContainersWorks() throws Exception { // Act service.deleteBlob("", BLOB_FOR_ROOT_CONTAINER); } - - // If container was created, delete it - if (error == null) { - service.deleteContainer("$root"); - } } @Test