diff --git a/azure/src/main/java/org/jclouds/azure/storage/handlers/ParseAzureStorageErrorFromXmlContent.java b/azure/src/main/java/org/jclouds/azure/storage/handlers/ParseAzureStorageErrorFromXmlContent.java index bff7ce6417..cf0cbd58ce 100644 --- a/azure/src/main/java/org/jclouds/azure/storage/handlers/ParseAzureStorageErrorFromXmlContent.java +++ b/azure/src/main/java/org/jclouds/azure/storage/handlers/ParseAzureStorageErrorFromXmlContent.java @@ -64,17 +64,33 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler { public void handleError(HttpCommand command, HttpResponse response) { Exception exception = new HttpResponseException(command, response); + String message = null; try { - AzureStorageError error = parseErrorFromContentOrNull(command, response); + if (response.getPayload() != null) { + String contentType = response.getPayload().getContentMetadata().getContentType(); + if (contentType != null && (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)) { + AzureStorageError error = utils.parseAzureStorageErrorFromContent(command, response, response + .getPayload().getInput()); + if (error != null) { + message = error.getMessage(); + exception = new AzureStorageResponseException(command, response, error); + } + } else { + try { + message = Utils.toStringAndClose(response.getPayload().getInput()); + } catch (IOException e) { + } + } + } + message = message != null ? message : String.format("%s -> %s", command.getRequest().getRequestLine(), + response.getStatusLine()); switch (response.getStatusCode()) { case 401: - exception = new AuthorizationException(command.getRequest(), error != null ? error - .getMessage() : response.getStatusLine()); + exception = new AuthorizationException(command.getRequest(), message); break; case 404: + if (!command.getRequest().getMethod().equals("DELETE")) { - String message = error != null ? error.getMessage() : String.format("%s -> %s", - command.getRequest().getRequestLine(), response.getStatusLine()); String path = command.getRequest().getEndpoint().getPath(); Matcher matcher = CONTAINER_PATH.matcher(path); if (matcher.find()) { @@ -82,15 +98,14 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler { } else { matcher = CONTAINER_KEY_PATH.matcher(path); if (matcher.find()) { - exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), - message); + exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message); } } } break; - default: - exception = error != null ? new AzureStorageResponseException(command, response, - error) : new HttpResponseException(command, response); + case 411: + exception = new IllegalArgumentException(message); + break; } } finally { releasePayload(response); @@ -98,17 +113,4 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler { } } - AzureStorageError parseErrorFromContentOrNull(HttpCommand command, HttpResponse response) { - if (response.getPayload() != null) { - try { - String content = Utils.toStringAndClose(response.getPayload().getInput()); - if (content != null && content.indexOf('<') >= 0) - return utils.parseAzureStorageErrorFromContent(command, response, Utils - .toInputStream(content)); - } catch (IOException e) { - logger.warn(e, "exception reading error from response", response); - } - } - return null; - } } \ No newline at end of file diff --git a/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java b/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java index 5124a7b789..551ed1fd90 100644 --- a/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java +++ b/azure/src/test/java/org/jclouds/azure/storage/blob/AzureBlobClientLiveTest.java @@ -81,11 +81,9 @@ public class AzureBlobClientLiveTest { protected void setupCredentials() { identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); - credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider - + ".credential"); - endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint"); - apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider - + ".apiversion"); + credential = System.getProperty("test." + provider + ".credential"); + endpoint = System.getProperty("test." + provider + ".endpoint"); + apiversion = System.getProperty("test." + provider + ".apiversion"); } protected Properties setupProperties() { @@ -93,9 +91,12 @@ public class AzureBlobClientLiveTest { overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); overrides.setProperty(provider + ".identity", identity); - overrides.setProperty(provider + ".credential", credential); - overrides.setProperty(provider + ".endpoint", endpoint); - overrides.setProperty(provider + ".apiversion", apiversion); + if (credential != null) + overrides.setProperty(provider + ".credential", credential); + if (endpoint != null) + overrides.setProperty(provider + ".endpoint", endpoint); + if (apiversion != null) + overrides.setProperty(provider + ".apiversion", apiversion); return overrides; } diff --git a/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java b/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java new file mode 100644 index 0000000000..5f19192af7 --- /dev/null +++ b/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java @@ -0,0 +1,105 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.azure.storage.handlers; + +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +import java.net.URI; + +import org.easymock.IArgumentMatcher; +import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.io.Payloads; +import org.jclouds.util.Utils; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class ParseAzureErrorFromXmlContentTest { + + @Test + public void test411WithTextHtmlIllegalArgumentException() { + assertCodeMakes("PUT", URI + .create("https://jclouds.blob.core.windows.net/adriancole-azureblob-413790770?restype=container"), 411, + "Length Required", "text/html; charset=us-ascii", "Length Required\r\n", + IllegalArgumentException.class); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType, + String content, Class expected) { + + ParseAzureStorageErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() { + + @Override + protected void configure() { + bind(SharedKeyLiteAuthentication.class).toInstance(createMock(SharedKeyLiteAuthentication.class)); + } + + }).getInstance(ParseAzureStorageErrorFromXmlContent.class); + + HttpCommand command = createMock(HttpCommand.class); + HttpRequest request = new HttpRequest(method, uri); + HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils + .toInputStream(content))); + response.getPayload().getContentMetadata().setContentType(contentType); + + expect(command.getRequest()).andReturn(request).atLeastOnce(); + command.setException(classEq(expected)); + + replay(command); + + function.handleError(command, response); + + verify(command); + } + + public static Exception classEq(final Class in) { + reportMatcher(new IArgumentMatcher() { + + @Override + public void appendTo(StringBuffer buffer) { + buffer.append("classEq("); + buffer.append(in); + buffer.append(")"); + } + + @Override + public boolean matches(Object arg) { + return arg.getClass() == in; + } + + }); + return null; + } + +} \ No newline at end of file