[JCLOUDS-43] add scoped transaction support to ultradns-ws
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/f88609d1 Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/f88609d1 Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/f88609d1 Branch: refs/heads/master Commit: f88609d1dd05b88ca5124b60359613210503f506 Parents: b021d74 Author: adriancole <[email protected]> Authored: Wed May 15 12:05:57 2013 -0700 Committer: adriancole <[email protected]> Committed: Wed May 15 12:26:09 2013 -0700 ---------------------------------------------------------------------- .../org/jclouds/ultradns/ws/ScopedTransaction.java | 134 +++++++++++++++ .../jclouds/ultradns/ws/UltraDNSWSApiMetadata.java | 7 +- .../ultradns/ws/features/DirectionalGroupApi.java | 6 +- .../ultradns/ws/features/DirectionalPoolApi.java | 6 +- .../ultradns/ws/features/ResourceRecordApi.java | 6 +- .../ultradns/ws/features/RoundRobinPoolApi.java | 6 +- .../org/jclouds/ultradns/ws/features/TaskApi.java | 6 +- .../ws/features/TrafficControllerPoolApi.java | 6 +- .../ultradns/ws/features/TransactionApi.java | 24 +++- .../org/jclouds/ultradns/ws/features/ZoneApi.java | 6 +- .../ultradns/ws/ScopedTransactionExpectTest.java | 55 ++++++ .../ultradns/ws/ScopedTransactionLiveTest.java | 84 +++++++++ .../src/test/resources/create_zone_tx.xml | 1 + 13 files changed, 338 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ScopedTransaction.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ScopedTransaction.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ScopedTransaction.java new file mode 100644 index 0000000..ea64816 --- /dev/null +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/ScopedTransaction.java @@ -0,0 +1,134 @@ +/** + * 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.ultradns.ws; + +import static com.google.common.base.Preconditions.checkState; +import static java.lang.String.format; + +import javax.inject.Inject; + +import org.jclouds.http.HttpException; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpRequestFilter; +import org.jclouds.rest.annotations.Transform; + +import com.google.common.base.Function; +import com.google.inject.AbstractModule; + +/** + * Adds support for implicit transactions. + * + * @author Adrian Cole + */ +public class ScopedTransaction { + + /** + * Sets a scoped transaction. Add to rest calls that start a transaction. + * Make sure that these note a possible IllegalStateException when a + * transaction is already in progress. + * + * <p/> + * + * ex. + * + * <pre> + * ... + * @Transform(ScopedTransaction.Set.class) + * String start() throws IllegalStateException; + * </pre> + * + * @see Transform + */ + public static class Set implements Function<String, String> { + private final ScopedTransaction scope; + + @Inject + private Set(ScopedTransaction scope) { + this.scope = scope; + } + + @Override + public String apply(String in) { + checkState(scope.transactionId.get() == null, "A transaction is already in progress"); + scope.transactionId.set(in); + return in; + } + } + + /** + * Removes a scoped transaction, if present. Add to rest calls that commit or + * rollback a transaction. + * + * <p/> + * + * ex. + * + * <pre> + * ... + * @Transform(ScopedTransaction.Invalidate.class) + * void rollback(String txId); + * </pre> + * + * @see Transform + */ + public static class Remove implements Function<Void, Void> { + private final ScopedTransaction scope; + + @Inject + private Remove(ScopedTransaction scope) { + this.scope = scope; + } + + @Override + public Void apply(Void in) { + scope.transactionId.remove(); + return in; + } + } + + public static class Filter implements HttpRequestFilter { + private final ScopedTransaction scope; + + @Inject + private Filter(ScopedTransaction scope) { + this.scope = scope; + } + + @Override + public HttpRequest filter(HttpRequest request) throws HttpException { + String transactionId = scope.transactionId.get(); + if (transactionId == null) + return request; + String body = request.getPayload().getRawContent().toString(); + body = body.replace("<transactionID />", format("<transactionID>%s</transactionID>", transactionId)); + return request.toBuilder().payload(body).build(); + } + } + + /** + * In order to support implicit transactions, this module must be installed. + */ + public static class Module extends AbstractModule { + public void configure() { + ScopedTransaction scope = new ScopedTransaction(); + bind(ScopedTransaction.class).toInstance(scope); + } + } + + private final ThreadLocal<String> transactionId = new ThreadLocal<String>(); +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java index f0131fd..655271c 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java @@ -25,6 +25,9 @@ import org.jclouds.apis.ApiMetadata; import org.jclouds.rest.internal.BaseHttpApiMetadata; import org.jclouds.ultradns.ws.config.UltraDNSWSHttpApiModule; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + /** * Implementation of {@link ApiMetadata} for Neustar's UltraDNSWS api. * @@ -61,7 +64,9 @@ public class UltraDNSWSApiMetadata extends BaseHttpApiMetadata<UltraDNSWSApi> { .documentation(URI.create("https://portal.ultradns.com/static/docs/NUS_API_XML_SOAP.pdf")) .defaultEndpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") .defaultProperties(UltraDNSWSApiMetadata.defaultProperties()) - .defaultModule(UltraDNSWSHttpApiModule.class); + .defaultModules(ImmutableSet.<Class<? extends Module>> builder() + .add(UltraDNSWSHttpApiModule.class) + .add(ScopedTransaction.Module.class).build()); } @Override http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java index b8b2620..f66e88f 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalGroupApi.java @@ -32,6 +32,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.binders.DirectionalGroupCoordinatesToXML; import org.jclouds.ultradns.ws.domain.AccountLevelGroup; import org.jclouds.ultradns.ws.domain.DirectionalGroup; @@ -51,7 +52,10 @@ import com.google.common.collect.FluentIterable; * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> * @author Adrian Cole */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) +@RequestFilters({ + ScopedTransaction.Filter.class, + SOAPWrapWithPasswordAuth.class +}) @VirtualHost public interface DirectionalGroupApi { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java index 1b7457a..6bf0edf 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/DirectionalPoolApi.java @@ -33,6 +33,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.UltraDNSWSApi; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.DirectionalGroupOverlapException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; @@ -55,7 +56,10 @@ import com.google.common.collect.FluentIterable; * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> * @author Adrian Cole */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) +@RequestFilters({ + ScopedTransaction.Filter.class, + SOAPWrapWithPasswordAuth.class +}) @VirtualHost public interface DirectionalPoolApi { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java index f636b53..6351f2a 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java @@ -30,6 +30,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.binders.ZoneAndResourceRecordToXML; import org.jclouds.ultradns.ws.domain.ResourceRecord; @@ -45,7 +46,10 @@ import com.google.common.collect.FluentIterable; * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> * @author Adrian Cole */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) +@RequestFilters({ + ScopedTransaction.Filter.class, + SOAPWrapWithPasswordAuth.class +}) @VirtualHost public interface ResourceRecordApi { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java index 74590b8..e9aecf0 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java @@ -30,6 +30,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.ResourceRecordDetail; @@ -47,7 +48,10 @@ import com.google.common.collect.FluentIterable; * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> * @author Adrian Cole */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) +@RequestFilters({ + ScopedTransaction.Filter.class, + SOAPWrapWithPasswordAuth.class +}) @VirtualHost public interface RoundRobinPoolApi { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java index a378ba6..80935f0 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java @@ -30,6 +30,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.domain.Task; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; import org.jclouds.ultradns.ws.xml.ElementTextHandler; @@ -43,7 +44,10 @@ import com.google.common.collect.FluentIterable; * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> * @author Adrian Cole */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) +@RequestFilters({ + ScopedTransaction.Filter.class, + SOAPWrapWithPasswordAuth.class +}) @VirtualHost public interface TaskApi { /** http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java index a257391..605bf97 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java @@ -33,6 +33,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.binders.UpdatePoolRecordToXML; import org.jclouds.ultradns.ws.domain.PoolRecordSpec; @@ -54,7 +55,10 @@ import com.google.common.collect.FluentIterable; * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> * @author Adrian Cole */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) +@RequestFilters({ + ScopedTransaction.Filter.class, + SOAPWrapWithPasswordAuth.class +}) @VirtualHost public interface TrafficControllerPoolApi { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TransactionApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TransactionApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TransactionApi.java index 0a555ea..685390e 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TransactionApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TransactionApi.java @@ -26,13 +26,30 @@ import org.jclouds.rest.annotations.Fallback; import org.jclouds.rest.annotations.Payload; import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.Transform; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.TooManyTransactionsException; import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; import org.jclouds.ultradns.ws.xml.ElementTextHandler; /** + * Adds transaction support when performing multiple write commands. + * + * <p/> + * ex. + * + * <pre> + * String txId = ultraDNSApi.getTransactionApi().start(); + * try { + * // perform operations + * ultraDNSApi.getTransactionApi().commit(txId); + * } catch (Throwable t) { + * ultraDNSApi.getTransactionApi().rollback(txId); + * throw propagate(t); + * } + * </pre> * * @see <a href="https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01?wsdl" /> * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> @@ -49,12 +66,15 @@ public interface TransactionApi { * @return id of the transaction created * @throws TooManyTransactionsException * if the maximum concurrent exception limit was hit. + * @throws IllegalStateException + * if another transaction is in progress. */ @Named("startTransaction") @POST @XMLResponseParser(ElementTextHandler.TransactionID.class) @Payload("<v01:startTransaction/>") - String start() throws TooManyTransactionsException; + @Transform(ScopedTransaction.Set.class) + String start() throws TooManyTransactionsException, IllegalStateException; /** * This request commits all of a transactionâs requests and writes them to @@ -68,6 +88,7 @@ public interface TransactionApi { @Named("commitTransaction") @POST @Payload("<v01:commitTransaction><transactionID>{transactionID}</transactionID></v01:commitTransaction>") + @Transform(ScopedTransaction.Remove.class) void commit(@PayloadParam("transactionID") String transactionID) throws ResourceNotFoundException; /** @@ -81,5 +102,6 @@ public interface TransactionApi { @POST @Payload("<v01:rollbackTransaction><transactionID>{transactionID}</transactionID></v01:rollbackTransaction>") @Fallback(VoidOnNotFoundOr404.class) + @Transform(ScopedTransaction.Remove.class) void rollback(@PayloadParam("transactionID") String transactionID); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java index 5466e43..cfee697 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java @@ -31,6 +31,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.ultradns.ws.ScopedTransaction; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.domain.Zone; import org.jclouds.ultradns.ws.domain.Zone.Type; @@ -46,7 +47,10 @@ import com.google.common.collect.FluentIterable; * @see <a href="https://www.ultradns.net/api/NUS_API_XML_SOAP.pdf" /> * @author Adrian Cole */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) +@RequestFilters({ + ScopedTransaction.Filter.class, + SOAPWrapWithPasswordAuth.class +}) @VirtualHost public interface ZoneApi { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionExpectTest.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionExpectTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionExpectTest.java new file mode 100644 index 0000000..0940974 --- /dev/null +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionExpectTest.java @@ -0,0 +1,55 @@ +/** + * 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.ultradns.ws; +import static com.google.common.net.HttpHeaders.HOST; +import static javax.ws.rs.HttpMethod.POST; +import static javax.ws.rs.core.Response.Status.OK; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.ultradns.ws.UltraDNSWSApi; +import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiExpectTest; +import org.testng.annotations.Test; +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ScopedTransactionExpectTest") +public class ScopedTransactionExpectTest extends BaseUltraDNSWSApiExpectTest { + HttpRequest start = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/start_tx.xml", "application/xml")).build(); + + HttpResponse startResponse = HttpResponse.builder().statusCode(OK.getStatusCode()) + .payload(payloadFromResourceWithContentType("/tx_started.xml", "application/xml")).build(); + + HttpRequest createWithTx = HttpRequest.builder().method(POST) + .endpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") + .addHeader(HOST, "ultra-api.ultradns.com:8443") + .payload(payloadFromResourceWithContentType("/create_zone_tx.xml", "application/xml")).build(); + + HttpResponse createResponse = HttpResponse.builder().statusCode(OK.getStatusCode()) + .payload(payloadFromResourceWithContentType("/zone_created.xml", "application/xml")).build(); + + public void testAddTransactionIdWhenTransactionStarted() { + UltraDNSWSApi success = requestsSendResponses(start, startResponse, createWithTx, createResponse); + + success.getTransactionApi().start(); + success.getZoneApi().createInAccount("jclouds.org.", "AAAAAAAAAAAAAAAA"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionLiveTest.java new file mode 100644 index 0000000..16c2398 --- /dev/null +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/ScopedTransactionLiveTest.java @@ -0,0 +1,84 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.ultradns.ws; + +import static java.util.logging.Logger.getAnonymousLogger; +import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; + +import org.jclouds.ultradns.ws.domain.ResourceRecord; +import org.jclouds.ultradns.ws.domain.ZoneProperties; +import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "live", testName = "ScopedTransactionLiveTest") +public class ScopedTransactionLiveTest extends BaseUltraDNSWSApiLiveTest { + + ResourceRecord mx = rrBuilder().name("mail." + zoneName) + .type(15) + .ttl(1800) + .infoValue(10) + .infoValue("maileast.jclouds.org.").build(); + + @Test + public void testMultiStepTransactionOnCommit() { + String txId = api.getTransactionApi().start(); + assertNotNull(txId); + getAnonymousLogger().info("starting transaction: " + txId); + try { + api.getZoneApi().createInAccount(zoneName, account.getId()); + api.getResourceRecordApiForZone(zoneName).create(mx); + + // can't read uncommitted stuff + assertNull(api.getZoneApi().get(zoneName)); + + // commit the tx + api.getTransactionApi().commit(txId); + + // now we can read it + ZoneProperties newZone = api.getZoneApi().get(zoneName); + assertEquals(newZone.getName(), zoneName); + assertEquals(newZone.getResourceRecordCount(), 6); + } finally { + // in case an assertion problem or otherwise occurred in the test. + api.getTransactionApi().rollback(txId); + api.getZoneApi().delete(zoneName); + } + } + + @Test + public void testScopedTransactionOnRollback() { + String txId = api.getTransactionApi().start(); + assertNotNull(txId); + getAnonymousLogger().info("starting transaction: " + txId); + try { + api.getZoneApi().createInAccount(zoneName, account.getId()); + api.getTransactionApi().rollback(txId); + assertNull(api.getZoneApi().get(zoneName)); + } finally { + // in case an assertion problem or otherwise occurred in the test. + api.getZoneApi().delete(zoneName); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/f88609d1/providers/ultradns-ws/src/test/resources/create_zone_tx.xml ---------------------------------------------------------------------- diff --git a/providers/ultradns-ws/src/test/resources/create_zone_tx.xml b/providers/ultradns-ws/src/test/resources/create_zone_tx.xml new file mode 100644 index 0000000..ba40474 --- /dev/null +++ b/providers/ultradns-ws/src/test/resources/create_zone_tx.xml @@ -0,0 +1 @@ +<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://webservice.api.ultra.neustar.com/v01/"><soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken><wsse:Username>identity</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">credential</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header><soapenv:Body><v01:createPrimaryZone><transactionID>jclouds-37562</transactionID><accountId>AAAAAAAAAAAAAAAA</accountId><zoneName>jclouds.org.</zoneName><forceImport>false</forceImport></v01:createPrimaryZone></soapenv:Body></soapenv:Envelope> \ No newline at end of file
