summaryrefslogtreecommitdiffstats
path: root/adapters
diff options
context:
space:
mode:
authorEric Multanen <eric.w.multanen@intel.com>2018-09-25 17:00:35 -0700
committerEric Multanen <eric.w.multanen@intel.com>2018-09-27 23:45:15 -0700
commit52a736802c707d75104dff25d551a1f8df76d100 (patch)
treed36de22097f436fe63dfb46a8a783e93a7de0eae /adapters
parentf09633016b12f728d19cde29afde7b3bc22228ea (diff)
Fix calls to multicloud adapter
Fix up the json body of the POST call to multicloud. Improve checkout of responses from multicloud calls. Change-Id: I1fb47460b54e9e5b478815d3b531d5bdbe1fe3dc Issue-ID: SO-1082 Signed-off-by: Eric Multanen <eric.w.multanen@intel.com>
Diffstat (limited to 'adapters')
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java3
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudParam.java110
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java266
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java77
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java76
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java90
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateStackResponse.java60
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java90
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java120
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java49
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestUtils.java19
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/BaseRestTestUtils.java16
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfMulticloudAdapterImplTest.java123
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImplTest.java102
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack.json5
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack_Create.json16
16 files changed, 902 insertions, 320 deletions
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
index 15f84890b7..476bff3692 100644
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
@@ -277,8 +277,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{
boolean backout) throws MsoException {
// Take out the multicloud inputs, if present.
- String[] directives = { "oof_directives", "sdnc_directives", "generic_vnf_id", "vf_module_id" };
- for (String key : directives) {
+ for (String key : MsoMulticloudUtils.MULTICLOUD_INPUTS) {
if (stackInputs.containsKey(key)) {
stackInputs.remove(key);
if (stackInputs.isEmpty()) {
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudParam.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudParam.java
deleted file mode 100644
index 9b2475a1c4..0000000000
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudParam.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * ONAP - SO
- * ================================================================================
- * Copyright (C) 2018 Intel Corp. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.so.openstack.utils;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class MsoMulticloudParam {
-
- @JsonProperty("generic-vnf-id")
- private String genericVnfId;
-
- @JsonProperty("vf-module-id")
- private String vfModuleId;
-
- @JsonProperty("oof_directives")
- private String oofDirectives;
-
- @JsonProperty("sdnc_directives")
- private String sdncDirectives;
-
- @JsonProperty("template_type")
- private String templateType;
-
- @JsonProperty("template_data")
- private String templateData;
-
- public void setGenericVnfId(String genericVnfId){
- this.genericVnfId = genericVnfId;
- }
-
- public String getGenericVnfId(){
- return this.genericVnfId;
- }
-
- public void setVfModuleId(String vfModuleId){
- this.vfModuleId = vfModuleId;
- }
-
- public String getVfModuleId(){
- return this.vfModuleId;
- }
-
- public void setOofDirectives(String oofDirectives){
- this.oofDirectives = oofDirectives;
- }
-
- public String getOofDirectives(){
- return this.oofDirectives;
- }
-
- public void setSdncDirectives(String sdncDirectives){
- this.sdncDirectives = sdncDirectives;
- }
-
- public String getSdncDirectives(){
- return this.sdncDirectives;
- }
-
- public void setTemplateType(String templateType){
- this.templateType = templateType;
- }
-
- public String TemplateType(){
- return this.templateType;
- }
-
- public void setTemplateData(String templateData){
- this.templateData = templateData;
- }
-
- public String getTemplateData(){
- return this.templateData;
- }
-
- @Override
- public String toString() {
- return String.format("MulticloudParam{"
- + "genericVnfId='%s',"
- + " vfModuleId='%s',"
- + " oofDirectives='%s',"
- + " sdncDirectives='%s',"
- + " templateType='%s',"
- + " templateData='%s'"
- + "}",
- genericVnfId,
- vfModuleId,
- oofDirectives,
- sdncDirectives,
- templateType,
- templateData);
- }
-}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java
index 4ed35a4d28..306de05eea 100644
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java
@@ -21,13 +21,21 @@
package org.onap.so.openstack.utils;
import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Scanner;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
+import javax.ws.rs.core.Response.StatusType;
import javax.ws.rs.core.Response;
+import org.apache.http.HttpStatus;
+import org.onap.so.db.catalog.beans.CloudIdentity;
+import org.onap.so.utils.CryptoUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.onap.so.adapters.vdu.CloudInfo;
@@ -48,24 +56,27 @@ import org.onap.so.openstack.exceptions.MsoOpenstackException;
import org.onap.so.openstack.mappers.StackInfoMapper;
import org.onap.so.client.HttpClient;
import org.onap.so.client.RestClient;
-import org.onap.so.cloud.CloudConfig;
import org.onap.so.db.catalog.beans.CloudSite;
import org.onap.so.utils.TargetEntity;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.woorea.openstack.heat.model.CreateStackParam;
import com.woorea.openstack.heat.model.Stack;
@Component
public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
- @Autowired
- protected CloudConfig cloudConfig;
-
- @Autowired
- private Environment env;
+ public static final String OOF_DIRECTIVES = "oof_directives";
+ public static final String SDNC_DIRECTIVES = "sdnc_directives";
+ public static final String GENERIC_VNF_ID = "generic_vnf_id";
+ public static final String VF_MODULE_ID = "vf_module_id";
+ public static final String TEMPLATE_TYPE = "template_type";
+ public static final List<String> MULTICLOUD_INPUTS =
+ Arrays.asList(OOF_DIRECTIVES, SDNC_DIRECTIVES, GENERIC_VNF_ID, VF_MODULE_ID, TEMPLATE_TYPE);
private static final String ONAP_IP = "ONAP_IP";
@@ -75,6 +86,8 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
private static final Logger logger = LoggerFactory.getLogger(MsoMulticloudUtils.class);
+ private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
/******************************************************************************
*
* Methods (and associated utilities) to implement the VduPlugin interface
@@ -135,59 +148,90 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
Map <String, Object> heatFiles,
boolean backout) throws MsoException {
- // Get the directives, if present.
- String oofDirectives = null;
- String sdncDirectives = null;
- String genericVnfId = null;
- String vfModuleId = null;
+ logger.trace("Started MsoMulticloudUtils.createStack");
- String key = "oof_directives";
- if (!stackInputs.isEmpty() && stackInputs.containsKey(key)) {
- oofDirectives = (String) stackInputs.get(key);
- stackInputs.remove(key);
- }
- key = "sdnc_directives";
- if (!stackInputs.isEmpty() && stackInputs.containsKey(key)) {
- sdncDirectives = (String) stackInputs.get(key);
- stackInputs.remove(key);
- }
- key = "generic_vnf_id";
- if (!stackInputs.isEmpty() && stackInputs.containsKey(key)) {
- genericVnfId = (String) stackInputs.get(key);
- stackInputs.remove(key);
- }
- key = "vf_module_id";
- if (!stackInputs.isEmpty() && stackInputs.containsKey(key)) {
- vfModuleId = (String) stackInputs.get(key);
- stackInputs.remove(key);
+ // Get the directives, if present.
+ String oofDirectives = "";
+ String sdncDirectives = "";
+ String genericVnfId = "";
+ String vfModuleId = "";
+ String templateType = "";
+
+ for (String key: MULTICLOUD_INPUTS) {
+ if (!stackInputs.isEmpty() && stackInputs.containsKey(key)) {
+ if ( key == OOF_DIRECTIVES) {oofDirectives = (String) stackInputs.get(key);}
+ if ( key == SDNC_DIRECTIVES) {sdncDirectives = (String) stackInputs.get(key);}
+ if ( key == GENERIC_VNF_ID) {genericVnfId = (String) stackInputs.get(key);}
+ if ( key == VF_MODULE_ID) {vfModuleId = (String) stackInputs.get(key);}
+ if ( key == TEMPLATE_TYPE) {templateType = (String) stackInputs.get(key);}
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Found %s: %s", key, stackInputs.get(key)));
+ }
+ stackInputs.remove(key);
+ }
}
// create the multicloud payload
CreateStackParam stack = createStackParam(stackName, heatTemplate, stackInputs, timeoutMinutes, environment, files, heatFiles);
- MsoMulticloudParam multicloudParam = new MsoMulticloudParam();
- multicloudParam.setGenericVnfId(genericVnfId);
- multicloudParam.setVfModuleId(vfModuleId);
- multicloudParam.setOofDirectives(oofDirectives);
- multicloudParam.setSdncDirectives(sdncDirectives);
- multicloudParam.setTemplateType("heat");
- multicloudParam.setTemplateData(stack.toString());
+ MulticloudRequest multicloudRequest= new MulticloudRequest();
+ HttpEntity<MulticloudRequest> request = null;
+ try {
+ multicloudRequest.setGenericVnfId(genericVnfId);
+ multicloudRequest.setVfModuleId(vfModuleId);
+ multicloudRequest.setOofDirectives(oofDirectives);
+ multicloudRequest.setSdncDirectives(sdncDirectives);
+ multicloudRequest.setTemplateType(templateType);
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Stack Template Data is: %s", stack.toString().substring(16)));
+ }
+ multicloudRequest.setTemplateData(JSON_MAPPER.writeValueAsString(stack));
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Multicloud Request is: %s", multicloudRequest.toString()));
+ }
+ CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() ->
+ new MsoCloudSiteNotFound(cloudSiteId));
+ CloudIdentity cloudIdentity = cloudSite.getIdentityService();
+ HttpHeaders headers = new HttpHeaders();
+ headers.set ("X-Auth-User", cloudIdentity.getMsoId ());
+ headers.set ("X-Auth-Key", CryptoUtils.decryptCloudConfigPassword(cloudIdentity.getMsoPass ()));
+ headers.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString());
+ headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString());
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Multicloud Request Headers: %s", headers.toString()));
+ }
+ request = new HttpEntity<>(multicloudRequest, headers);
+ } catch (Exception e) {
+ logger.debug("ERROR making multicloud JSON body ", e);
+ }
String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, null);
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Multicloud Endpoint is: %s", multicloudEndpoint));
+ }
RestClient multicloudClient = getMulticloudClient(multicloudEndpoint);
- if (multicloudClient != null) {
- Response res = multicloudClient.post(multicloudParam);
- logger.debug("Multicloud Post response is: " + res);
- }
+ Response response = multicloudClient.post(request);
- Stack responseStack = new Stack();
- responseStack.setStackStatus(HeatStatus.CREATED.toString());
+ StackInfo responseStackInfo = new StackInfo();
+ responseStackInfo.setName(stackName);
+ responseStackInfo.setStatus(mapResponseToHeatStatus(response));
- return new StackInfoMapper(responseStack).map();
+ MulticloudCreateResponse multicloudResponseBody = null;
+ if (response.getStatus() == Response.Status.CREATED.getStatusCode() && response.hasEntity()) {
+ multicloudResponseBody = getCreateBody((java.io.InputStream)response.getEntity());
+ responseStackInfo.setCanonicalName(multicloudResponseBody.getWorkloadId());
+ if (logger.isDebugEnabled()) {
+ logger.debug("Multicloud Create Response Body: " + multicloudResponseBody);
+ }
+ }
+
+ return responseStackInfo;
}
+ @Override
public Map<String, Object> queryStackForOutputs(String cloudSiteId,
String tenantId, String stackName) throws MsoException {
logger.debug("MsoHeatUtils.queryStackForOutputs)");
@@ -211,64 +255,129 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
*/
@Override
public StackInfo queryStack (String cloudSiteId, String tenantId, String stackName) throws MsoException {
- logger.debug ("Query multicloud HEAT stack: " + stackName + " in tenant " + tenantId);
+ if (logger.isDebugEnabled()) {
+ logger.debug (String.format("Query multicloud HEAT stack: %s in tenant %s", stackName, tenantId));
+ }
- String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, stackName);
+ StackInfo returnInfo = new StackInfo();
+ returnInfo.setName(stackName);
+ String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, stackName);
RestClient multicloudClient = getMulticloudClient(multicloudEndpoint);
if (multicloudClient != null) {
Response response = multicloudClient.get();
- logger.debug("Multicloud Get response is: " + response);
+ if (logger.isDebugEnabled()) {
+ logger.debug (String.format("Mulicloud GET Response: %s", response.toString()));
+ }
+
+ returnInfo.setStatus(mapResponseToHeatStatus(response));
- return new StackInfo (stackName, HeatStatus.CREATED);
+ MulticloudQueryResponse multicloudQueryBody = null;
+ if (response.getStatus() == Response.Status.OK.getStatusCode() && response.hasEntity()) {
+ multicloudQueryBody = getQueryBody((java.io.InputStream)response.getEntity());
+ returnInfo.setCanonicalName(multicloudQueryBody.getWorkloadId());
+ if (logger.isDebugEnabled()) {
+ logger.debug("Multicloud Create Response Body: " + multicloudQueryBody.toString());
+ }
+ }
}
- return new StackInfo (stackName, HeatStatus.NOTFOUND);
+ return returnInfo;
+
}
public StackInfo deleteStack (String cloudSiteId, String tenantId, String stackName) throws MsoException {
- logger.debug ("Delete multicloud HEAT stack: " + stackName + " in tenant " + tenantId);
+ if (logger.isDebugEnabled()) {
+ logger.debug (String.format("Delete multicloud HEAT stack: %s in tenant %s", stackName, tenantId));
+ }
+ StackInfo returnInfo = new StackInfo();
+ returnInfo.setName(stackName);
+ Response response = null;
String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, stackName);
-
RestClient multicloudClient = getMulticloudClient(multicloudEndpoint);
if (multicloudClient != null) {
- Response response = multicloudClient.delete();
- logger.debug("Multicloud Get response is: " + response);
-
- return new StackInfo (stackName, HeatStatus.DELETING);
+ response = multicloudClient.delete();
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Multicloud Delete response is: %s", response.getEntity().toString()));
+ }
}
-
- return new StackInfo (stackName, HeatStatus.FAILED);
+ returnInfo.setStatus(mapResponseToHeatStatus(response));
+ return returnInfo;
}
// ---------------------------------------------------------------
// PRIVATE FUNCTIONS FOR USE WITHIN THIS CLASS
+ private HeatStatus mapResponseToHeatStatus(Response response) {
+ if (response.getStatusInfo().getStatusCode() == Response.Status.OK.getStatusCode()) {
+ return HeatStatus.CREATED;
+ } else if (response.getStatusInfo().getStatusCode() == Response.Status.CREATED.getStatusCode()) {
+ return HeatStatus.CREATED;
+ } else if (response.getStatusInfo().getStatusCode() == Response.Status.NO_CONTENT.getStatusCode()) {
+ return HeatStatus.CREATED;
+ } else if (response.getStatusInfo().getStatusCode() == Response.Status.BAD_REQUEST.getStatusCode()) {
+ return HeatStatus.FAILED;
+ } else if (response.getStatusInfo().getStatusCode() == Response.Status.UNAUTHORIZED.getStatusCode()) {
+ return HeatStatus.FAILED;
+ } else if (response.getStatusInfo().getStatusCode() == Response.Status.NOT_FOUND.getStatusCode()) {
+ return HeatStatus.NOTFOUND;
+ } else if (response.getStatusInfo().getStatusCode() == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
+ return HeatStatus.FAILED;
+ } else {
+ return HeatStatus.UNKNOWN;
+ }
+ }
+ private MulticloudCreateResponse getCreateBody(java.io.InputStream in) {
+ Scanner scanner = new Scanner(in);
+ scanner.useDelimiter("\\Z");
+ String body = "";
+ if (scanner.hasNext()) {
+ body = scanner.next();
+ }
+ scanner.close();
- private String getMsbHost() {
- // MSB_IP will be set as ONAP_IP environment parameter in install flow.
- String msbIp = System.getenv().get(ONAP_IP);
+ try {
+ return new ObjectMapper().readerFor(MulticloudCreateResponse.class).readValue(body);
+ } catch (Exception e) {
+ logger.debug("Exception retrieving multicloud vfModule POST response body " + e);
+ }
+ return null;
+ }
- // if ONAP IP is not set. get it from config file.
- if (null == msbIp || msbIp.isEmpty()) {
- msbIp = env.getProperty("mso.msb-ip", DEFAULT_MSB_IP);
+ private MulticloudQueryResponse getQueryBody(java.io.InputStream in) {
+ Scanner scanner = new Scanner(in);
+ scanner.useDelimiter("\\Z");
+ String body = "";
+ if (scanner.hasNext()) {
+ body = scanner.next();
}
- Integer msbPort = env.getProperty("mso.msb-port", Integer.class, DEFAULT_MSB_PORT);
+ scanner.close();
- return UriBuilder.fromPath("").host(msbIp).port(msbPort).scheme("http").build().toString();
+ try {
+ return new ObjectMapper().readerFor(MulticloudQueryResponse.class).readValue(body);
+ } catch (Exception e) {
+ logger.debug("Exception retrieving multicloud workload query response body " + e);
+ }
+ return null;
}
private String getMulticloudEndpoint(String cloudSiteId, String workloadId) throws MsoCloudSiteNotFound {
CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
- String endpoint = getMsbHost() + cloudSite.getIdentityService().getIdentityUrl();
+ String endpoint = cloudSite.getIdentityService().getIdentityUrl();
if (workloadId != null) {
- return endpoint + workloadId;
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Multicloud Endpoint is: %s/%s", endpoint, workloadId));
+ }
+ return String.format("%s/%s", endpoint, workloadId);
} else {
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Multicloud Endpoint is: %s", endpoint));
+ }
return endpoint;
}
}
@@ -277,13 +386,13 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
RestClient client = null;
try {
client= new HttpClient(UriBuilder.fromUri(endpoint).build().toURL(),
- "application/json", TargetEntity.OPENSTACK_ADAPTER);
+ MediaType.APPLICATION_JSON.toString(), TargetEntity.MULTICLOUD);
} catch (MalformedURLException e) {
- logger.debug("Encountered malformed URL error getting multicloud rest client " + e.getMessage());
+ logger.debug(String.format("Encountered malformed URL error getting multicloud rest client %s", e.getMessage()));
} catch (IllegalArgumentException e) {
- logger.debug("Encountered illegal argument getting multicloud rest client " + e.getMessage());
+ logger.debug(String.format("Encountered illegal argument getting multicloud rest client %s",e.getMessage()));
} catch (UriBuilderException e) {
- logger.debug("Encountered URI builder error getting multicloud rest client " + e.getMessage());
+ logger.debug(String.format("Encountered URI builder error getting multicloud rest client %s", e.getMessage()));
}
return client;
}
@@ -382,7 +491,7 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
try {
// Delete the Multicloud stack
- StackInfo stackInfo = deleteStack (tenantId, cloudSiteId, instanceId, true);
+ StackInfo stackInfo = deleteStack (tenantId, cloudSiteId, instanceId);
// Populate a VduInstance based on the deleted Cloudify Deployment object
VduInstance vduInstance = stackInfoToVduInstance(stackInfo);
@@ -425,6 +534,9 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
{
VduInstance vduInstance = new VduInstance();
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("StackInfo to convert: %s", stackInfo.getParameters().toString()));
+ }
// The full canonical name as the instance UUID
vduInstance.setVduInstanceId(stackInfo.getCanonicalName());
vduInstance.setVduInstanceName(stackInfo.getName());
@@ -447,6 +559,12 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{
// There are lots of HeatStatus values, so this is a bit long...
HeatStatus heatStatus = stackInfo.getStatus();
String statusMessage = stackInfo.getStatusMessage();
+ logger.debug("HeatStatus = " + heatStatus + " msg = " + statusMessage);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Stack Status: %s", heatStatus.toString()));
+ logger.debug(String.format("Stack Status Message: %s", statusMessage));
+ }
if (heatStatus == HeatStatus.INIT || heatStatus == HeatStatus.BUILDING) {
vduStatus.setState(VduStateType.INSTANTIATING);
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java
new file mode 100644
index 0000000000..543ad07d52
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateHeatResponse.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 Intel Corp. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.openstack.utils;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "id",
+ "links"
+})
+public class MulticloudCreateHeatResponse implements Serializable {
+ private final static long serialVersionUID = -5215028275577848311L;
+
+ @JsonProperty("id")
+ private String id;
+ @JsonProperty("links")
+ private List<MulticloudCreateLinkResponse> links;
+
+ @JsonCreator
+ public MulticloudCreateHeatResponse(
+ @JsonProperty("id") String id,
+ @JsonProperty("links") List<MulticloudCreateLinkResponse> links) {
+ this.id = id;
+ this.links = links;
+ }
+
+ @JsonProperty("id")
+ public String getId() {
+ return id;
+ }
+
+ @JsonProperty("id")
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @JsonProperty("links")
+ public List<MulticloudCreateLinkResponse> getLinks() {
+ return links;
+ }
+
+ @JsonProperty("links")
+ public void setLinks(List<MulticloudCreateLinkResponse> links) {
+ this.links = links;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("id", id).append("links", links).toString();
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java
new file mode 100644
index 0000000000..b609ac96c4
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateLinkResponse.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 Intel Corp. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.openstack.utils;
+
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "href",
+ "rel"
+})
+public class MulticloudCreateLinkResponse implements Serializable {
+ private final static long serialVersionUID = -5215028275577848311L;
+
+ @JsonProperty("href")
+ private String href;
+ @JsonProperty("rel")
+ private String rel;
+
+ @JsonCreator
+ public MulticloudCreateLinkResponse(
+ @JsonProperty("href") String href,
+ @JsonProperty("rel") String rel) {
+ this.href = href;
+ this.rel = rel;
+ }
+
+ @JsonProperty("href")
+ public String getHref() {
+ return href;
+ }
+
+ @JsonProperty("href")
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ @JsonProperty("rel")
+ public String getRel() {
+ return rel;
+ }
+
+ @JsonProperty("rel")
+ public void setRel(String rel) {
+ this.rel = rel;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("href", href).append("rel", rel).toString();
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java
new file mode 100644
index 0000000000..fafd4a074d
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateResponse.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 Intel Corp. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.openstack.utils;
+
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "template_type",
+ "workload_id",
+ "template_response"
+})
+public class MulticloudCreateResponse implements Serializable {
+ private final static long serialVersionUID = -5215028275577848311L;
+
+ @JsonProperty("template_type")
+ private String templateType;
+ @JsonProperty("workload_id")
+ private String workloadId;
+ @JsonProperty("template_response")
+ private MulticloudCreateStackResponse templateResponse;
+
+ @JsonCreator
+ public MulticloudCreateResponse(
+ @JsonProperty("template_type") String templateType,
+ @JsonProperty("workload_id") String workloadId,
+ @JsonProperty("template_response") MulticloudCreateStackResponse templateResponse) {
+ this.templateType = templateType;
+ this.workloadId = workloadId;
+ this.templateResponse = templateResponse;
+ }
+
+ @JsonProperty("template_type")
+ public String getTemplateType() {
+ return templateType;
+ }
+
+ @JsonProperty("template_type")
+ public void setTemplateType(String templateType) {
+ this.templateType = templateType;
+ }
+
+ @JsonProperty("workload_id")
+ public String getWorkloadId() {
+ return workloadId;
+ }
+
+ @JsonProperty("workload_id")
+ public void setWorkloadId(String workloadId) {
+ this.workloadId = workloadId;
+ }
+
+ @JsonProperty("template_response")
+ public void setTemplateResponse(MulticloudCreateStackResponse templateResponse) {
+ this.templateResponse = templateResponse;
+ }
+
+ @JsonProperty("template_response")
+ public MulticloudCreateStackResponse getTemplateResponse() {
+ return templateResponse;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("templateType", templateType).append("workloadId", workloadId).append("templateResponse", templateResponse).toString();
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateStackResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateStackResponse.java
new file mode 100644
index 0000000000..f1d44a8814
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudCreateStackResponse.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 Intel Corp. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.openstack.utils;
+
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "stack"
+})
+public class MulticloudCreateStackResponse implements Serializable {
+ private final static long serialVersionUID = -5215028275577848311L;
+
+ @JsonProperty("stack")
+ private MulticloudCreateHeatResponse stack;
+
+ @JsonCreator
+ public MulticloudCreateStackResponse(
+ @JsonProperty("stack") MulticloudCreateHeatResponse stack) {
+ this.stack = stack;
+ }
+
+ @JsonProperty("stack")
+ public MulticloudCreateHeatResponse getStack() {
+ return stack;
+ }
+
+ @JsonProperty("stack")
+ public void setStack(MulticloudCreateHeatResponse stack) {
+ this.stack = stack;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("stack", stack).toString();
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java
new file mode 100644
index 0000000000..b22e9dc03e
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudQueryResponse.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 Intel Corp. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.openstack.utils;
+
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "template_type",
+ "workload_id",
+ "workload_status"
+})
+public class MulticloudQueryResponse implements Serializable {
+ private final static long serialVersionUID = -5215028275577848311L;
+
+ @JsonProperty("template_type")
+ private String templateType;
+ @JsonProperty("workload_id")
+ private String workloadId;
+ @JsonProperty("workload_status")
+ private String workloadStatus;
+
+ @JsonCreator
+ public MulticloudQueryResponse(
+ @JsonProperty("template_type") String templateType,
+ @JsonProperty("workload_id") String workloadId,
+ @JsonProperty("workload_status") String workloadStatus) {
+ this.templateType = templateType;
+ this.workloadId = workloadId;
+ this.workloadStatus = workloadStatus;
+ }
+
+ @JsonProperty("template_type")
+ public String getTemplateType() {
+ return templateType;
+ }
+
+ @JsonProperty("template_type")
+ public void setTemplateType(String templateType) {
+ this.templateType = templateType;
+ }
+
+ @JsonProperty("workload_id")
+ public String getWorkloadId() {
+ return workloadId;
+ }
+
+ @JsonProperty("workload_id")
+ public void setWorkloadId(String workloadId) {
+ this.workloadId = workloadId;
+ }
+
+ @JsonProperty("workload_status")
+ public String getWorkloadStatus() {
+ return workloadStatus;
+ }
+
+ @JsonProperty("workload_status")
+ public void setWorkloadStatus(String workloadStatus) {
+ this.workloadStatus = workloadStatus;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("templateType", templateType).append("workloadId", workloadId).append("workloadStatus", workloadStatus).toString();
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java
new file mode 100644
index 0000000000..fefc0951f6
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MulticloudRequest.java
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 Intel Corp. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.openstack.utils;
+
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "generic-vnf-id",
+ "vf-module-id",
+ "oof_directives",
+ "sdnc_directives",
+ "template_type",
+ "template_data"
+})
+public class MulticloudRequest implements Serializable {
+ private final static long serialVersionUID = -5215028275577848311L;
+
+ @JsonProperty("generic-vnf-id")
+ private String genericVnfId;
+ @JsonProperty("vf-module-id")
+ private String vfModuleId;
+ @JsonProperty("oof_directives")
+ private String oofDirectives;
+ @JsonProperty("sdnc_directives")
+ private String sdncDirectives;
+ @JsonProperty("template_type")
+ private String templateType;
+ @JsonProperty("template_data")
+ private String templateData;
+
+
+ @JsonProperty("generic-vnf-id")
+ public String getGenericVnfId() {
+ return genericVnfId;
+ }
+
+ @JsonProperty("generic-vnf-id")
+ public void setGenericVnfId(String genericVnfId) {
+ this.genericVnfId = genericVnfId;
+ }
+
+ @JsonProperty("vf-module-id")
+ public String getVfModuleId() {
+ return vfModuleId;
+ }
+
+ @JsonProperty("vf-module-id")
+ public void setVfModuleId(String vfModuleId) {
+ this.vfModuleId = vfModuleId;
+ }
+
+ @JsonProperty("oof_directives")
+ public String getOofDirectives() {
+ return oofDirectives;
+ }
+
+ @JsonProperty("oof_directives")
+ public void setOofDirectives(String oofDirectives) {
+ this.oofDirectives = oofDirectives;
+ }
+
+ @JsonProperty("sdnc_directives")
+ public String getSdncDirectives() {
+ return sdncDirectives;
+ }
+
+ @JsonProperty("sdnc_directives")
+ public void setSdncDirectives(String sdncDirectives) {
+ this.sdncDirectives = sdncDirectives;
+ }
+
+ @JsonProperty("template_type")
+ public String getTemplateType() {
+ return templateType;
+ }
+
+ @JsonProperty("template_type")
+ public void setTemplateType(String templateType) {
+ this.templateType = templateType;
+ }
+
+ @JsonProperty("template_data")
+ public String getTemplateData() {
+ return templateData;
+ }
+
+ @JsonProperty("template_data")
+ public void setTemplateData(String templateData) {
+ this.templateData = templateData;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("genericVnfId", genericVnfId).append("vfModuleId", vfModuleId).append("oofDirectives", oofDirectives).append("sdncDirectives", sdncDirectives).append("templateType", templateType).append("templateData", templateData).toString();
+ }
+
+}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java
index e9567170dd..9a64e62e57 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImpl.java
@@ -710,6 +710,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter {
CloudSite cloudSite = cloudSiteOp.get();
MavenLikeVersioning aicV = new MavenLikeVersioning();
aicV.setVersion(cloudSite.getCloudVersion());
+ Boolean usingMulticloud = getUsingMulticloud(cloudSite);
String vnfMin = vnfResource.getAicVersionMin();
String vnfMax = vnfResource.getAicVersionMax();
@@ -732,23 +733,25 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter {
// Use the VduPlugin.
VduPlugin vduPlugin = getVduPlugin(cloudSiteId);
- // First, look up to see if the VF already exists.
+ // First, look up to see if the VF already exists, unless using multicloud adapter
long subStartTime1 = System.currentTimeMillis ();
- try {
- vduInstance = vduPlugin.queryVdu (cloudInfo, vfModuleName);
- LOGGER.recordMetricEvent (subStartTime1, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from VduPlugin", "VDU", "QueryVDU", vfModuleName);
- }
- catch (VduException me) {
- // Failed to query the VDU due to a plugin exception.
- String error = "Create VF Module: Query " + vfModuleName + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
- LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, "VDU", "queryVdu", MsoLogger.ErrorCode.DataError, "Exception - queryVdu", me);
- LOGGER.recordMetricEvent (subStartTime1, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "VDU", "QueryVdu", vfModuleName);
- LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+ if (!usingMulticloud) {
+ try {
+ vduInstance = vduPlugin.queryVdu (cloudInfo, vfModuleName);
+ LOGGER.recordMetricEvent (subStartTime1, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from VduPlugin", "VDU", "QueryVDU", vfModuleName);
+ }
+ catch (VduException me) {
+ // Failed to query the VDU due to a plugin exception.
+ String error = "Create VF Module: Query " + vfModuleName + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
+ LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, "VDU", "queryVdu", MsoLogger.ErrorCode.DataError, "Exception - queryVdu", me);
+ LOGGER.recordMetricEvent (subStartTime1, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "VDU", "QueryVdu", vfModuleName);
+ LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
- // Convert to a generic VnfException
- me.addContext ("CreateVFModule");
- throw new VnfException (me);
+ // Convert to a generic VnfException
+ me.addContext ("CreateVFModule");
+ throw new VnfException (me);
+ }
}
// More precise handling/messaging if the Module already exists
@@ -810,7 +813,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter {
Map<String, Object> volumeGroupOutputs = null;
// If a Volume Group was provided, query its outputs for inclusion in Module input parameters
- if (volumeGroupId != null) {
+ if (!usingMulticloud && volumeGroupId != null) {
long subStartTime2 = System.currentTimeMillis ();
VduInstance volumeVdu = null;
try {
@@ -858,7 +861,8 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter {
LOGGER.debug ("WARNING: Add-on Module request - no Base Module ID provided");
}
- if (baseVfModuleId != null) {
+ // Need to verify if multicloud needs to have the vaseVfModuleId passed to it. Ignoring this for now.
+ if (!usingMulticloud && baseVfModuleId != null) {
long subStartTime2 = System.currentTimeMillis ();
VduInstance baseVdu = null;
try {
@@ -979,9 +983,8 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter {
}
if (!extraInputs.isEmpty()) {
- // Add directive inputs
- String[] directives = { "oof_directives", "sdnc_directives" };
- for (String key : directives) {
+ // Add multicloud inputs
+ for (String key : MsoMulticloudUtils.MULTICLOUD_INPUTS) {
if (extraInputs.contains(key)) {
goldenInputs.put(key, inputs.get(key));
extraInputs.remove(key);
@@ -1242,4 +1245,12 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter {
// Default - return HEAT plugin, though will fail later
return heatUtils;
}
+
+ private Boolean getUsingMulticloud (CloudSite cloudSite) {
+ if (cloudSite.getOrchestrator().equalsIgnoreCase("MULTICLOUD")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestUtils.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestUtils.java
index 88f102c2a5..c332c49832 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestUtils.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/VnfAdapterRestUtils.java
@@ -33,6 +33,10 @@ public class VnfAdapterRestUtils
{
private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA, VnfAdapterRestUtils.class);
+ private static final String HEAT_MODE = "HEAT";
+ private static final String CLOUDIFY_MODE = "CLOUDIFY";
+ private static final String MULTICLOUD_MODE = "MULTICLOUD";
+
@Autowired
private CloudConfig cloudConfig;
@@ -65,9 +69,12 @@ public class VnfAdapterRestUtils
if (cloudSite.isPresent()) {
LOGGER.debug("Got CloudSite: " + cloudSite.toString());
if (cloudConfig.getCloudifyManager(cloudSite.get().getCloudifyId()) != null) {
- mode = "CLOUDIFY";
- } else {
- mode = "HEAT";
+ mode = CLOUDIFY_MODE;
+ } else if (MULTICLOUD_MODE.equalsIgnoreCase(cloudSite.get().getOrchestrator())) {
+ mode = MULTICLOUD_MODE;
+ }
+ else {
+ mode = HEAT_MODE;
}
}
}
@@ -77,15 +84,15 @@ public class VnfAdapterRestUtils
MsoVnfAdapter vnfAdapter = null;
// TODO: Make this more dynamic (e.g. Service Loader)
- if ("CLOUDIFY".equalsIgnoreCase(mode)) {
+ if (CLOUDIFY_MODE.equalsIgnoreCase(mode)) {
LOGGER.debug ("GetVnfAdapterImpl: Return Cloudify Adapter");
vnfAdapter = cloudifyImpl;
}
- else if ("HEAT".equalsIgnoreCase(mode)) {
+ else if (HEAT_MODE.equalsIgnoreCase(mode)) {
LOGGER.debug ("GetVnfAdapterImpl: Return Heat Adapter");
vnfAdapter = vnfImpl;
}
- else if ("MULTICLOUD".equalsIgnoreCase(mode)) {
+ else if (MULTICLOUD_MODE.equalsIgnoreCase(mode)) {
LOGGER.debug ("GetVnfAdapterImpl: Return Plugin (multicloud) Adapter");
vnfAdapter = vnfPluginImpl;
}
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/BaseRestTestUtils.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/BaseRestTestUtils.java
index a2f57ef06f..9ead28b577 100644
--- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/BaseRestTestUtils.java
+++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/BaseRestTestUtils.java
@@ -77,7 +77,10 @@ public class BaseRestTestUtils {
private int port;
public ObjectMapper mapper;
-
+
+ public String orchestrator = "orchestrator";
+ public String cloudEndpoint = "/v2.0";
+
protected String readJsonFileAsString(String fileLocation) throws JsonParseException, JsonMappingException, IOException{
ObjectMapper mapper = new ObjectMapper();
@@ -111,7 +114,6 @@ public class BaseRestTestUtils {
public void setUp() throws Exception {
reset();
mapper = new ObjectMapper();
-
CloudIdentity identity = new CloudIdentity();
identity.setId("MTN13");
identity.setMsoId("m93945");
@@ -119,7 +121,8 @@ public class BaseRestTestUtils {
identity.setAdminTenant("admin");
identity.setMemberRole("admin");
identity.setTenantMetadata(new Boolean(true));
- identity.setIdentityUrl("http://localhost:"+wireMockPort+"/v2.0");
+ identity.setIdentityUrl("http://localhost:" + wireMockPort + cloudEndpoint);
+
identity.setIdentityAuthenticationType(AuthenticationType.USERNAME_PASSWORD);
CloudSite cloudSite = new CloudSite();
@@ -127,12 +130,10 @@ public class BaseRestTestUtils {
cloudSite.setCloudVersion("3.0");
cloudSite.setClli("MDT13");
cloudSite.setRegionId("mtn13");
- cloudSite.setOrchestrator("orchestrator" +
- "");
+ cloudSite.setOrchestrator(orchestrator);
identity.setIdentityServerType(ServerType.KEYSTONE);
cloudSite.setIdentityService(identity);
-
stubFor(get(urlPathEqualTo("/cloudSite/MTN13")).willReturn(aResponse()
.withBody(getBody(mapper.writeValueAsString(cloudSite),wireMockPort, ""))
.withHeader(org.apache.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
@@ -145,8 +146,7 @@ public class BaseRestTestUtils {
.withBody(getBody(mapper.writeValueAsString(identity),wireMockPort, ""))
.withHeader(org.apache.http.HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON)
.withStatus(HttpStatus.SC_OK)));
- cloudConfig.getCloudSite("MTN13").get().getIdentityService().setIdentityUrl("http://localhost:" + wireMockPort + "/v2.0");
-
+ cloudConfig.getCloudSite("MTN13").get().getIdentityService().setIdentityUrl("http://localhost:" + wireMockPort + cloudEndpoint);
}
protected static String getBody(String body, int port, String urlPath) throws IOException {
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfMulticloudAdapterImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfMulticloudAdapterImplTest.java
new file mode 100644
index 0000000000..07fa47df42
--- /dev/null
+++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfMulticloudAdapterImplTest.java
@@ -0,0 +1,123 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2018 Intel Corp. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.adapters.vnf;
+
+import org.apache.http.HttpStatus;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.so.adapters.openstack.MsoOpenstackAdaptersApplication;
+import org.onap.so.adapters.vnf.exceptions.VnfException;
+import org.onap.so.cloud.CloudConfig;
+import org.onap.so.db.catalog.beans.CloudSite;
+import org.onap.so.entity.MsoRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.embedded.LocalServerPort;
+
+import javax.xml.ws.Holder;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.delete;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+
+public class MsoVnfMulticloudAdapterImplTest extends BaseRestTestUtils{
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Autowired
+ private MsoVnfPluginAdapterImpl instance;
+
+ @Autowired
+ private CloudConfig cloudConfig;
+
+ @Before
+ public void before() throws Exception {
+ super.orchestrator = "multicloud";
+ super.cloudEndpoint = "/api/multicloud/v1/cloud_owner/cloud_region_id/infra_workload";
+ super.setUp();
+ }
+
+ @Test
+ public void createVfModule() throws Exception {
+ //expectedException.expect(VnfException.class);
+ Map<String, String> stackInputs = new HashMap<>();
+ stackInputs.put("oof_directives", "{oofDIRECTIVES}");
+ stackInputs.put("sdnc_directives", "{sdncDIRECTIVES}");
+ stackInputs.put("generic_vnf_id", "genVNFID");
+ stackInputs.put("vf_module_id", "vfMODULEID");
+
+ MsoRequest msoRequest = new MsoRequest();
+ msoRequest.setRequestId("12345");
+ msoRequest.setServiceInstanceId("12345");
+
+ stubFor(get(urlPathEqualTo("/api/multicloud/v1/cloud_owner/cloud_region_id/infra_workload/vfname")).willReturn(aResponse()
+ //.withHeader()
+ .withStatus(HttpStatus.SC_NOT_FOUND)));
+
+ stubFor(get(urlPathEqualTo("/api/multicloud/v1/cloud_owner/cloud_region_id/infra_workload/vfname/outputs")).willReturn(aResponse()
+ .withStatus(HttpStatus.SC_NOT_FOUND)));
+
+ stubFor(post(urlPathEqualTo("/api/multicloud/v1/cloud_owner/cloud_region_id/infra_workload")).willReturn(aResponse()
+ .withBodyFile("MulticloudResponse_Stack_Create.json")
+ .withStatus(HttpStatus.SC_CREATED)));
+
+ instance.createVfModule("MTN13", "123", "vf", "v1", "vfname", "create", null, "234", "9b339a61-69ca-465f-86b8-1c72c582b8e8", stackInputs, true, true, true, msoRequest, new Holder<>(), new Holder<>(), new Holder<>());
+ }
+
+ @Test
+ public void deleteVfModule() throws Exception {
+ MsoRequest msoRequest = new MsoRequest();
+ msoRequest.setRequestId("12345");
+ msoRequest.setServiceInstanceId("12345");
+
+ stubFor(get(urlPathEqualTo("/api/multicloud/v1/cloud_owner/cloud_region_id/infra_workload/workload-id")).willReturn(aResponse()
+ .withBodyFile("MulticloudResponse_Stack.json")
+ .withStatus(HttpStatus.SC_OK)));
+
+ stubFor(delete(urlPathEqualTo("/api/multicloud/v1/cloud_owner/cloud_region_id/infra_workload/workload-id")).willReturn(aResponse()
+ .withStatus(HttpStatus.SC_NO_CONTENT)));
+
+ instance.deleteVfModule("MTN13", "123", "workload-id", msoRequest, new Holder<>());
+ }
+
+ @Test
+ public void queryVfModule() throws Exception {
+ MsoRequest msoRequest = new MsoRequest();
+ msoRequest.setRequestId("12345");
+ msoRequest.setServiceInstanceId("12345");
+
+ stubFor(get(urlPathEqualTo("/api/multicloud/v1/cloud_owner/cloud_region_id/infra_workload/workload-id")).willReturn(aResponse()
+ .withBodyFile("MulticloudResponse_Stack.json")
+ .withStatus(HttpStatus.SC_OK)));
+
+ instance.queryVnf("MTN13", "123", "workload-id", msoRequest, new Holder<>(), new Holder<>(), new Holder<>(), new Holder<>());
+ }
+
+ // TODO Error Tests
+}
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImplTest.java
index 77ef8d4776..936bce5b5c 100644
--- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImplTest.java
+++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/vnf/MsoVnfPluginAdapterImplTest.java
@@ -20,31 +20,15 @@
package org.onap.so.adapters.vnf;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.tomakehurst.wiremock.client.WireMock;
import org.apache.http.HttpStatus;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.mockito.MockitoAnnotations;
-import org.onap.so.adapters.vdu.CloudInfo;
-import org.onap.so.adapters.vdu.VduInstance;
-import org.onap.so.adapters.vdu.VduStateType;
-import org.onap.so.adapters.vdu.VduStatus;
import org.onap.so.adapters.vnf.exceptions.VnfException;
-import org.onap.so.db.catalog.beans.AuthenticationType;
-import org.onap.so.db.catalog.beans.CloudIdentity;
-import org.onap.so.db.catalog.beans.CloudSite;
-import org.onap.so.db.catalog.beans.ServerType;
import org.onap.so.entity.MsoRequest;
-import org.onap.so.openstack.beans.HeatStatus;
-import org.onap.so.openstack.beans.StackInfo;
import org.onap.so.openstack.beans.VnfRollback;
-import org.onap.so.openstack.utils.MsoMulticloudUtils;
import org.springframework.beans.factory.annotation.Autowired;
-import javax.ws.rs.core.MediaType;
import javax.xml.ws.Holder;
import java.util.HashMap;
import java.util.Map;
@@ -52,15 +36,11 @@ import java.util.Map;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.delete;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.reset;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-import static org.mockito.Mockito.when;
import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackGetStackVfModule_200;
import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackGetStackVfModule_404;
import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackResponseAccess;
-import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenStackResponseAccessMulticloud;
-import static org.onap.so.bpmn.mock.StubOpenStack.mockOpenstackGetWithResponse;
public class MsoVnfPluginAdapterImplTest extends BaseRestTestUtils {
@@ -72,53 +52,6 @@ public class MsoVnfPluginAdapterImplTest extends BaseRestTestUtils {
String vnfName = "DEV-VF-1802-it3-pwt3-v6-vSAMP10a-addon2-Replace-1001/stackId";
- /***
- * Before each test execution, updating IdentityUrl port value to the ramdom wireMockPort
- * Since URL will be used as a rest call and required to be mocked in unit tests
- */
- @Before
- public void setUp() throws Exception {
- reset();
- mapper = new ObjectMapper();
-
- CloudIdentity identity = new CloudIdentity();
- identity.setId("MTN13");
- identity.setMsoId("m93945");
- identity.setMsoPass("93937EA01B94A10A49279D4572B48369");
- identity.setAdminTenant("admin");
- identity.setMemberRole("admin");
- identity.setTenantMetadata(new Boolean(true));
- identity.setIdentityUrl("http://localhost:"+wireMockPort+"/v2.0");
- identity.setIdentityAuthenticationType(AuthenticationType.USERNAME_PASSWORD);
-
- CloudSite cloudSite = new CloudSite();
- cloudSite.setId("MTN13");
- cloudSite.setCloudVersion("3.0");
- cloudSite.setClli("MDT13");
- cloudSite.setRegionId("MTN13");
- cloudSite.setOrchestrator("multicloud" +
- "");
- identity.setIdentityServerType(ServerType.KEYSTONE);
- cloudSite.setIdentityService(identity);
-
-
-
- stubFor(get(urlPathEqualTo("/cloudSite/MTN13")).willReturn(aResponse()
- .withBody(getBody(mapper.writeValueAsString(cloudSite),wireMockPort, ""))
- .withHeader(org.apache.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
- .withStatus(HttpStatus.SC_OK)));
- stubFor(get(urlPathEqualTo("/cloudSite/DEFAULT")).willReturn(aResponse()
- .withBody(getBody(mapper.writeValueAsString(cloudSite),wireMockPort, ""))
- .withHeader(org.apache.http.HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON)
- .withStatus(HttpStatus.SC_OK)));
- stubFor(get(urlPathEqualTo("/cloudIdentity/MTN13")).willReturn(aResponse()
- .withBody(getBody(mapper.writeValueAsString(identity),wireMockPort, ""))
- .withHeader(org.apache.http.HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON)
- .withStatus(HttpStatus.SC_OK)));
- cloudConfig.getCloudSite("MTN13").get().getIdentityService().setIdentityUrl("http://localhost:" + wireMockPort + "/v2.0");
-
- }
-
@Test
public void createVfModule_ModelCustUuidIsNull() throws Exception {
expectedException.expect(VnfException.class);
@@ -155,7 +88,7 @@ public class MsoVnfPluginAdapterImplTest extends BaseRestTestUtils {
new Holder<VnfRollback>());
}
- /* @Test
+ @Test
public void createVfModule_INSTANTIATED() throws Exception {
mockOpenStackResponseAccess(wireMockPort);
mockOpenStackGetStackVfModule_200();
@@ -167,40 +100,7 @@ public class MsoVnfPluginAdapterImplTest extends BaseRestTestUtils {
null, "baseVfHeatStackId", "9b339a61-69ca-465f-86b8-1c72c582b8e8", map,
Boolean.FALSE, Boolean.TRUE, Boolean.FALSE, msoRequest, new Holder<>(), new Holder<Map<String, String>>(),
new Holder<VnfRollback>());
- }*/
-
- @Test
- public void createVfModule_INSTANTIATED_Multicloud() throws Exception {
- mockOpenStackResponseAccessMulticloud(wireMockPort);
- mockOpenStackGetStackVfModule_200();
-
- MsoRequest msoRequest = getMsoRequest();
- Map<String, String> map = new HashMap<>();
- map.put("key1", "value1");
- msoVnfPluginAdapter.createVfModule("MTN13", "88a6ca3ee0394ade9403f075db23167e", "vnf", "1", vnfName, "VFMOD",
- null, "baseVfHeatStackId", "9b339a61-69ca-465f-86b8-1c72c582b8e8", map,
- Boolean.FALSE, Boolean.TRUE, Boolean.FALSE, msoRequest, new Holder<>(), new Holder<Map<String, String>>(),
- new Holder<VnfRollback>());
- }
-
- /*
- @Test
- public void createVfModule_Multicloud() throws Exception {
- expectedException.expect(VnfException.class);
- mockOpenStackResponseAccessMulticloud(wireMockPort);
- mockOpenStackGetStackVfModule_404();
-
- MsoRequest msoRequest = getMsoRequest();
- Map<String, String> map = new HashMap<>();
- map.put("key1", "value1");
- map.put("oof_directives", "{ abc: 123 }");
- map.put("sdnc_directives", "{ def: 456 }");
- msoVnfPluginAdapter.createVfModule("MTN13", "88a6ca3ee0394ade9403f075db23167e", "vnf", "1", vnfName, "VFMOD",
- null, "baseVfHeatStackId", "9b339a61-69ca-465f-86b8-1c72c582b8e8", map,
- Boolean.FALSE, Boolean.TRUE, Boolean.FALSE, msoRequest, new Holder<>(), new Holder<Map<String, String>>(),
- new Holder<VnfRollback>());
}
- */
@Test
public void createVfModule_queryVduNotFoundWithVolumeGroupId() throws Exception {
diff --git a/adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack.json b/adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack.json
new file mode 100644
index 0000000000..068cb83a33
--- /dev/null
+++ b/adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack.json
@@ -0,0 +1,5 @@
+{
+ "template_type":"heat",
+ "workload_id": "vfname",
+ "workload_status":"STATUS"
+ } \ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack_Create.json b/adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack_Create.json
new file mode 100644
index 0000000000..b6092bfbe0
--- /dev/null
+++ b/adapters/mso-openstack-adapters/src/test/resources/__files/MulticloudResponse_Stack_Create.json
@@ -0,0 +1,16 @@
+{
+ "template_type": "heat",
+ "workload_id": "workload-id",
+ "template_response":
+ {
+ "stack": {
+ "id": "abcdef00-1234-abcd-5678-ef9123456789",
+ "links": [
+ {
+ "href": "http://localhost:1234/v1/id12345678/stacks/workload-id/abcdef00-1234-abcd-5678-ef9123456789",
+ "rel": "self"
+ }
+ ]
+ }
+ }
+}