summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--aai-resources/bundleconfig-local/etc/appprops/aaiconfig.properties4
-rw-r--r--aai-resources/bundleconfig-local/etc/appprops/error.properties1
-rw-r--r--aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java55
-rw-r--r--aai-resources/src/test/java/org/onap/aai/rest/BulkAddConsumerTest.java24
-rw-r--r--aai-resources/src/test/java/org/onap/aai/rest/BulkProcessConsumerTest.java24
-rw-r--r--aai-resources/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties2
-rw-r--r--aai-resources/src/test/resources/bundleconfig-local/etc/appprops/error.properties1
-rw-r--r--aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-exceed.json229
-rw-r--r--aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-meet.json222
9 files changed, 556 insertions, 6 deletions
diff --git a/aai-resources/bundleconfig-local/etc/appprops/aaiconfig.properties b/aai-resources/bundleconfig-local/etc/appprops/aaiconfig.properties
index 98d4c57..27a744c 100644
--- a/aai-resources/bundleconfig-local/etc/appprops/aaiconfig.properties
+++ b/aai-resources/bundleconfig-local/etc/appprops/aaiconfig.properties
@@ -147,3 +147,7 @@ aai.server.rebind=g
# This is a fake one just for test so please ignore
ecm.auth.password.x=OBF:1igd1i9a1jnb1yte1vv11vu91yt81jk71i6o1idt
aai.run.migrations=false
+aai.jms.enable=false
+
+#limit set for bulk consumer APIS
+aai.bulkconsumer.payloadlimit=30
diff --git a/aai-resources/bundleconfig-local/etc/appprops/error.properties b/aai-resources/bundleconfig-local/etc/appprops/error.properties
index 9ad86ec..a20dce5 100644
--- a/aai-resources/bundleconfig-local/etc/appprops/error.properties
+++ b/aai-resources/bundleconfig-local/etc/appprops/error.properties
@@ -114,6 +114,7 @@ AAI_6143=5:4:INFO:6143:400:3000:Ghost vertex found
AAI_6144=5:4:WARN:6144:400:3000:Cycle found in graph
AAI_6145=5:4:ERROR:6145:400:3000:Cannot create a nested/containment edge via relationship
AAI_6146=5:4:ERROR:6146:400:3000:Ambiguous identity map found, use a URI instead
+AAI_6147=5:4:ERROR:6147:400:3000:Payload Limit Reached, reduce payload
#--- aaicsvp: 7101-7199
AAI_7101=5:4:ERROR:7101:500:3002:Unexpected error in CSV file processing
diff --git a/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java b/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java
index 5591ae3..5ff0e35 100644
--- a/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java
+++ b/aai-resources/src/main/java/org/onap/aai/rest/BulkConsumer.java
@@ -24,8 +24,11 @@ package org.onap.aai.rest;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
+import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
@@ -60,6 +63,8 @@ import org.onap.aai.restcore.HttpMethod;
import org.onap.aai.restcore.RESTAPI;
import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.util.AAIConfig;
+import org.onap.aai.util.AAIConstants;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
@@ -250,12 +255,7 @@ public abstract class BulkConsumer extends RESTAPI {
throw new AAIException("AAI_6111", String.format("input payload does not follow %s interface", module));
}
JsonArray transactions = transactionsObj.getAsJsonArray();
- if (transactions.size() == 0) {
- //case where user sends a validly formatted transactions object but
- //which has no actual things in it for A&AI to do anything with
- //assuming we should count this as a user error
- throw new AAIException("AAI_6118", "payload had no objects to operate on");
- }
+ validateRequest(transactions);
return transactions;
}
@@ -531,6 +531,49 @@ public abstract class BulkConsumer extends RESTAPI {
}
}
+ /**
+ * Pulls the config value for the limit of operations allowed in a bulk add/process request
+ *
+ * @throws AAIException
+ */
+ private int getPayLoadLimit() throws AAIException{
+ return Integer.parseInt(AAIConfig.get(AAIConstants.AAI_BULKCONSUMER_LIMIT));
+ }
+
+ /**
+ * Validates the amount of operations in a request payload is allowed
+ *
+ * @param transactions - a JsonArray of all the transactions in the request payload
+ * @throws AAIException
+ */
+ private void validateRequest(JsonArray transactions) throws AAIException{
+ if (transactions.size() == 0) {
+ //case where user sends a validly formatted transactions object but
+ //which has no actual things in it for A&AI to do anything with
+ //assuming we should count this as a user error
+ throw new AAIException("AAI_6118", "payload had no objects to operate on");
+ }else if(transactions.size() > getPayLoadLimit()) {
+ throw new AAIException("AAI_6147", String.format("Payload limit of %s reached, please reduce payload.", getPayLoadLimit()));
+ }
+ int operationCount = 0;
+ int payLoadLimit = getPayLoadLimit();
+ for(int i = 0; i < transactions.size(); i++){
+ Set<Entry<String, JsonElement>> entrySet = transactions.get(i).getAsJsonObject().entrySet();
+ Iterator<Entry<String, JsonElement>> it = entrySet.iterator();
+ while(it.hasNext()){
+ Map.Entry<String, JsonElement> element = it.next();
+ if(element.getValue() instanceof JsonArray) {
+ operationCount += ((JsonArray) element.getValue()).size();
+ }else{
+ operationCount++;
+ }
+ }
+ if(operationCount > payLoadLimit){
+ throw new AAIException("AAI_6147", String.format("Payload limit of %s reached, please reduce payload.", payLoadLimit));
+ }
+ }
+ }
+
protected abstract String getModule();
protected abstract boolean functionAllowed(HttpMethod method);
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/BulkAddConsumerTest.java b/aai-resources/src/test/java/org/onap/aai/rest/BulkAddConsumerTest.java
index 66afeeb..e734d98 100644
--- a/aai-resources/src/test/java/org/onap/aai/rest/BulkAddConsumerTest.java
+++ b/aai-resources/src/test/java/org/onap/aai/rest/BulkAddConsumerTest.java
@@ -107,6 +107,30 @@ public class BulkAddConsumerTest extends BulkProcessorTestAbstraction {
assertEquals("Bad Request", Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
assertEquals("Contains error code", true, response.getEntity().toString().contains("ERR.5.4.6111"));
}
+
+ @Test
+ public void bulkAddCheckMeetsLimit() throws IOException{
+ when(uriInfo.getPath()).thenReturn(uri);
+ when(uriInfo.getPath(false)).thenReturn(uri);
+
+ String payload = getBulkPayload("pserver-bulk-limit-meet");
+ Response response = executeRequest(payload);
+
+ assertEquals("Created", Response.Status.CREATED.getStatusCode(), response.getStatus());
+ assertEquals("Contains 30 {\"201\":null}", 30, StringUtils.countMatches(response.getEntity().toString(), "{\"201\":null}"));
+ }
+
+ @Test
+ public void bulkAddCheckExceedsLimit() throws IOException{
+ when(uriInfo.getPath()).thenReturn(uri);
+ when(uriInfo.getPath(false)).thenReturn(uri);
+
+ String payload = getBulkPayload("pserver-bulk-limit-exceed");
+ Response response = executeRequest(payload);
+
+ assertEquals("Bad Request", Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertEquals("Contains error code", true, response.getEntity().toString().contains("ERR.5.4.6147"));
+ }
@Override
protected BulkConsumer getConsumer(){
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/BulkProcessConsumerTest.java b/aai-resources/src/test/java/org/onap/aai/rest/BulkProcessConsumerTest.java
index 8a75a96..1e3a4e4 100644
--- a/aai-resources/src/test/java/org/onap/aai/rest/BulkProcessConsumerTest.java
+++ b/aai-resources/src/test/java/org/onap/aai/rest/BulkProcessConsumerTest.java
@@ -246,6 +246,30 @@ public class BulkProcessConsumerTest extends BulkProcessorTestAbstraction {
assertEquals("Bad Request", Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
assertEquals("Contains error code", true, response.getEntity().toString().contains("ERR.5.4.6111"));
}
+ @Test
+ public void bulkProcessCheckMeetsLimit() throws IOException{
+ when(uriInfo.getPath()).thenReturn(uri);
+ when(uriInfo.getPath(false)).thenReturn(uri);
+
+ String payload = getBulkPayload("pserver-bulk-limit-meet");
+ Response response = executeRequest(payload);
+
+ assertEquals("Created", Response.Status.CREATED.getStatusCode(), response.getStatus());
+ //assertEquals("Contains error code", true, response.getEntity().toString().contains("ERR.5.4.6147"));
+ assertEquals("Contains 30 {\"201\":null}", 30, StringUtils.countMatches(response.getEntity().toString(), "{\"201\":null}"));
+ }
+
+ @Test
+ public void bulkProcessCheckExceedsLimit() throws IOException{
+ when(uriInfo.getPath()).thenReturn(uri);
+ when(uriInfo.getPath(false)).thenReturn(uri);
+
+ String payload = getBulkPayload("pserver-bulk-limit-exceed");
+ Response response = executeRequest(payload);
+
+ assertEquals("Bad Request", Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertEquals("Contains error code", true, response.getEntity().toString().contains("ERR.5.4.6147"));
+ }
@Override
protected BulkConsumer getConsumer(){
diff --git a/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties b/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties
index 5ba1e0f..d406c04 100644
--- a/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties
+++ b/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties
@@ -144,3 +144,5 @@ aai.run.migrations=false
ecm.auth.password.x=OBF:1igd1i9a1jnb1yte1vv11vu91yt81jk71i6o1idt
aai.jms.enable=false
+#limit set for bulk consumer APIS
+aai.bulkconsumer.payloadlimit=30
diff --git a/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/error.properties b/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/error.properties
index 11416ca..10f1177 100644
--- a/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/error.properties
+++ b/aai-resources/src/test/resources/bundleconfig-local/etc/appprops/error.properties
@@ -111,6 +111,7 @@ AAI_6143=5:4:INFO:6143:400:3000:Ghost vertex found
AAI_6144=5:4:WARN:6144:400:3000:Cycle found in graph
AAI_6145=5:4:ERROR:6145:400:3000:Cannot create a nested/containment edge via relationship
AAI_6146=5:4:ERROR:6146:400:3000:Ambiguous identity map found, use a URI instead
+AAI_6147=5:4:ERROR:6147:400:3000:Payload Limit Reached, reduce payload
#--- aaicsvp: 7101-7199
AAI_7101=5:4:ERROR:7101:500:3002:Unexpected error in CSV file processing
diff --git a/aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-exceed.json b/aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-exceed.json
new file mode 100644
index 0000000..60a96dd
--- /dev/null
+++ b/aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-exceed.json
@@ -0,0 +1,229 @@
+{
+ "transactions": [
+ {
+ "put": [
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-1-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-1-<UUID>",
+ "fqdn": "fake-fqdn-1"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-2-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-2-<UUID>",
+ "fqdn": "fake-fqdn-2"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-3-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-3-<UUID>",
+ "fqdn": "fake-fqdn-3"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-4-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-4-<UUID>",
+ "fqdn": "fake-fqdn-4"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-5-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-5-<UUID>",
+ "fqdn": "fake-fqdn-5"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-6-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-6-<UUID>",
+ "fqdn": "fake-fqdn-6"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-7-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-7-<UUID>",
+ "fqdn": "fake-fqdn-7"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-8-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-8-<UUID>",
+ "fqdn": "fake-fqdn-8"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-9-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-9-<UUID>",
+ "fqdn": "fake-fqdn-9"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-10-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-10-<UUID>",
+ "fqdn": "fake-fqdn-10"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-11-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-11-<UUID>",
+ "fqdn": "fake-fqdn-11"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-12-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-12-<UUID>",
+ "fqdn": "fake-fqdn-12"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-13-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-13-<UUID>",
+ "fqdn": "fake-fqdn-13"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-14-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-14-<UUID>",
+ "fqdn": "fake-fqdn-14"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-15-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-15-<UUID>",
+ "fqdn": "fake-fqdn-15"
+ }
+ }
+ ]
+ },
+ {
+ "put": [
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-16-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-16-<UUID>",
+ "fqdn": "fake-fqdn-16"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-17-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-17-<UUID>",
+ "fqdn": "fake-fqdn-17"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-18-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-18-<UUID>",
+ "fqdn": "fake-fqdn-18"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-19-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-19-<UUID>",
+ "fqdn": "fake-fqdn-19"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-20-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-20-<UUID>",
+ "fqdn": "fake-fqdn-20"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-21-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-21-<UUID>",
+ "fqdn": "fake-fqdn-21"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-22-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-22-<UUID>",
+ "fqdn": "fake-fqdn-22"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-23-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-23-<UUID>",
+ "fqdn": "fake-fqdn-23"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-24-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-24-<UUID>",
+ "fqdn": "fake-fqdn-24"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-25-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-25-<UUID>",
+ "fqdn": "fake-fqdn-25"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-26-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-26-<UUID>",
+ "fqdn": "fake-fqdn-26"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-27-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-27-<UUID>",
+ "fqdn": "fake-fqdn-27"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-28-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-28-<UUID>",
+ "fqdn": "fake-fqdn-28"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-29-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-29-<UUID>",
+ "fqdn": "fake-fqdn-29"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-30-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-30-<UUID>",
+ "fqdn": "fake-fqdn-30"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-31-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-31-<UUID>",
+ "fqdn": "fake-fqdn-31"
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-meet.json b/aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-meet.json
new file mode 100644
index 0000000..b06a846
--- /dev/null
+++ b/aai-resources/src/test/resources/payloads/bulk/pserver-bulk-limit-meet.json
@@ -0,0 +1,222 @@
+{
+ "transactions": [
+ {
+ "put": [
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-1-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-1-<UUID>",
+ "fqdn": "fake-fqdn-1"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-2-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-2-<UUID>",
+ "fqdn": "fake-fqdn-2"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-3-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-3-<UUID>",
+ "fqdn": "fake-fqdn-3"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-4-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-4-<UUID>",
+ "fqdn": "fake-fqdn-4"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-5-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-5-<UUID>",
+ "fqdn": "fake-fqdn-5"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-6-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-6-<UUID>",
+ "fqdn": "fake-fqdn-6"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-7-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-7-<UUID>",
+ "fqdn": "fake-fqdn-7"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-8-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-8-<UUID>",
+ "fqdn": "fake-fqdn-8"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-9-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-9-<UUID>",
+ "fqdn": "fake-fqdn-9"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-10-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-10-<UUID>",
+ "fqdn": "fake-fqdn-10"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-11-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-11-<UUID>",
+ "fqdn": "fake-fqdn-11"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-12-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-12-<UUID>",
+ "fqdn": "fake-fqdn-12"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-13-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-13-<UUID>",
+ "fqdn": "fake-fqdn-13"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-14-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-14-<UUID>",
+ "fqdn": "fake-fqdn-14"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-15-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-15-<UUID>",
+ "fqdn": "fake-fqdn-15"
+ }
+ }
+ ]
+ },
+ {
+ "put": [
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-16-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-16-<UUID>",
+ "fqdn": "fake-fqdn-16"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-17-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-17-<UUID>",
+ "fqdn": "fake-fqdn-17"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-18-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-18-<UUID>",
+ "fqdn": "fake-fqdn-18"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-19-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-19-<UUID>",
+ "fqdn": "fake-fqdn-19"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-20-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-20-<UUID>",
+ "fqdn": "fake-fqdn-20"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-21-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-21-<UUID>",
+ "fqdn": "fake-fqdn-21"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-22-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-22-<UUID>",
+ "fqdn": "fake-fqdn-22"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-23-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-23-<UUID>",
+ "fqdn": "fake-fqdn-23"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-24-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-24-<UUID>",
+ "fqdn": "fake-fqdn-24"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-25-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-25-<UUID>",
+ "fqdn": "fake-fqdn-25"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-26-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-26-<UUID>",
+ "fqdn": "fake-fqdn-26"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-27-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-27-<UUID>",
+ "fqdn": "fake-fqdn-27"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-28-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-28-<UUID>",
+ "fqdn": "fake-fqdn-28"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-29-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-29-<UUID>",
+ "fqdn": "fake-fqdn-29"
+ }
+ },
+ {
+ "uri": "/cloud-infrastructure/pservers/pserver/pserver-transactions-30-<UUID>",
+ "body": {
+ "hostname": "pserver-transactions-30-<UUID>",
+ "fqdn": "fake-fqdn-30"
+ }
+ }
+ ]
+ }
+ ]
+}