You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2013/05/15 22:29:21 UTC
[2/2] git commit: [JCLOUDS-43] add scoped transaction support to
ultradns-ws
[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 <ad...@gmail.com>
Authored: Wed May 15 12:05:57 2013 -0700
Committer: adriancole <ad...@gmail.com>
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