Cleanup output-only Operation object.
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/20c397c7 Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/20c397c7 Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/20c397c7 Branch: refs/heads/master Commit: 20c397c7fbf82eeee41590821689f6eedcb49ac0 Parents: f4af63f Author: Adrian Cole <[email protected]> Authored: Mon Oct 20 09:59:13 2014 -0400 Committer: Adrian Cole <[email protected]> Committed: Mon Oct 20 13:26:54 2014 -0400 ---------------------------------------------------------------------- .../jclouds/azurecompute/domain/Operation.java | 180 +++++-------------- .../azurecompute/xml/OperationHandler.java | 81 ++++----- .../features/HostedServiceApiLiveTest.java | 2 +- .../features/OperationApiMockTest.java | 14 +- .../azurecompute/parse/GetOperationTest.java | 53 ------ .../azurecompute/xml/OperationHandlerTest.java | 41 +++++ 6 files changed, 124 insertions(+), 247 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/20c397c7/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Operation.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Operation.java b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Operation.java index eb336f4..0c0b02a 100644 --- a/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Operation.java +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/domain/Operation.java @@ -16,168 +16,62 @@ */ package org.jclouds.azurecompute.domain; -import com.google.common.base.CaseFormat; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import com.google.common.base.Optional; - +import static com.google.common.base.Objects.equal; import static com.google.common.base.Preconditions.checkNotNull; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.Objects; + /** * - * Determines whether the operation has succeeded, failed, or is still in progress. + * Determines whether the asynchronous operation has succeeded, failed, or is still in progress. * * @see <a href="http://msdn.microsoft.com/en-us/library/ee460783" >api</a> */ -public class Operation { - - public static enum Status { - - IN_PROGRESS, - - SUCCEEDED, - - FAILED, - +public final class Operation { + public enum Status { + IN_PROGRESS, SUCCEEDED, FAILED, UNRECOGNIZED; - - public String value() { - return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); - } - - @Override - public String toString() { - return value(); - } - - public static Status fromValue(String status) { - try { - return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(status, "status"))); - } catch (IllegalArgumentException e) { - return UNRECOGNIZED; - } - } - } - - public static Builder builder() { - return new Builder(); - } - - public Builder toBuilder() { - return builder().fromOperation(this); } - public static class Builder { - - private String id; - private String rawStatus; - private Status status; - // When the operation is in progress, no status code is returned - private Optional<Integer> httpStatusCode = Optional.absent(); - private Optional<Error> error = Optional.absent(); - - /** - * @see Operation#getId() - */ - public Builder id(String id) { - this.id = id; - return this; - } - - /** - * @see Operation#getRawStatus() - */ - public Builder rawStatus(String rawStatus) { - this.rawStatus = rawStatus; - return this; - } - - /** - * @see Operation#getStatus() - */ - public Builder status(Status status) { - this.status = status; - return this; - } - - /** - * @see Operation#getHttpStatusCode() - */ - public Builder httpStatusCode(Integer httpStatusCode) { - this.httpStatusCode = Optional.fromNullable(httpStatusCode); - return this; - } - - /** - * @see Operation#getError() - */ - public Builder error(Error error) { - this.error = Optional.fromNullable(error); - return this; - } - - public Operation build() { - return new Operation(id, rawStatus, status, httpStatusCode, error); - } - - public Builder fromOperation(Operation in) { - return this.id(in.id).rawStatus(in.rawStatus).status(in.status).httpStatusCode(in.httpStatusCode.orNull()) - .error(in.error.orNull()); - } + public String id() { + return id; } - private final String id; - private final String rawStatus; - private final Status status; - private final Optional<Integer> httpStatusCode; - private final Optional<Error> error; - - protected Operation(String id, String rawStatus, Status status, Optional<Integer> httpStatusCode, Optional<Error> error) { - this.id = checkNotNull(id, "id"); - this.rawStatus = checkNotNull(rawStatus, "rawStatus for %s", id); - this.status = checkNotNull(status, "status for %s", id); - this.httpStatusCode = checkNotNull(httpStatusCode, "httpStatusCode for %s", id); - this.error = checkNotNull(error, "error for %s", id); + public Status status() { + return status; } - /** - * The request ID of the asynchronous request. - */ - public String getId() { - return id; + @Nullable public Integer httpStatusCode() { + return httpStatusCode; } - /** - * The status of the asynchronous request. - */ - public Status getStatus() { - return status; + /** Present when the operation {@link Status#FAILED failed}. */ + @Nullable public Error error() { + return error; } - /** - * The status of the asynchronous request, unparsed - */ - public String getRawStatus() { - return rawStatus; + public static Operation create(String id, Status status, Integer httpStatusCode, Error error) { + return new Operation(id, status, httpStatusCode, error); } - /** - * The HTTP status code for the asynchronous request. - */ - public Optional<Integer> getHttpStatusCode() { - return httpStatusCode; + // TODO: Remove from here down with @AutoValue. + private Operation(String id, Status status, Integer httpStatusCode, Error error) { + this.id = checkNotNull(id, "id"); + this.status = checkNotNull(status, "status"); + this.httpStatusCode = httpStatusCode; + this.error = error; } - /** - * The management service error returned if the asynchronous request failed. - */ - public Optional<Error> getError() { - return error; - } + private final String id; + private final Status status; + private final Integer httpStatusCode; + private final Error error; @Override public int hashCode() { - return Objects.hashCode(id); + return Objects.hashCode(id, status, httpStatusCode, error); } @Override @@ -189,12 +83,18 @@ public class Operation { if (getClass() != obj.getClass()) return false; Operation other = (Operation) obj; - return Objects.equal(this.id, other.id); + return equal(this.id, other.id) && + equal(this.status, other.status) && + equal(this.httpStatusCode, other.httpStatusCode) && + equal(this.error, other.error); } @Override public String toString() { - return MoreObjects.toStringHelper(this).omitNullValues().add("id", id).add("status", rawStatus) - .add("httpStatusCode", httpStatusCode).add("error", error.orNull()).toString(); + return Objects.toStringHelper(this) + .add("id", id) + .add("status", status) + .add("httpStatusCode", httpStatusCode) + .add("error", error).toString(); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/20c397c7/azurecompute/src/main/java/org/jclouds/azurecompute/xml/OperationHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/OperationHandler.java b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/OperationHandler.java index e0a6912..e417be1 100644 --- a/azurecompute/src/main/java/org/jclouds/azurecompute/xml/OperationHandler.java +++ b/azurecompute/src/main/java/org/jclouds/azurecompute/xml/OperationHandler.java @@ -16,82 +16,69 @@ */ package org.jclouds.azurecompute.xml; -import javax.inject.Inject; +import static com.google.common.base.CaseFormat.UPPER_CAMEL; +import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; +import static org.jclouds.util.SaxUtils.currentOrNull; + +import org.jclouds.azurecompute.domain.Error; import org.jclouds.azurecompute.domain.Operation; -import org.jclouds.azurecompute.domain.Operation.Builder; import org.jclouds.azurecompute.domain.Operation.Status; import org.jclouds.http.functions.ParseSax; import org.xml.sax.Attributes; -import org.xml.sax.SAXException; - -import static org.jclouds.util.SaxUtils.currentOrNull; -import static org.jclouds.util.SaxUtils.equalsOrSuffix; /** * @see <a href="http://msdn.microsoft.com/en-us/library/ee460783" >api</a> */ -public class OperationHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Operation> { - - private final ErrorHandler errorHandler; - - @Inject - private OperationHandler(ErrorHandler errorHandler) { - this.errorHandler = errorHandler; - } - - private StringBuilder currentText = new StringBuilder(); - private Operation.Builder builder = builder(); - - private Builder builder() { - return Operation.builder(); - } +public final class OperationHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Operation> { + private String id; + private Status status; + private Integer httpStatusCode; + private Error error; private boolean inError; + private final ErrorHandler errorHandler = new ErrorHandler(); + private final StringBuilder currentText = new StringBuilder(); - @Override - public Operation getResult() { - try { - return builder.build(); - } finally { - builder = builder(); - } + @Override public Operation getResult() { + return Operation.create(id, status, httpStatusCode, error); } - @Override - public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { - if (equalsOrSuffix(qName, "Error")) { + @Override public void startElement(String url, String name, String qName, Attributes attributes) { + if (qName.equals("Error")) { inError = true; } - if (inError) { - errorHandler.startElement(url, name, qName, attributes); - } } - @Override - public void endElement(String uri, String name, String qName) throws SAXException { - if (equalsOrSuffix(qName, "Error")) { - builder.error(errorHandler.getResult()); + @Override public void endElement(String uri, String name, String qName) { + if (qName.equals("Error")) { + error = errorHandler.getResult(); inError = false; } else if (inError) { errorHandler.endElement(uri, name, qName); - } else if (equalsOrSuffix(qName, "ID")) { - builder.id(currentOrNull(currentText)); + } else if (qName.equals("ID")) { + id = currentOrNull(currentText); } else if (qName.equals("Status")) { - String rawStatus = currentOrNull(currentText); - builder.rawStatus(rawStatus); - builder.status(Status.fromValue(rawStatus)); - } else if (equalsOrSuffix(qName, "HttpStatusCode")) { - builder.httpStatusCode(Integer.parseInt(currentOrNull(currentText))); + String statusText = currentOrNull(currentText); + status = parseStatus(statusText); + } else if (qName.equals("HttpStatusCode")) { + httpStatusCode = Integer.parseInt(currentOrNull(currentText)); } currentText.setLength(0); } - @Override - public void characters(char ch[], int start, int length) { + @Override public void characters(char ch[], int start, int length) { if (inError) { errorHandler.characters(ch, start, length); } else { currentText.append(ch, start, length); } } + + private static Status parseStatus(String status) { + try { + return Status.valueOf(UPPER_CAMEL.to(UPPER_UNDERSCORE, status)); + } catch (IllegalArgumentException e) { + return Status.UNRECOGNIZED; + } + } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/20c397c7/azurecompute/src/test/java/org/jclouds/azurecompute/features/HostedServiceApiLiveTest.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/HostedServiceApiLiveTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/HostedServiceApiLiveTest.java index eb0eec8..894c0de 100644 --- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/HostedServiceApiLiveTest.java +++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/HostedServiceApiLiveTest.java @@ -57,7 +57,7 @@ public class HostedServiceApiLiveTest extends BaseAzureComputeApiLiveTest { location = Iterables.get(api.getLocationApi().list(), 0).name(); operationSucceeded = retry(new Predicate<String>() { public boolean apply(String input) { - return api.getOperationApi().get(input).getStatus() == Operation.Status.SUCCEEDED; + return api.getOperationApi().get(input).status() == Operation.Status.SUCCEEDED; } }, 600, 5, 5, SECONDS); hostedServiceCreated = retry(new Predicate<HostedService>() { http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/20c397c7/azurecompute/src/test/java/org/jclouds/azurecompute/features/OperationApiMockTest.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/features/OperationApiMockTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/features/OperationApiMockTest.java index 2298bc0..dae2053 100644 --- a/azurecompute/src/test/java/org/jclouds/azurecompute/features/OperationApiMockTest.java +++ b/azurecompute/src/test/java/org/jclouds/azurecompute/features/OperationApiMockTest.java @@ -16,13 +16,15 @@ */ package org.jclouds.azurecompute.features; -import com.squareup.okhttp.mockwebserver.MockResponse; -import com.squareup.okhttp.mockwebserver.MockWebServer; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + import org.jclouds.azurecompute.internal.BaseAzureComputeApiMockTest; -import org.jclouds.azurecompute.parse.GetOperationTest; +import org.jclouds.azurecompute.xml.OperationHandlerTest; import org.testng.annotations.Test; -import static org.assertj.core.api.Assertions.assertThat; +import com.squareup.okhttp.mockwebserver.MockResponse; +import com.squareup.okhttp.mockwebserver.MockWebServer; @Test(groups = "unit", testName = "OperationApiMockTest") public class OperationApiMockTest extends BaseAzureComputeApiMockTest { @@ -34,7 +36,7 @@ public class OperationApiMockTest extends BaseAzureComputeApiMockTest { try { OperationApi api = api(server.getUrl("/")).getOperationApi(); - assertThat(api.get("request-id")).isEqualTo(GetOperationTest.expected()); + assertEquals(api.get("request-id"), OperationHandlerTest.expected()); assertSent(server, "GET", "/operations/request-id"); } finally { @@ -49,7 +51,7 @@ public class OperationApiMockTest extends BaseAzureComputeApiMockTest { try { OperationApi api = api(server.getUrl("/")).getOperationApi(); - assertThat(api.get("request-id")).isNull(); + assertNull(api.get("request-id")); assertSent(server, "GET", "/operations/request-id"); } finally { http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/20c397c7/azurecompute/src/test/java/org/jclouds/azurecompute/parse/GetOperationTest.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/parse/GetOperationTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/parse/GetOperationTest.java deleted file mode 100644 index 8e41f81..0000000 --- a/azurecompute/src/test/java/org/jclouds/azurecompute/parse/GetOperationTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.azurecompute.parse; - -import static org.testng.Assert.assertEquals; - -import java.io.InputStream; - -import org.jclouds.azurecompute.domain.Operation; -import org.jclouds.azurecompute.domain.Operation.Status; -import org.jclouds.azurecompute.xml.ErrorHandlerTest; -import org.jclouds.azurecompute.xml.OperationHandler; -import org.jclouds.http.functions.BaseHandlerTest; -import org.testng.annotations.Test; - -@Test(groups = "unit", testName = "GetOperationTest") -public class GetOperationTest extends BaseHandlerTest { - - public void test() { - InputStream is = getClass().getResourceAsStream("/operation.xml"); - - Operation expected = expected(); - - OperationHandler handler = injector.getInstance(OperationHandler.class); - Operation result = factory.create(handler).parse(is); - - assertEquals(result.toString(), expected.toString()); - } - - public static Operation expected() { - return Operation.builder() - .id("request-id") - .rawStatus("Failed") - .status(Status.FAILED) - .httpStatusCode(400) - .error(ErrorHandlerTest.expected()) - .build(); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/20c397c7/azurecompute/src/test/java/org/jclouds/azurecompute/xml/OperationHandlerTest.java ---------------------------------------------------------------------- diff --git a/azurecompute/src/test/java/org/jclouds/azurecompute/xml/OperationHandlerTest.java b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/OperationHandlerTest.java new file mode 100644 index 0000000..635c5df --- /dev/null +++ b/azurecompute/src/test/java/org/jclouds/azurecompute/xml/OperationHandlerTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.xml; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.azurecompute.domain.Operation; +import org.jclouds.azurecompute.domain.Operation.Status; +import org.jclouds.http.functions.BaseHandlerTest; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "OperationHandlerTest") +public class OperationHandlerTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/operation.xml"); + Operation result = factory.create(new OperationHandler()).parse(is); + + assertEquals(result, expected()); + } + + public static Operation expected() { + return Operation.create("request-id", Status.FAILED, 400, ErrorHandlerTest.expected()); + } +}
