diff options
Diffstat (limited to 'adapters')
32 files changed, 1334 insertions, 339 deletions
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java index 98793601d0..da81da91ea 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoCommonUtils.java @@ -2,14 +2,15 @@ * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ + * Copyright (C) 2018 Intel Corp. All rights reserved. * Copyright (C) 2017 AT&T Intellectual Property. 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. @@ -22,6 +23,9 @@ package org.onap.so.openstack.utils; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import org.onap.so.config.beans.PoConfig; import org.onap.so.logger.MessageEnum; @@ -35,10 +39,13 @@ import org.onap.so.openstack.exceptions.MsoOpenstackException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.woorea.openstack.base.client.OpenStackBaseException; import com.woorea.openstack.base.client.OpenStackConnectException; import com.woorea.openstack.base.client.OpenStackRequest; import com.woorea.openstack.base.client.OpenStackResponseException; +import com.woorea.openstack.heat.model.CreateStackParam; import com.woorea.openstack.heat.model.Explanation; import com.woorea.openstack.keystone.model.Error; import com.woorea.openstack.quantum.model.NeutronError; @@ -57,11 +64,11 @@ public class MsoCommonUtils { * sub-category that identifies the specific call (using the real * openstack-java-sdk classname of the OpenStackRequest<T> parameter). */ - + protected <T> T executeAndRecordOpenstackRequest (OpenStackRequest <T> request) { - + int limit; - + long start = System.currentTimeMillis (); String requestType; if (request.getClass ().getEnclosingClass () != null) { @@ -70,17 +77,17 @@ public class MsoCommonUtils { } else { requestType = request.getClass ().getSimpleName (); } - + int retryDelay = poConfig.getRetryDelay(); int retryCount = poConfig.getRetryCount(); String retryCodes = poConfig.getRetryCodes(); - + // Run the actual command. All exceptions will be propagated while (true) { try { return request.execute (); - } + } catch (OpenStackResponseException e) { boolean retry = false; if (retryCodes != null ) { @@ -128,11 +135,11 @@ public class MsoCommonUtils { } else throw e; - + } } } - + /* * Convert an Openstack Exception on a Keystone call to an MsoException. * This method supports both OpenstackResponseException and OpenStackConnectException. @@ -281,7 +288,7 @@ public class MsoCommonUtils { return me; } - + protected MsoException ioExceptionToMsoException(IOException e, String context) { MsoAdapterException me = new MsoAdapterException (e.getMessage (), e); me.addContext (context); @@ -297,7 +304,105 @@ public class MsoCommonUtils { public boolean isNullOrEmpty (String s) { return s == null || s.isEmpty(); } - - + + + protected CreateStackParam createStackParam(String stackName, + String heatTemplate, + Map <String, ?> stackInputs, + int timeoutMinutes, + String environment, + Map <String, Object> files, + Map <String, Object> heatFiles) { + + // Create local variables checking to see if we have an environment, nested, get_files + // Could later add some checks to see if it's valid. + boolean haveEnvtVariable = true; + if (environment == null || "".equalsIgnoreCase (environment.trim ())) { + haveEnvtVariable = false; + logger.debug ("createStackParam called with no environment variable"); + } else { + logger.debug ("createStackParam called with an environment variable: " + environment); + } + + boolean haveFiles = true; + if (files == null || files.isEmpty ()) { + haveFiles = false; + logger.debug ("createStackParam called with no files / child template ids"); + } else { + logger.debug ("createStackParam called with " + files.size () + " files / child template ids"); + } + + boolean haveHeatFiles = true; + if (heatFiles == null || heatFiles.isEmpty ()) { + haveHeatFiles = false; + logger.debug ("createStackParam called with no heatFiles"); + } else { + logger.debug ("createStackParam called with " + heatFiles.size () + " heatFiles"); + } + + //force entire stackInput object to generic Map<String, Object> for openstack compatibility + ObjectMapper mapper = new ObjectMapper(); + Map<String, Object> normalized = new HashMap<>(); + try { + normalized = mapper.readValue(mapper.writeValueAsString(stackInputs), new TypeReference<HashMap<String,Object>>() {}); + } catch (IOException e1) { + logger.debug("could not map json", e1); + } + + // Build up the stack to create + // Disable auto-rollback, because error reason is lost. Always rollback in the code. + CreateStackParam stack = new CreateStackParam (); + stack.setStackName (stackName); + stack.setTimeoutMinutes (timeoutMinutes); + stack.setParameters (normalized); + stack.setTemplate (heatTemplate); + stack.setDisableRollback (true); + // TJM New for PO Adapter - add envt variable + if (haveEnvtVariable) { + logger.debug ("Found an environment variable - value: " + environment); + stack.setEnvironment (environment); + } + // Now handle nested templates or get_files - have to combine if we have both + // as they're both treated as "files:" on the stack. + if (haveFiles && haveHeatFiles) { + // Let's do this here - not in the bean + logger.debug ("Found files AND heatFiles - combine and add!"); + Map <String, Object> combinedFiles = new HashMap <> (); + for (Entry<String, Object> entry : files.entrySet()) { + combinedFiles.put(entry.getKey(), entry.getValue()); + } + for (Entry<String, Object> entry : heatFiles.entrySet()) { + combinedFiles.put(entry.getKey(), entry.getValue()); + } + stack.setFiles (combinedFiles); + } else { + // Handle if we only have one or neither: + if (haveFiles) { + logger.debug ("Found files - adding to stack"); + stack.setFiles (files); + } + if (haveHeatFiles) { + logger.debug ("Found heatFiles - adding to stack"); + // the setFiles was modified to handle adding the entries + stack.setFiles (heatFiles); + } + } + + // 1802 - attempt to add better formatted printout of request to openstack + try { + Map<String, Object> inputs = new HashMap<>(); + for (Entry<String, ?> entry : stackInputs.entrySet()) { + if (entry.getValue() != null) { + inputs.put(entry.getKey(), entry.getValue()); + } + } + logger.debug("stack request:" + stack.toString()); + } catch (Exception e) { + // that's okay - this is a nice-to-have + logger.debug("(had an issue printing nicely formatted request to debuglog) " + e.getMessage()); + } + + return stack; + } } 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 6b66970ea0..15f84890b7 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 @@ -8,9 +8,9 @@ * 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. @@ -106,18 +106,18 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ // Fetch cloud configuration each time (may be cached in CloudConfig class) @Autowired protected CloudConfig cloudConfig; - + @Autowired private Environment environment; @Autowired private AuthenticationMethodFactory authenticationMethodFactory; - + @Autowired private MsoTenantUtilsFactory tenantUtilsFactory; - + private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA, MsoHeatUtils.class); - + // Properties names and variables (with default values) protected String createPollIntervalProp = "ecomp.mso.adapters.po.pollInterval"; private String deletePollIntervalProp = "ecomp.mso.adapters.po.pollInterval"; @@ -125,7 +125,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ protected static final String createPollIntervalDefault = "15"; private static final String deletePollIntervalDefault = "15"; - + private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); /** @@ -275,31 +275,19 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ Map <String, Object> files, Map <String, Object> heatFiles, boolean backout) throws MsoException { - // Create local variables checking to see if we have an environment, nested, get_files - // Could later add some checks to see if it's valid. - boolean haveEnvtVariable = true; - if (environment == null || "".equalsIgnoreCase (environment.trim ())) { - haveEnvtVariable = false; - LOGGER.debug ("createStack called with no environment variable"); - } else { - LOGGER.debug ("createStack called with an environment variable: " + environment); - } - boolean haveFiles = true; - if (files == null || files.isEmpty ()) { - haveFiles = false; - LOGGER.debug ("createStack called with no files / child template ids"); - } else { - LOGGER.debug ("createStack called with " + files.size () + " files / child template ids"); + // Take out the multicloud inputs, if present. + String[] directives = { "oof_directives", "sdnc_directives", "generic_vnf_id", "vf_module_id" }; + for (String key : directives) { + if (stackInputs.containsKey(key)) { + stackInputs.remove(key); + if (stackInputs.isEmpty()) { + break; + } + } } - boolean haveHeatFiles = true; - if (heatFiles == null || heatFiles.isEmpty ()) { - haveHeatFiles = false; - LOGGER.debug ("createStack called with no heatFiles"); - } else { - LOGGER.debug ("createStack called with " + heatFiles.size () + " heatFiles"); - } + CreateStackParam stack = createStackParam(stackName, heatTemplate, stackInputs, timeoutMinutes, environment, files, heatFiles); // Obtain the cloud site information where we will create the stack CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow( @@ -309,73 +297,11 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ // This could throw MsoTenantNotFound or MsoOpenstackException (both propagated) Heat heatClient = getHeatClient (cloudSite, tenantId); if (heatClient != null) { - LOGGER.debug("Found: " + heatClient.toString()); + LOGGER.debug("Found: " + heatClient.toString()); } LOGGER.debug ("Ready to Create Stack (" + heatTemplate + ") with input params: " + stackInputs); - //force entire stackInput object to generic Map<String, Object> for openstack compatibility - ObjectMapper mapper = new ObjectMapper(); - Map<String, Object> normalized = new HashMap<>(); - try { - normalized = mapper.readValue(mapper.writeValueAsString(stackInputs), new TypeReference<HashMap<String,Object>>() {}); - } catch (IOException e1) { - LOGGER.debug("could not map json", e1); - } - - // Build up the stack to create - // Disable auto-rollback, because error reason is lost. Always rollback in the code. - CreateStackParam stack = new CreateStackParam (); - stack.setStackName (stackName); - stack.setTimeoutMinutes (timeoutMinutes); - stack.setParameters (normalized); - stack.setTemplate (heatTemplate); - stack.setDisableRollback (true); - // TJM New for PO Adapter - add envt variable - if (haveEnvtVariable) { - LOGGER.debug ("Found an environment variable - value: " + environment); - stack.setEnvironment (environment); - } - // Now handle nested templates or get_files - have to combine if we have both - // as they're both treated as "files:" on the stack. - if (haveFiles && haveHeatFiles) { - // Let's do this here - not in the bean - LOGGER.debug ("Found files AND heatFiles - combine and add!"); - Map <String, Object> combinedFiles = new HashMap <> (); - for (Entry<String, Object> entry : files.entrySet()) { - combinedFiles.put(entry.getKey(), entry.getValue()); - } - for (Entry<String, Object> entry : heatFiles.entrySet()) { - combinedFiles.put(entry.getKey(), entry.getValue()); - } - stack.setFiles (combinedFiles); - } else { - // Handle if we only have one or neither: - if (haveFiles) { - LOGGER.debug ("Found files - adding to stack"); - stack.setFiles (files); - } - if (haveHeatFiles) { - LOGGER.debug ("Found heatFiles - adding to stack"); - // the setFiles was modified to handle adding the entries - stack.setFiles (heatFiles); - } - } - - // 1802 - attempt to add better formatted printout of request to openstack - try { - Map<String, Object> inputs = new HashMap<>(); - for (Entry<String, ?> entry : stackInputs.entrySet()) { - if (entry.getValue() != null) { - inputs.put(entry.getKey(), entry.getValue()); - } - } - LOGGER.debug(this.printStackRequest(tenantId, heatFiles, files, environment, inputs, stackName, heatTemplate, timeoutMinutes, backout, cloudSiteId)); - } catch (Exception e) { - // that's okay - this is a nice-to-have - LOGGER.debug("(had an issue printing nicely formatted request to debuglog) " + e.getMessage()); - } - Stack heatStack = null; try { // Execute the actual Openstack command to create the Heat stack @@ -401,7 +327,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ throw me; } else { // Convert the OpenStackResponseException to an MsoOpenstackException - LOGGER.debug("ERROR STATUS = " + e.getStatus() + ",\n" + e.getMessage() + "\n" + e.getLocalizedMessage()); + LOGGER.debug("ERROR STATUS = " + e.getStatus() + ",\n" + e.getMessage() + "\n" + e.getLocalizedMessage()); throw heatExceptionToMsoException (e, CREATE_STACK); } } catch (OpenStackConnectException e) { @@ -422,8 +348,8 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ // Set a time limit on overall polling. // Use the resource (template) timeout for Openstack (expressed in minutes) // and add one poll interval to give Openstack a chance to fail on its own.s - - int createPollInterval = Integer.parseInt(this.environment.getProperty(createPollIntervalProp, createPollIntervalDefault)); + + int createPollInterval = Integer.parseInt(this.environment.getProperty(createPollIntervalProp, createPollIntervalDefault)); int pollTimeout = (timeoutMinutes * 60) + createPollInterval; // New 1610 - poll on delete if we rollback - use same values for now int deletePollInterval = createPollInterval; @@ -741,7 +667,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ else { LOGGER.debug ("Heat Client is NULL" ); } - + executeAndRecordOpenstackRequest (request); } catch (OpenStackResponseException e) { if (e.getStatus () == 404) { @@ -765,7 +691,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ if (pollForCompletion) { // Set a timeout on polling - + int pollInterval = Integer.parseInt(this.environment.getProperty(deletePollIntervalProp, "" + deletePollIntervalDefault)); int pollTimeout = Integer.parseInt(this.environment.getProperty(deletePollTimeoutProp, "" + deletePollIntervalDefault)); @@ -914,7 +840,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ // Remove any extraneous parameters (don't throw an error) Map <String, Object> updatedParams = new HashMap <> (); List <String> extraParams = new ArrayList <> (); - + for (Entry<String, Object> entry : inputParams.entrySet()) { if (!paramList.contains(entry.getKey())) { // This is not a valid parameter for this template @@ -1079,7 +1005,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ */ protected Stack queryHeatStack (Heat heatClient, String stackName) throws MsoException { if (stackName == null) { - return null; + return null; } try { OpenStackRequest <Stack> request = heatClient.getStacks ().byName (stackName); @@ -1204,7 +1130,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } - private StringBuilder getOutputsAsStringBuilder(Stack heatStack) { + protected StringBuilder getOutputsAsStringBuilder(Stack heatStack) { // This should only be used as a utility to print out the stack outputs // to the log StringBuilder sb = new StringBuilder(""); @@ -1237,7 +1163,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } catch (Exception e) { LOGGER.debug("Exception :",e); sb.append("(a LinkedHashMap value that would not convert nicely)"); - } + } } else if (obj instanceof Integer) { String str = ""; try { @@ -1281,8 +1207,8 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ sb.append("[END]"); return sb; } - - + + public void copyBaseOutputsToInputs(Map<String, Object> inputs, Map<String, Object> otherStackOutputs, List<String> paramNames, Map<String, String> aliases) { if (inputs == null || otherStackOutputs == null) @@ -1331,7 +1257,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } return; } - + public List<String> convertCdlToArrayList(String cdl) { String cdl2 = cdl.trim(); String cdl3; @@ -1342,7 +1268,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } return new ArrayList<>(Arrays.asList(cdl3.split(","))); } - + /** * New with 1707 - this method will convert all the String *values* of the inputs * to their "actual" object type (based on the param type: in the db - which comes from the template): @@ -1364,12 +1290,12 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ HashMap<String, Object> newInputs = new HashMap<>(); HashMap<String, HeatTemplateParam> params = new HashMap<>(); HashMap<String, HeatTemplateParam> paramAliases = new HashMap<>(); - + if (inputs == null) { LOGGER.debug("convertInputMap - inputs is null - nothing to do here"); return new HashMap<>(); } - + LOGGER.debug("convertInputMap in MsoHeatUtils called, with " + inputs.size() + " inputs, and template " + template.getArtifactUuid()); try { LOGGER.debug(template.toString()); @@ -1378,7 +1304,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } catch (Exception e) { LOGGER.debug("Exception occurred in convertInputMap:" + e.getMessage(), e); } - + for (HeatTemplateParam htp : template.getParameters()) { LOGGER.debug("Adding " + htp.getParamName()); params.put(htp.getParamName(), htp); @@ -1413,9 +1339,9 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ if ("string".equalsIgnoreCase(type)) { // Easiest! String str = inputs.get(key); - if (alias) + if (alias) newInputs.put(realName, str); - else + else newInputs.put(key, str); } else if ("number".equalsIgnoreCase(type)) { String integerString = inputs.get(key); @@ -1480,9 +1406,9 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } return newInputs; } - - /* - * This helpful method added for Valet + + /* + * This helpful method added for Valet */ public String getCloudSiteKeystoneUrl(String cloudSiteId) throws MsoCloudSiteNotFound { String keystone_url = null; @@ -1498,17 +1424,17 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } return keystone_url; } - + /* - * Create a string suitable for being dumped to a debug log that creates a + * Create a string suitable for being dumped to a debug log that creates a * pseudo-JSON request dumping what's being sent to Openstack API in the create or update request */ - - private String printStackRequest(String tenantId, + + private String printStackRequest(String tenantId, Map<String, Object> heatFiles, Map<String, Object> nestedTemplates, String environment, - Map<String, Object> inputs, + Map<String, Object> inputs, String vfModuleName, String template, int timeoutMinutes, @@ -1520,14 +1446,14 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ sb.append("{\n"); sb.append(" \"stack_name\": \"" + vfModuleName + "\",\n"); sb.append(" \"disable_rollback\": " + backout + ",\n"); - sb.append(" \"timeout_mins\": " + timeoutMinutes + ",\n"); + sb.append(" \"timeout_mins\": " + timeoutMinutes + ",\n"); sb.append(" \"template\": {\n"); sb.append(template); sb.append(" },\n"); sb.append(" \"environment\": {\n"); - if (environment == null) + if (environment == null) sb.append("<none>"); - else + else sb.append(environment); sb.append(" },\n"); sb.append(" \"files\": {\n"); @@ -1574,19 +1500,19 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } } sb.append("\n }\n}\n"); - + return sb.toString(); } - + /******************************************************************************* - * + * * Methods (and associated utilities) to implement the VduPlugin interface - * + * *******************************************************************************/ - + /** * VduPlugin interface for instantiate function. - * + * * Translate the VduPlugin parameters to the corresponding 'createStack' parameters, * and then invoke the existing function. */ @@ -1601,7 +1527,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ { String cloudSiteId = cloudInfo.getCloudSiteId(); String tenantId = cloudInfo.getTenantId(); - + // Translate the VDU ModelInformation structure to that which is needed for // creating the Heat stack. Loop through the artifacts, looking specifically // for MAIN_TEMPLATE and ENVIRONMENT. Any other artifact will @@ -1610,7 +1536,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ Map<String,Object> nestedTemplates = new HashMap<>(); Map<String,Object> files = new HashMap<>(); String heatEnvironment = null; - + for (VduArtifact vduArtifact: vduModel.getArtifacts()) { if (vduArtifact.getType() == ArtifactType.MAIN_TEMPLATE) { heatTemplate = new String(vduArtifact.getContent()); @@ -1622,7 +1548,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ heatEnvironment = new String(vduArtifact.getContent()); } } - + try { StackInfo stackInfo = createStack (cloudSiteId, tenantId, @@ -1635,7 +1561,7 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ nestedTemplates, files, rollbackOnFailure); - + // Populate a vduInstance from the StackInfo return stackInfoToVduInstance(stackInfo); } @@ -1643,8 +1569,8 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ throw new VduException ("MsoHeatUtils (instantiateVDU): createStack Exception", e); } } - - + + /** * VduPlugin interface for query function. */ @@ -1654,19 +1580,19 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ { String cloudSiteId = cloudInfo.getCloudSiteId(); String tenantId = cloudInfo.getTenantId(); - + try { // Query the Cloudify Deployment object and populate a VduInstance StackInfo stackInfo = queryStack (cloudSiteId, tenantId, instanceId); - + return stackInfoToVduInstance(stackInfo); } catch (Exception e) { throw new VduException ("MsoHeatUtile (queryVdu): queryStack Exception ", e); } } - - + + /** * VduPlugin interface for delete function. */ @@ -1676,31 +1602,31 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ { String cloudSiteId = cloudInfo.getCloudSiteId(); String tenantId = cloudInfo.getTenantId(); - + try { // Delete the Heat stack StackInfo stackInfo = deleteStack (tenantId, cloudSiteId, instanceId, true); - + // Populate a VduInstance based on the deleted Cloudify Deployment object VduInstance vduInstance = stackInfoToVduInstance(stackInfo); - + // Override return state to DELETED (HeatUtils sets to NOTFOUND) vduInstance.getStatus().setState(VduStateType.DELETED); - + return vduInstance; } catch (Exception e) { throw new VduException ("Delete VDU Exception", e); } } - - + + /** * VduPlugin interface for update function. - * + * * Update is currently not supported in the MsoHeatUtils implementation of VduPlugin. * Just return a VduException. - * + * */ @Override public VduInstance updateVdu ( @@ -1713,38 +1639,38 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ { throw new VduException ("MsoHeatUtils: updateVdu interface not supported"); } - - + + /* * Convert the local DeploymentInfo object (Cloudify-specific) to a generic VduInstance object */ - private VduInstance stackInfoToVduInstance (StackInfo stackInfo) + protected VduInstance stackInfoToVduInstance (StackInfo stackInfo) { VduInstance vduInstance = new VduInstance(); - + // The full canonical name as the instance UUID vduInstance.setVduInstanceId(stackInfo.getCanonicalName()); vduInstance.setVduInstanceName(stackInfo.getName()); - + // Copy inputs and outputs vduInstance.setInputs(stackInfo.getParameters()); vduInstance.setOutputs(stackInfo.getOutputs()); - + // Translate the status elements vduInstance.setStatus(stackStatusToVduStatus (stackInfo)); - + return vduInstance; } - + private VduStatus stackStatusToVduStatus (StackInfo stackInfo) { VduStatus vduStatus = new VduStatus(); - + // Map the status fields to more generic VduStatus. // There are lots of HeatStatus values, so this is a bit long... HeatStatus heatStatus = stackInfo.getStatus(); String statusMessage = stackInfo.getStatusMessage(); - + if (heatStatus == HeatStatus.INIT || heatStatus == HeatStatus.BUILDING) { vduStatus.setState(VduStateType.INSTANTIATING); vduStatus.setLastAction((new PluginAction ("create", "in_progress", statusMessage))); @@ -1774,10 +1700,10 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ } else { vduStatus.setState(VduStateType.UNKNOWN); } - + return vduStatus; } - + private void sleep(long time) { try { Thread.sleep(time); @@ -1786,5 +1712,5 @@ public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ Thread.currentThread().interrupt(); } } - + } 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 new file mode 100644 index 0000000000..9b2475a1c4 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudParam.java @@ -0,0 +1,110 @@ +/*- + * ============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 new file mode 100644 index 0000000000..4ed35a4d28 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java @@ -0,0 +1,483 @@ +/*- + * ============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.net.MalformedURLException; +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriBuilderException; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.onap.so.adapters.vdu.CloudInfo; +import org.onap.so.adapters.vdu.PluginAction; +import org.onap.so.adapters.vdu.VduArtifact; +import org.onap.so.adapters.vdu.VduArtifact.ArtifactType; +import org.onap.so.adapters.vdu.VduException; +import org.onap.so.adapters.vdu.VduInstance; +import org.onap.so.adapters.vdu.VduModelInfo; +import org.onap.so.adapters.vdu.VduPlugin; +import org.onap.so.adapters.vdu.VduStateType; +import org.onap.so.adapters.vdu.VduStatus; +import org.onap.so.openstack.beans.HeatStatus; +import org.onap.so.openstack.beans.StackInfo; +import org.onap.so.openstack.exceptions.MsoCloudSiteNotFound; +import org.onap.so.openstack.exceptions.MsoException; +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.stereotype.Component; + +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; + + private static final String ONAP_IP = "ONAP_IP"; + + private static final String DEFAULT_MSB_IP = "127.0.0.1"; + + private static final Integer DEFAULT_MSB_PORT = 80; + + private static final Logger logger = LoggerFactory.getLogger(MsoMulticloudUtils.class); + + /****************************************************************************** + * + * Methods (and associated utilities) to implement the VduPlugin interface + * + *******************************************************************************/ + + /** + * Create a new Stack in the specified cloud location and tenant. The Heat template + * and parameter map are passed in as arguments, along with the cloud access credentials. + * It is expected that parameters have been validated and contain at minimum the required + * parameters for the given template with no extra (undefined) parameters.. + * + * The Stack name supplied by the caller must be unique in the scope of this tenant. + * However, it should also be globally unique, as it will be the identifier for the + * resource going forward in Inventory. This latter is managed by the higher levels + * invoking this function. + * + * The caller may choose to let this function poll Openstack for completion of the + * stack creation, or may handle polling itself via separate calls to query the status. + * In either case, a StackInfo object will be returned containing the current status. + * When polling is enabled, a status of CREATED is expected. When not polling, a + * status of BUILDING is expected. + * + * An error will be thrown if the requested Stack already exists in the specified + * Tenant and Cloud. + * + * For 1510 - add "environment", "files" (nested templates), and "heatFiles" (get_files) as + * parameters for createStack. If environment is non-null, it will be added to the stack. + * The nested templates and get_file entries both end up being added to the "files" on the + * stack. We must combine them before we add them to the stack if they're both non-null. + * + * @param cloudSiteId The cloud (may be a region) in which to create the stack. + * @param tenantId The Openstack ID of the tenant in which to create the Stack + * @param stackName The name of the stack to create + * @param heatTemplate The Heat template + * @param stackInputs A map of key/value inputs + * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client + * @param environment An optional yaml-format string to specify environmental parameters + * @param files a Map<String, Object> that lists the child template IDs (file is the string, object is an int of + * Template id) + * @param heatFiles a Map<String, Object> that lists the get_file entries (fileName, fileBody) + * @param backout Donot delete stack on create Failure - defaulted to True + * @return A StackInfo object + * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. + */ + + @SuppressWarnings("unchecked") + @Override + public StackInfo createStack (String cloudSiteId, + String tenantId, + String stackName, + String heatTemplate, + Map <String, ?> stackInputs, + boolean pollForCompletion, + int timeoutMinutes, + String environment, + Map <String, Object> files, + 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; + + 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); + } + + // 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()); + + + String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, null); + RestClient multicloudClient = getMulticloudClient(multicloudEndpoint); + + if (multicloudClient != null) { + Response res = multicloudClient.post(multicloudParam); + logger.debug("Multicloud Post response is: " + res); + } + + Stack responseStack = new Stack(); + responseStack.setStackStatus(HeatStatus.CREATED.toString()); + + return new StackInfoMapper(responseStack).map(); + } + + public Map<String, Object> queryStackForOutputs(String cloudSiteId, + String tenantId, String stackName) throws MsoException { + logger.debug("MsoHeatUtils.queryStackForOutputs)"); + StackInfo heatStack = this.queryStack(cloudSiteId, tenantId, stackName); + if (heatStack == null || heatStack.getStatus() == HeatStatus.NOTFOUND) { + return null; + } + return heatStack.getOutputs(); + } + + /** + * Query for a single stack (by Name) in a tenant. This call will always return a + * StackInfo object. If the stack does not exist, an "empty" StackInfo will be + * returned - containing only the stack name and a status of NOTFOUND. + * + * @param tenantId The Openstack ID of the tenant in which to query + * @param cloudSiteId The cloud identifier (may be a region) in which to query + * @param stackName The name of the stack to query (may be simple or canonical) + * @return A StackInfo object + * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. + */ + @Override + public StackInfo queryStack (String cloudSiteId, String tenantId, String stackName) throws MsoException { + logger.debug ("Query multicloud HEAT stack: " + stackName + " in tenant " + tenantId); + + String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, stackName); + + RestClient multicloudClient = getMulticloudClient(multicloudEndpoint); + + if (multicloudClient != null) { + Response response = multicloudClient.get(); + logger.debug("Multicloud Get response is: " + response); + + return new StackInfo (stackName, HeatStatus.CREATED); + } + + return new StackInfo (stackName, HeatStatus.NOTFOUND); + } + + public StackInfo deleteStack (String cloudSiteId, String tenantId, String stackName) throws MsoException { + logger.debug ("Delete multicloud HEAT stack: " + stackName + " in tenant " + tenantId); + + 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); + } + + return new StackInfo (stackName, HeatStatus.FAILED); + } + + // --------------------------------------------------------------- + // PRIVATE FUNCTIONS FOR USE WITHIN THIS CLASS + + + private String getMsbHost() { + // MSB_IP will be set as ONAP_IP environment parameter in install flow. + String msbIp = System.getenv().get(ONAP_IP); + + // 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); + } + Integer msbPort = env.getProperty("mso.msb-port", Integer.class, DEFAULT_MSB_PORT); + + return UriBuilder.fromPath("").host(msbIp).port(msbPort).scheme("http").build().toString(); + } + + private String getMulticloudEndpoint(String cloudSiteId, String workloadId) throws MsoCloudSiteNotFound { + + CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId)); + String endpoint = getMsbHost() + cloudSite.getIdentityService().getIdentityUrl(); + + if (workloadId != null) { + return endpoint + workloadId; + } else { + return endpoint; + } + } + + private RestClient getMulticloudClient(String endpoint) { + RestClient client = null; + try { + client= new HttpClient(UriBuilder.fromUri(endpoint).build().toURL(), + "application/json", TargetEntity.OPENSTACK_ADAPTER); + } catch (MalformedURLException e) { + logger.debug("Encountered malformed URL error getting multicloud rest client " + e.getMessage()); + } catch (IllegalArgumentException e) { + logger.debug("Encountered illegal argument getting multicloud rest client " + e.getMessage()); + } catch (UriBuilderException e) { + logger.debug("Encountered URI builder error getting multicloud rest client " + e.getMessage()); + } + return client; + } + + /** + * VduPlugin interface for instantiate function. + * + * Translate the VduPlugin parameters to the corresponding 'createStack' parameters, + * and then invoke the existing function. + */ + @Override + public VduInstance instantiateVdu ( + CloudInfo cloudInfo, + String instanceName, + Map<String,Object> inputs, + VduModelInfo vduModel, + boolean rollbackOnFailure) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + // Translate the VDU ModelInformation structure to that which is needed for + // creating the Heat stack. Loop through the artifacts, looking specifically + // for MAIN_TEMPLATE and ENVIRONMENT. Any other artifact will + // be attached as a FILE. + String heatTemplate = null; + Map<String,Object> nestedTemplates = new HashMap<>(); + Map<String,Object> files = new HashMap<>(); + String heatEnvironment = null; + + for (VduArtifact vduArtifact: vduModel.getArtifacts()) { + if (vduArtifact.getType() == ArtifactType.MAIN_TEMPLATE) { + heatTemplate = new String(vduArtifact.getContent()); + } + else if (vduArtifact.getType() == ArtifactType.NESTED_TEMPLATE) { + nestedTemplates.put(vduArtifact.getName(), new String(vduArtifact.getContent())); + } + else if (vduArtifact.getType() == ArtifactType.ENVIRONMENT) { + heatEnvironment = new String(vduArtifact.getContent()); + } + } + + try { + StackInfo stackInfo = createStack (cloudSiteId, + tenantId, + instanceName, + heatTemplate, + inputs, + true, // poll for completion + vduModel.getTimeoutMinutes(), + heatEnvironment, + nestedTemplates, + files, + rollbackOnFailure); + // Populate a vduInstance from the StackInfo + return stackInfoToVduInstance(stackInfo); + } + catch (Exception e) { + throw new VduException ("MsoMulticloudUtils (instantiateVDU): createStack Exception", e); + } + } + + + /** + * VduPlugin interface for query function. + */ + @Override + public VduInstance queryVdu (CloudInfo cloudInfo, String instanceId) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + try { + // Query the Cloudify Deployment object and populate a VduInstance + StackInfo stackInfo = queryStack (cloudSiteId, tenantId, instanceId); + + return stackInfoToVduInstance(stackInfo); + } + catch (Exception e) { + throw new VduException ("MsoMulticloudUtils (queryVdu): queryStack Exception ", e); + } + } + + + /** + * VduPlugin interface for delete function. + */ + @Override + public VduInstance deleteVdu (CloudInfo cloudInfo, String instanceId, int timeoutMinutes) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + try { + // Delete the Multicloud stack + StackInfo stackInfo = deleteStack (tenantId, cloudSiteId, instanceId, true); + + // Populate a VduInstance based on the deleted Cloudify Deployment object + VduInstance vduInstance = stackInfoToVduInstance(stackInfo); + + // Override return state to DELETED (MulticloudUtils sets to NOTFOUND) + vduInstance.getStatus().setState(VduStateType.DELETED); + + return vduInstance; + } + catch (Exception e) { + throw new VduException ("Delete VDU Exception", e); + } + } + + + /** + * VduPlugin interface for update function. + * + * Update is currently not supported in the MsoMulticloudUtils implementation of VduPlugin. + * Just return a VduException. + * + */ + @Override + public VduInstance updateVdu ( + CloudInfo cloudInfo, + String instanceId, + Map<String,Object> inputs, + VduModelInfo vduModel, + boolean rollbackOnFailure) + throws VduException + { + throw new VduException ("MsoMulticloudUtils: updateVdu interface not supported"); + } + + + /* + * Convert the local DeploymentInfo object (Cloudify-specific) to a generic VduInstance object + */ + protected VduInstance stackInfoToVduInstance (StackInfo stackInfo) + { + VduInstance vduInstance = new VduInstance(); + + // The full canonical name as the instance UUID + vduInstance.setVduInstanceId(stackInfo.getCanonicalName()); + vduInstance.setVduInstanceName(stackInfo.getName()); + + // Copy inputs and outputs + vduInstance.setInputs(stackInfo.getParameters()); + vduInstance.setOutputs(stackInfo.getOutputs()); + + // Translate the status elements + vduInstance.setStatus(stackStatusToVduStatus (stackInfo)); + + return vduInstance; + } + + private VduStatus stackStatusToVduStatus (StackInfo stackInfo) + { + VduStatus vduStatus = new VduStatus(); + + // Map the status fields to more generic VduStatus. + // There are lots of HeatStatus values, so this is a bit long... + HeatStatus heatStatus = stackInfo.getStatus(); + String statusMessage = stackInfo.getStatusMessage(); + + if (heatStatus == HeatStatus.INIT || heatStatus == HeatStatus.BUILDING) { + vduStatus.setState(VduStateType.INSTANTIATING); + vduStatus.setLastAction((new PluginAction ("create", "in_progress", statusMessage))); + } + else if (heatStatus == HeatStatus.NOTFOUND) { + vduStatus.setState(VduStateType.NOTFOUND); + } + else if (heatStatus == HeatStatus.CREATED) { + vduStatus.setState(VduStateType.INSTANTIATED); + vduStatus.setLastAction((new PluginAction ("create", "complete", statusMessage))); + } + else if (heatStatus == HeatStatus.UPDATED) { + vduStatus.setState(VduStateType.INSTANTIATED); + vduStatus.setLastAction((new PluginAction ("update", "complete", statusMessage))); + } + else if (heatStatus == HeatStatus.UPDATING) { + vduStatus.setState(VduStateType.UPDATING); + vduStatus.setLastAction((new PluginAction ("update", "in_progress", statusMessage))); + } + else if (heatStatus == HeatStatus.DELETING) { + vduStatus.setState(VduStateType.DELETING); + vduStatus.setLastAction((new PluginAction ("delete", "in_progress", statusMessage))); + } + else if (heatStatus == HeatStatus.FAILED) { + vduStatus.setState(VduStateType.FAILED); + vduStatus.setErrorMessage(stackInfo.getStatusMessage()); + } else { + vduStatus.setState(VduStateType.UNKNOWN); + } + + return vduStatus; + } +} diff --git a/adapters/mso-adapter-utils/src/test/resources/__files/HeatStack.json b/adapters/mso-adapter-utils/src/test/resources/__files/HeatStack.json index 411a3e0bd7..679e8e1832 100644 --- a/adapters/mso-adapter-utils/src/test/resources/__files/HeatStack.json +++ b/adapters/mso-adapter-utils/src/test/resources/__files/HeatStack.json @@ -1,11 +1,11 @@ { "description" : "description", "links" : [], - "stackStatusReason" : "stackStatusReason", - "stackName" : "stackName", - "updatedTime" : null, - "creationTime" : null, - "stackStatus" : "stackStatus", + "stack_status_reason" : "stackStatusReason", + "stack_name" : "stackName", + "updated_time" : null, + "creation_time" : null, + "stack_status" : "stackStatus", "id" : "id", "files" : {} }
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Access.json b/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Access.json index f1c08cc093..cd516ad082 100644 --- a/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Access.json +++ b/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Access.json @@ -18,7 +18,7 @@ "adminURL": null } ], - "endpointsLinks": null + "endpoints_links": null }, { "type": "network", @@ -31,7 +31,7 @@ "adminURL": null } ], - "endpointsLinks": null + "endpoints_links": null }, { "type": "identity", @@ -44,7 +44,7 @@ "adminURL": null } ], - "endpointsLinks": null + "endpoints_links": null } ], "user": null, diff --git a/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Stack_DeleteComplete.json b/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Stack_DeleteComplete.json index 8612258eee..a26a551f7d 100644 --- a/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Stack_DeleteComplete.json +++ b/adapters/mso-adapter-utils/src/test/resources/__files/OpenstackResponse_Stack_DeleteComplete.json @@ -2,10 +2,10 @@ "stack": { "description": null, "links": null, - "stackStatusReason": null, - "stackName": null, - "updatedTime": null, - "creationTime": null, + "stack_status_reason": null, + "stack_name": null, + "updated_time": null, + "creation_time": null, "stack_status": "DELETE_COMPLETE", "id": "stackId", "files": null, diff --git a/adapters/mso-adapter-utils/src/test/resources/__files/UpdateStack.json b/adapters/mso-adapter-utils/src/test/resources/__files/UpdateStack.json index 0a09d599ba..bf61cc8c8b 100644 --- a/adapters/mso-adapter-utils/src/test/resources/__files/UpdateStack.json +++ b/adapters/mso-adapter-utils/src/test/resources/__files/UpdateStack.json @@ -1,11 +1,11 @@ { "description" : "description", "links" : [], - "stackStatusReason" : "stackStatusReason", - "stackName" : "stackName", - "updatedTime" : null, - "creationTime" : null, - "stackStatus" : "UPDATE_COMPLETE", + "stack_status_reason" : "stackStatusReason", + "stack_name" : "stackName", + "updated_time" : null, + "creation_time" : null, + "stack_status" : "UPDATE_COMPLETE", "id" : "id", "files" : {} }
\ No newline at end of file diff --git a/adapters/mso-adapters-rest-interface/src/test/resources/stack-example.json b/adapters/mso-adapters-rest-interface/src/test/resources/stack-example.json index c0f08f8bd7..968f6179b0 100644 --- a/adapters/mso-adapters-rest-interface/src/test/resources/stack-example.json +++ b/adapters/mso-adapters-rest-interface/src/test/resources/stack-example.json @@ -1,13 +1,12 @@ { "outputs" : [{ - "outputKey": "key1", - "outputValue": "value1" + "output_key": "key1", + "output_value": "value1" },{ - "outputKey": "key2", - "outputValue": "value2" + "output_key": "key2", + "output_value": "value2" },{ - "outputKey": "key3", - "outputValue": "value3" + "output_key": "key3", + "output_value": "value3" }] - }
\ No newline at end of file diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.11__RecreateRecipe.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.11__RecreateRecipe.sql new file mode 100644 index 0000000000..627f7a4a61 --- /dev/null +++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.11__RecreateRecipe.sql @@ -0,0 +1,5 @@ +use catalogdb; + +INSERT INTO `vnf_recipe` (`NF_ROLE`, `ACTION`, `VERSION_STR`, `DESCRIPTION`, `ORCHESTRATION_URI`, `RECIPE_TIMEOUT`) +VALUES +('GR-API-DEFAULT', 'recreateInstance', '1', 'Gr api recipe to recreate vnf', '/mso/async/services/WorkflowActionBB', 180);
\ No newline at end of file diff --git a/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/adapters/catalogdb/catalogrest/CatalogDBRestTest.java b/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/adapters/catalogdb/catalogrest/CatalogDBRestTest.java index 8ccf40eff5..e15311eb0e 100644 --- a/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/adapters/catalogdb/catalogrest/CatalogDBRestTest.java +++ b/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/adapters/catalogdb/catalogrest/CatalogDBRestTest.java @@ -111,7 +111,7 @@ public class CatalogDBRestTest { assertEquals(Response.Status.OK.getStatusCode(),response.getStatusCode().value()); for(ILoggingEvent logEvent : TestAppender.events) if(logEvent.getLoggerName().equals("org.onap.so.logging.spring.interceptor.LoggingInterceptor") && - logEvent.getMarker().getName().equals("ENTRY") + logEvent.getMarker() != null && logEvent.getMarker().getName().equals("ENTRY") ){ Map<String,String> mdc = logEvent.getMDCPropertyMap(); assertNotNull(mdc.get(ONAPLogConstants.MDCs.INSTANCE_UUID)); diff --git a/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/db/catalog/client/CatalogDbClientTest.java b/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/db/catalog/client/CatalogDbClientTest.java index 4ec5839cb6..3783a51689 100644 --- a/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/db/catalog/client/CatalogDbClientTest.java +++ b/adapters/mso-catalog-db-adapter/src/test/java/org/onap/so/db/catalog/client/CatalogDbClientTest.java @@ -38,6 +38,7 @@ import org.onap.so.db.catalog.beans.VnfComponentsRecipe; import org.onap.so.db.catalog.beans.VnfRecipe; import org.onap.so.db.catalog.beans.VnfResource; import org.onap.so.db.catalog.beans.VnfResourceCustomization; +import org.onap.so.db.catalog.beans.macro.RainyDayHandlerStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; @@ -63,6 +64,18 @@ public class CatalogDbClientTest { } @Test + public void testGetRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep(){ + RainyDayHandlerStatus rainyDayHandlerStatus = client.getRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep("AssignServiceInstanceBB", "*", "*", "*", "*"); + Assert.assertEquals("Rollback", rainyDayHandlerStatus.getPolicy()); + } + + @Test + public void testGetRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStepRecordNotFound(){ + RainyDayHandlerStatus rainyDayHandlerStatus = client.getRainyDayHandlerStatusByFlowNameAndServiceTypeAndVnfTypeAndErrorCodeAndWorkStep(UUID.randomUUID().toString(), "*", "*", "*", "*"); + Assert.assertNull(rainyDayHandlerStatus); + } + + @Test public void testGetCloudSiteHappyPath() throws Exception { CloudSite cloudSite = client.getCloudSite(MTN13); Assert.assertNotNull(cloudSite); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterAsyncImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterAsyncImpl.java index 2eeed777de..b47905d134 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterAsyncImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterAsyncImpl.java @@ -294,7 +294,7 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { } catch (Exception e1) { error = "Error sending updateNetwork notification " + e1.getMessage (); LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending updateNetwork notification", e1); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -311,7 +311,7 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { } catch (Exception e) { error = "Error sending updateNotification request" + e.getMessage (); LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending updateNotification request", e); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -376,9 +376,9 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl); notifyPort.queryNetworkNotification (messageId, false, exCat, eMsg, null, null, null, null, null, null); } catch (Exception e1) { - error = "Error sending createNetwork notification " + e1.getMessage (); - LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e1); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + error = CREATE_NETWORK_ERROR_MSG + e1.getMessage (); + LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, CREATE_NETWORK_EXCEPTON_MSG, e1); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -398,9 +398,9 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { vlans.value, copyQuerySubnetIdMap (subnetIdMap)); } catch (Exception e) { - error = "Error sending createNetwork notification " + e.getMessage (); - LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + error = CREATE_NETWORK_ERROR_MSG + e.getMessage (); + LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, CREATE_NETWORK_EXCEPTON_MSG, e); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -463,9 +463,9 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl); notifyPort.deleteNetworkNotification (messageId, false, exCat, eMsg, null); } catch (Exception e1) { - error = "Error sending createNetwork notification " + e1.getMessage (); - LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e1); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + error = CREATE_NETWORK_ERROR_MSG + e1.getMessage (); + LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, CREATE_NETWORK_EXCEPTON_MSG, e1); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -477,7 +477,7 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { } catch (Exception e) { error = "Error sending deleteNetwork notification " + e.getMessage (); LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending deleteNetwork notification", e); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -527,9 +527,9 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl); notifyPort.rollbackNetworkNotification (rollback.getMsoRequest ().getRequestId (), false, exCat, eMsg); } catch (Exception e1) { - error = "Error sending createNetwork notification " + e1.getMessage (); + error = CREATE_NETWORK_ERROR_MSG + e1.getMessage (); LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception in sending createNetwork notification ", e1); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -541,7 +541,7 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { } catch (Exception e) { error = "Error sending rollbackNetwork notification " + e.getMessage (); LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception in sending rollbackNetwork notification", e); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error); } return; } @@ -627,7 +627,7 @@ public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync { } catch (Exception e) { String error1 = "Unable to set authorization in callback request" + e.getMessage (); LOGGER.error (MessageEnum.RA_SET_CALLBACK_AUTH_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception - Unable to set authorization in callback request", e); - alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error1); + alarmLogger.sendAlarm (MSO_INTERNAL_ERROR_MSG, MsoAlarmLogger.CRITICAL, error1); } return notifyPort; diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java index ac33a5269e..4b6bd09144 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/MsoNetworkAdapterImpl.java @@ -42,6 +42,8 @@ import org.onap.so.db.catalog.beans.CloudSite; import org.onap.so.db.catalog.beans.HeatTemplate; import org.onap.so.db.catalog.beans.NetworkResource; import org.onap.so.db.catalog.beans.NetworkResourceCustomization; +import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization; +import org.onap.so.db.catalog.data.repository.CollectionNetworkResourceCustomizationRepository; import org.onap.so.db.catalog.data.repository.NetworkResourceCustomizationRepository; import org.onap.so.db.catalog.data.repository.NetworkResourceRepository; import org.onap.so.db.catalog.utils.MavenLikeVersioning; @@ -108,6 +110,9 @@ public class MsoNetworkAdapterImpl implements MsoNetworkAdapter { private NetworkResourceCustomizationRepository networkCustomRepo; @Autowired + private CollectionNetworkResourceCustomizationRepository collectionNetworkCustomRepo; + + @Autowired private NetworkResourceRepository networkResourceRepo; /** * Health Check web method. Does nothing but return to show the adapter is deployed. @@ -1124,18 +1129,26 @@ public class MsoNetworkAdapterImpl implements MsoNetworkAdapter { // Retrieve the Network Resource definition NetworkResource networkResource = null; NetworkResourceCustomization networkCust = null; + CollectionNetworkResourceCustomization collectionNetworkCust = null; if (commonUtils.isNullOrEmpty(modelCustomizationUuid)) { if (!commonUtils.isNullOrEmpty(networkType)) { - networkResource = networkResourceRepo.findOneByModelName(networkType); + networkResource = networkResourceRepo.findFirstByModelNameOrderByModelVersionDesc(networkType); } } else { networkCust = networkCustomRepo.findOneByModelCustomizationUUID(modelCustomizationUuid); + if (networkCust == null) { + collectionNetworkCust = collectionNetworkCustomRepo.findOneByModelCustomizationUUID(modelCustomizationUuid); + } } if(networkCust != null){ LOGGER.debug("Got Network Customization definition from Catalog: " + networkCust.toString()); networkResource = networkCust.getNetworkResource(); + } else if (collectionNetworkCust != null) { + LOGGER.debug("Retrieved Collection Network Resource Customization from Catalog: " + + collectionNetworkCust.toString()); + networkResource = collectionNetworkCust.getNetworkResource(); } if (networkResource == null) { String error = "Create/UpdateNetwork: Unable to get network resource with NetworkType:" diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java index 465fb6d866..effe7a8c61 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/NetworkAdapterRest.java @@ -84,8 +84,8 @@ import io.swagger.annotations.ApiResponses; public class NetworkAdapterRest { private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA,NetworkAdapterRest.class); private static final String TESTING_KEYWORD = "___TESTING___"; - - + private String APPEND_RESPONSE = ", resp="; + private String EXCEPTION = "Exception:"; @Autowired private MsoNetworkAdapterImpl adapter; @@ -239,7 +239,7 @@ public class NetworkAdapterRest { rollback.value, req.getMessageId()); } catch (NetworkException e) { - LOGGER.debug ("Exception:", e); + LOGGER.debug (EXCEPTION, e); eresp = new CreateNetworkError( e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); } @@ -248,7 +248,7 @@ public class NetworkAdapterRest { BpelRestClient bpelClient = bpelRestClientProvider.get(); bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); } - LOGGER.debug ("CreateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + LOGGER.debug ("CreateNetworkTask exit: code=" + getStatusCode() + APPEND_RESPONSE+ getResponse()); } } @@ -345,7 +345,7 @@ public class NetworkAdapterRest { } response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId()); } catch (NetworkException e) { - LOGGER.debug ("Exception:", e); + LOGGER.debug (EXCEPTION, e); eresp = new DeleteNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); } if (!req.isSynchronous()) { @@ -353,7 +353,7 @@ public class NetworkAdapterRest { BpelRestClient bpelClient = bpelRestClientProvider.get(); bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); } - LOGGER.debug("DeleteNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + LOGGER.debug("DeleteNetworkTask exit: code=" + getStatusCode() + APPEND_RESPONSE+ getResponse()); } } @@ -501,7 +501,7 @@ public class NetworkAdapterRest { adapter.rollbackNetwork(nwr); response = new RollbackNetworkResponse(true, req.getMessageId()); } catch (NetworkException e) { - LOGGER.debug ("Exception:", e); + LOGGER.debug (EXCEPTION, e); eresp = new RollbackNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); } if (!req.isSynchronous()) { @@ -509,7 +509,7 @@ public class NetworkAdapterRest { BpelRestClient bpelClient = bpelRestClientProvider.get(); bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); } - LOGGER.debug("RollbackNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + LOGGER.debug("RollbackNetworkTask exit: code=" + getStatusCode() + APPEND_RESPONSE+ getResponse()); } } @@ -649,7 +649,7 @@ public class NetworkAdapterRest { subnetIdMap.value, req.getMessageId()); } catch (NetworkException e) { - LOGGER.debug ("Exception:", e); + LOGGER.debug (EXCEPTION, e); eresp = new UpdateNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId()); } if (!req.isSynchronous()) { @@ -657,7 +657,7 @@ public class NetworkAdapterRest { BpelRestClient bpelClient = bpelRestClientProvider.get(); bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml); } - LOGGER.debug("UpdateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse()); + LOGGER.debug("UpdateNetworkTask exit: code=" + getStatusCode() + APPEND_RESPONSE+ getResponse()); } } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/async/client/ObjectFactory.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/async/client/ObjectFactory.java index d65cdc4638..f2238fce78 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/async/client/ObjectFactory.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/network/async/client/ObjectFactory.java @@ -4,7 +4,6 @@ * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. * ================================================================================ - * Modifications Copyright 2018 IBM. * 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 diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/CXFConfiguration.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/CXFConfiguration.java index 996e2c2712..72c74ccaf9 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/CXFConfiguration.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/CXFConfiguration.java @@ -47,7 +47,7 @@ import org.onap.so.adapters.vnf.VnfAdapterRestV2; import org.onap.so.adapters.vnf.VolumeAdapterRest; import org.onap.so.adapters.vnf.VolumeAdapterRestV2; import org.onap.so.client.policy.JettisonStyleMapperProvider; -import org.onap.so.logger.MsoLogger; + import org.onap.so.logging.cxf.interceptor.SOAPLoggingInInterceptor; import org.onap.so.logging.cxf.interceptor.SOAPLoggingOutInterceptor; import org.springframework.beans.factory.annotation.Autowired; diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java index 02aa0843ae..a9aa50f654 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/openstack/MsoOpenstackAdaptersApplication.java @@ -22,6 +22,8 @@ package org.onap.so.adapters.openstack; import java.util.concurrent.Executor; +import org.onap.so.logging.jaxrs.filter.MDCTaskDecorator; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -38,6 +40,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @EntityScan({ "org.onap.so.db.catalog.beans", "org.onap.so.db.request.beans"}) public class MsoOpenstackAdaptersApplication { + @Value("${mso.async.core-pool-size}") private int corePoolSize; @@ -63,6 +66,7 @@ public class MsoOpenstackAdaptersApplication { @Bean public Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setTaskDecorator(new MDCTaskDecorator()); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/valet/ValetClient.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/valet/ValetClient.java index 5cce4dd35f..2f688dbf48 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/valet/ValetClient.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/valet/ValetClient.java @@ -50,6 +50,8 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import org.springframework.stereotype.Component; @@ -108,13 +110,11 @@ public class ValetClient { URI uri = builder.build(); ValetCreateRequest vcr = this.createValetCreateRequest(regionId, tenantId, serviceInstanceId, vnfId, vnfName, vfModuleId, vfModuleName, keystoneUrl, heatRequest); - RestTemplate restTemplate = new RestTemplate(); String body = mapper.writeValueAsString(vcr); HttpHeaders headers = generateHeaders(requestId); - HttpEntity<String> entity = new HttpEntity<>(body, headers); - LOGGER.debug("valet create req: " + uri.toString() + HEADERS + headers.toString() + BODY + body); + HttpEntity<String> entity = new HttpEntity<>(body, headers); - response = restTemplate.exchange(uri, HttpMethod.POST, entity, ValetCreateResponse.class); + response = getRestTemplate().exchange(uri, HttpMethod.POST, entity, ValetCreateResponse.class); gvr = this.getGVRFromResponse(response); } catch (Exception e) { LOGGER.error("An exception occurred in callValetCreateRequest", e); @@ -123,6 +123,12 @@ public class ValetClient { return gvr; } + private RestTemplate getRestTemplate(){ + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory())); + return restTemplate; + } + /* * This method will be invoked to send an Update request to Valet. */ @@ -135,14 +141,13 @@ public class ValetClient { UriBuilder builder = UriBuilder.fromPath(baseUrl).path(basePath).queryParam(REQUEST_ID, requestId); URI uri = builder.build(); - ValetUpdateRequest vur = this.createValetUpdateRequest(regionId, tenantId, serviceInstanceId, vnfId, vnfName, vfModuleId, vfModuleName, keystoneUrl, heatRequest); - RestTemplate restTemplate = new RestTemplate(); + ValetUpdateRequest vur = this.createValetUpdateRequest(regionId, tenantId, serviceInstanceId, vnfId, vnfName, vfModuleId, vfModuleName, keystoneUrl, heatRequest); String body = mapper.writeValueAsString(vur); HttpHeaders headers = generateHeaders(requestId); HttpEntity<String> entity = new HttpEntity<>(body, headers); - LOGGER.debug("valet update req: " + uri.toString() + HEADERS + headers.toString() + BODY + body); + - response = restTemplate.exchange(uri, HttpMethod.PUT, entity, ValetUpdateResponse.class); + response = getRestTemplate().exchange(uri, HttpMethod.PUT, entity, ValetUpdateResponse.class); gvr = this.getGVRFromResponse(response); } catch (Exception e) { LOGGER.error("An exception occurred in callValetUpdateRequest", e); @@ -163,13 +168,13 @@ public class ValetClient { URI uri = builder.build(); ValetDeleteRequest vdr = this.createValetDeleteRequest(regionId, tenantId, vfModuleId, vfModuleName); - RestTemplate restTemplate = new RestTemplate(); + String body = mapper.writeValueAsString(vdr); HttpHeaders headers = generateHeaders(requestId); HttpEntity<String> entity = new HttpEntity<>(body, headers); - LOGGER.debug("valet delete req: " + uri.toString() + HEADERS + headers.toString() + ", body=" + body); - response = restTemplate.exchange(uri, HttpMethod.DELETE, entity, ValetDeleteResponse.class); + + response = getRestTemplate().exchange(uri, HttpMethod.DELETE, entity, ValetDeleteResponse.class); gvr = this.getGVRFromResponse(response); } catch (Exception e) { LOGGER.error("An exception occurred in callValetDeleteRequest", e); @@ -190,13 +195,13 @@ public class ValetClient { URI uri = builder.build(requestId); ValetConfirmRequest vcr = this.createValetConfirmRequest(stackId); - RestTemplate restTemplate = new RestTemplate(); + String body = mapper.writeValueAsString(vcr); HttpHeaders headers = generateHeaders(requestId); HttpEntity<String> entity = new HttpEntity<>(body, headers); LOGGER.debug("valet confirm req: " + uri.toString() + HEADERS + headers.toString() + BODY + body); - response = restTemplate.exchange(uri, HttpMethod.PUT, entity, ValetConfirmResponse.class); + response = getRestTemplate().exchange(uri, HttpMethod.PUT, entity, ValetConfirmResponse.class); gvr = this.getGVRFromResponse(response); } catch (Exception e) { LOGGER.error("An exception occurred in callValetConfirmRequest", e); @@ -217,13 +222,13 @@ public class ValetClient { URI uri = builder.build(requestId); ValetRollbackRequest vrr = this.createValetRollbackRequest(stackId, suppressRollback, errorMessage); - RestTemplate restTemplate = new RestTemplate(); + String body = mapper.writeValueAsString(vrr); HttpHeaders headers = generateHeaders(requestId); HttpEntity<String> entity = new HttpEntity<>(body, headers); - LOGGER.debug("valet rollback req: " + uri.toString() + HEADERS + headers.toString() + BODY + body); - response = restTemplate.exchange(uri, HttpMethod.PUT, entity, ValetRollbackResponse.class); + + response = getRestTemplate().exchange(uri, HttpMethod.PUT, entity, ValetRollbackResponse.class); gvr = this.getGVRFromResponse(response); } catch (Exception e) { LOGGER.error("An exception occurred in callValetRollbackRequest", e); 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 b440f7d521..e9567170dd 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 @@ -29,7 +29,7 @@ * - base and volume module queries * - rollback logic * - logging and error handling - * + * * Then based on the orchestration mode of the VNF, it will invoke different VDU plug-ins * to perform the low level instantiations, deletions, and queries. At this time, the * set of available plug-ins is hard-coded, though in the future a dynamic selection @@ -81,6 +81,7 @@ import org.onap.so.openstack.exceptions.MsoExceptionCategory; import org.onap.so.openstack.utils.MsoHeatEnvironmentEntry; import org.onap.so.openstack.utils.MsoHeatUtils; import org.onap.so.openstack.utils.MsoKeystoneUtils; +import org.onap.so.openstack.utils.MsoMulticloudUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; @@ -100,28 +101,31 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger (); private static final String CHECK_REQD_PARAMS = "org.onap.so.adapters.vnf.checkRequiredParameters"; private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); - + @Autowired protected CloudConfig cloudConfig; - + @Autowired private VFModuleCustomizationRepository vfModuleCustomRepo; - + @Autowired private Environment environment; @Autowired protected MsoKeystoneUtils keystoneUtils; - + @Autowired protected MsoCloudifyUtils cloudifyUtils; - + @Autowired protected MsoHeatUtils heatUtils; - + + @Autowired + protected MsoMulticloudUtils multicloudUtils; + @Autowired protected VfModuleCustomizationToVduMapper vduMapper; - + /** * Health Check web method. Does nothing but return to show the adapter is deployed. */ @@ -192,9 +196,9 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { /** * This is the "Query VNF" web service implementation. - * + * * This really should be QueryVfModule, but nobody ever changed it. - * + * * The method returns an indicator that the VNF exists, along with its status and outputs. * The input "vnfName" will also be reflected back as its ID. * @@ -244,7 +248,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error); throw new VnfException (e); } - + if (vduInstance != null && vduInstance.getStatus().getState() != VduStateType.NOTFOUND) { vnfExists.value = Boolean.TRUE; status.value = vduStatusToVnfStatus(vduInstance); @@ -265,7 +269,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { return; } - + /** * This is the "Delete VNF" web service implementation. * This function is now unsupported and will return an error. @@ -278,7 +282,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { MsoRequest msoRequest) throws VnfException { MsoLogger.setLogContext (msoRequest); MsoLogger.setServiceName ("DeleteVnf"); - + // This operation is no longer supported at the VNF level. The adapter is only called to deploy modules. LOGGER.debug ("DeleteVNF command attempted but not supported"); throw new VnfException ("DeleteVNF: Unsupported command", MsoExceptionCategory.USERDATA); @@ -289,7 +293,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { * A rollback object is returned to the client in a successful creation * response. The client can pass that object as-is back to the rollbackVnf * operation to undo the creation. - * + * * TODO: This should be rollbackVfModule and/or rollbackVolumeGroup, * but APIs were apparently never updated. */ @@ -309,7 +313,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Rollback VF Module - nothing to roll back"); return; } - + // Get the elements of the VnfRollback object for easier access String cloudSiteId = rollback.getCloudSiteId (); String tenantId = rollback.getTenantId (); @@ -330,7 +334,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { try { // TODO: Get a reasonable timeout. Use a global property, or store the creation timeout in rollback object and use that. vduInstance = vduPlugin.deleteVdu(cloudInfo, vfModuleId, 5); - + LOGGER.debug("Rolled back VDU instantiation: " + vduInstance.getVduInstanceId()); LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from VDU Plugin", "VDU", "DeleteVdu", null); } @@ -354,7 +358,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { // DeploymentInfo object should be enhanced to report a better status internally. VduStatus vduStatus = vdu.getStatus(); VduStateType status = vduStatus.getState(); - + if (status == null) { return VnfStatus.UNKNOWN; } @@ -379,7 +383,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { { String type = templateParam.getParamType(); LOGGER.debug("Parameter: " + templateParam.getParamName() + " is of type " + type); - + if (type.equalsIgnoreCase("number")) { try { return Integer.valueOf(inputValue); @@ -400,7 +404,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } else if (type.equalsIgnoreCase("boolean")) { return new Boolean(inputValue); } - + // Nothing else matched. Return the original string return inputValue; } @@ -464,9 +468,9 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } } LOGGER.debug(sb.toString()); - return; + return; } - + private void sendMapToDebug(Map<String, String> inputs) { int i = 0; StringBuilder sb = new StringBuilder("inputs:"); @@ -612,7 +616,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { { // Will capture execution time for metrics long startTime = System.currentTimeMillis (); - + MsoLogger.setLogContext (msoRequest); MsoLogger.setServiceName ("CreateVfModule"); @@ -625,14 +629,14 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error); throw new VnfException(error, MsoExceptionCategory.USERDATA); } - + // Clean up some inputs to make comparisons easier if (requestType == null) requestType = ""; - + if ("".equals(volumeGroupId) || "null".equals(volumeGroupId)) - volumeGroupId = null; - + volumeGroupId = null; + if ("".equals(baseVfModuleId) || "null".equals(baseVfModuleId)) baseVfModuleId = null; @@ -643,7 +647,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } else { this.sendMapToDebug(inputs); } - + // Check if this is for a "Volume" module boolean isVolumeRequest = false; if (requestType.startsWith("VOLUME")) { @@ -663,7 +667,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { vfRollback.setBaseGroupHeatStackId(baseVfModuleId); vfRollback.setModelCustomizationUuid(modelCustomizationUuid); vfRollback.setMode("CFY"); - + rollback.value = vfRollback; // Default rollback - no updates performed // Get the VNF/VF Module definition from the Catalog DB first. @@ -675,7 +679,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { try { vfModuleCust = vfModuleCustomRepo.findByModelCustomizationUUID(modelCustomizationUuid); - + if (vfModuleCust == null) { String error = "Create vfModule error: Unable to find vfModuleCust with modelCustomizationUuid=" + modelCustomizationUuid; LOGGER.debug(error); @@ -692,7 +696,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { vnfResource = vfModuleCust.getVfModule().getVnfResources(); } catch (Exception e) { - + LOGGER.debug("unhandled exception in create VF - [Query]" + e.getMessage()); throw new VnfException("Exception during create VF " + e.getMessage()); } @@ -706,10 +710,10 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { CloudSite cloudSite = cloudSiteOp.get(); MavenLikeVersioning aicV = new MavenLikeVersioning(); aicV.setVersion(cloudSite.getCloudVersion()); - + String vnfMin = vnfResource.getAicVersionMin(); String vnfMax = vnfResource.getAicVersionMax(); - + if ( (vnfMin != null && !(aicV.isMoreRecentThan(vnfMin) || aicV.isTheSameVersion(vnfMin))) || (vnfMax != null && aicV.isMoreRecentThan(vnfMax))) { @@ -720,11 +724,11 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { throw new VnfException(error, MsoExceptionCategory.USERDATA); } // End Version check - - + + VduInstance vduInstance = null; CloudInfo cloudInfo = new CloudInfo (cloudSiteId, tenantId, null); - + // Use the VduPlugin. VduPlugin vduPlugin = getVduPlugin(cloudSiteId); @@ -746,12 +750,12 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { me.addContext ("CreateVFModule"); throw new VnfException (me); } - + // More precise handling/messaging if the Module already exists if (vduInstance != null && !(vduInstance.getStatus().getState() == VduStateType.NOTFOUND)) { VduStateType status = vduInstance.getStatus().getState(); LOGGER.debug ("Found Existing VDU, status=" + status); - + if (status == VduStateType.INSTANTIATED) { if (failIfExists != null && failIfExists) { // fail - it exists @@ -799,8 +803,8 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { throw new VnfAlreadyExists (vfModuleName, cloudSiteId, tenantId, vduInstance.getVduInstanceId()); } } - - + + // Collect outputs from Base Modules and Volume Modules Map<String, Object> baseModuleOutputs = null; Map<String, Object> volumeGroupOutputs = null; @@ -824,7 +828,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { me.addContext ("CreateVFModule(QueryVolume)"); throw new VnfException (me); } - + if (volumeVdu == null || volumeVdu.getStatus().getState() == VduStateType.NOTFOUND) { String error = "Create VFModule: Attached Volume Group DOES NOT EXIST " + volumeGroupId + " in " + cloudSiteId + "/" + tenantId + " USER ERROR" ; LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, volumeGroupId, cloudSiteId, tenantId, error, "VDU", "queryVdu(volume)", MsoLogger.ErrorCode.BusinessProcesssError, "Create VFModule: Attached Volume Group DOES NOT EXIST"); @@ -837,7 +841,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { this.sendMapToDebug(volumeGroupOutputs, "volumeGroupOutputs"); } } - + // If this is an Add-On Module, query the Base Module outputs // Note: This will be performed whether or not the current request is for an // Add-On Volume Group or Add-On VF Module @@ -847,7 +851,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { vfRollback.setIsBase(true); } else { LOGGER.debug("This is an Add-On Module request"); - + // Add-On Modules should always have a Base, but just treat as a warning if not provided. // Add-on Volume requests may or may not specify a base. if (!isVolumeRequest && baseVfModuleId == null) { @@ -867,12 +871,12 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, baseVfModuleId, cloudSiteId, tenantId, "VDU", "queryVdu(Base)", MsoLogger.ErrorCode.DataError, "Exception - queryVdu(Base)", me); LOGGER.recordMetricEvent (subStartTime2, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "VDU", "QueryVdu(Base)", baseVfModuleId); LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error); - + // Convert to a generic VnfException me.addContext ("CreateVFModule(QueryBase)"); throw new VnfException (me); } - + if (baseVdu == null || baseVdu.getStatus().getState() == VduStateType.NOTFOUND) { String error = "Create VFModule: Base Module DOES NOT EXIST " + baseVfModuleId + " in " + cloudSiteId + "/" + tenantId + " USER ERROR" ; LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, baseVfModuleId, cloudSiteId, tenantId, error, "VDU", "queryVdu(Base)", MsoLogger.ErrorCode.BusinessProcesssError, "Create VFModule: Base Module DOES NOT EXIST"); @@ -886,14 +890,14 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } } } - + // NOTE: For this section, heatTemplate is used for all template artifacts. // In final implementation (post-POC), the template object would either be generic or there would // be a separate DB Table/Object for different sub-orchestrators. // NOTE: The template is fixed for the VF Module. The environment is part of the customization. - + HeatTemplate heatTemplate = null; HeatEnvironment heatEnvironment = null; if (isVolumeRequest) { @@ -903,7 +907,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { heatTemplate = vfModule.getModuleHeatTemplate(); heatEnvironment = vfModuleCust.getHeatEnvironment(); } - + if (heatTemplate == null) { String error = "UpdateVF: No Heat Template ID defined in catalog database for " + vfModuleType + ", reqType=" + requestType; LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Template ID", vfModuleType, "VNF", "", MsoLogger.ErrorCode.DataError, error); @@ -914,7 +918,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } else { LOGGER.debug ("Got HEAT Template from DB: " + heatTemplate.getHeatTemplate()); } - + if (heatEnvironment == null) { String error = "Update VNF: undefined Heat Environment. VF=" + vfModuleType; LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Environment ID", "OpenStack", "", MsoLogger.ErrorCode.DataError, error); @@ -927,15 +931,15 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { LOGGER.debug ("Got Heat Environment from DB: " + heatEnvironment.getEnvironment()); } - + // Create the combined set of parameters from the incoming request, base-module outputs, // volume-module outputs. Also, convert all variables to their native object types. - + HashMap<String, Object> goldenInputs = new HashMap<String,Object>(); List<String> extraInputs = new ArrayList<String>(); Boolean skipInputChecks = false; - + if (skipInputChecks) { goldenInputs = new HashMap<String,Object>(); for (String key : inputs.keySet()) { @@ -945,10 +949,10 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { else { // Build maps for the parameters (including aliases) to simplify checks HashMap<String, HeatTemplateParam> params = new HashMap<String, HeatTemplateParam>(); - + Set<HeatTemplateParam> paramSet = heatTemplate.getParameters(); LOGGER.debug("paramSet has " + paramSet.size() + " entries"); - + for (HeatTemplateParam htp : paramSet) { params.put(htp.getParamName(), htp); @@ -958,7 +962,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { params.put(alias, htp); } } - + // First, convert all inputs to their "template" type for (String key : inputs.keySet()) { if (params.containsKey(key)) { @@ -973,11 +977,22 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { extraInputs.add(key); } } - + if (!extraInputs.isEmpty()) { + // Add directive inputs + String[] directives = { "oof_directives", "sdnc_directives" }; + for (String key : directives) { + if (extraInputs.contains(key)) { + goldenInputs.put(key, inputs.get(key)); + extraInputs.remove(key); + if (extraInputs.isEmpty()) { + break; + } + } + } LOGGER.debug("Ignoring extra inputs: " + extraInputs); } - + // Next add in Volume Group Outputs if there are any. Copy directly without conversions. if (volumeGroupOutputs != null && !volumeGroupOutputs.isEmpty()) { for (String key : volumeGroupOutputs.keySet()) { @@ -986,7 +1001,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } } } - + // Next add in Base Module Outputs if there are any. Copy directly without conversions. if (baseModuleOutputs != null && !baseModuleOutputs.isEmpty()) { for (String key : baseModuleOutputs.keySet()) { @@ -995,14 +1010,13 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } } } - + // TODO: The model should support a mechanism to pre-assign default parameter values // per "customization" (i.e. usage) of a given module. In HEAT, this is specified by // an Environment file. There is not a general mechanism in the model to handle this. // For the general case, any such parameter/values can be added dynamically to the // inputs (only if not already specified). - - + // Check that required parameters have been supplied from any of the sources String missingParams = null; boolean checkRequiredParameters = true; @@ -1017,7 +1031,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { // No problem - default is true LOGGER.debug ("An exception occured trying to get property " + MsoVnfPluginAdapterImpl.CHECK_REQD_PARAMS, e); } - + // Do the actual parameter checking. // Include looking at the ENV file as a valid definition of a parameter value. // TODO: This handling of ENV applies only to Heat. A general mechanism to @@ -1040,7 +1054,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } } } - + if (missingParams != null) { if (checkRequiredParameters) { // Problem - missing one or more required parameters @@ -1056,12 +1070,12 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } } // NOTE: END PARAMETER CHECKING - - + + // Here we go... ready to deploy the VF Module. long instantiateVduStartTime = System.currentTimeMillis (); if (backout == null) backout = true; - + try { // Construct the VDU Model structure to pass to the targeted VduPlugin VduModelInfo vduModel = null; @@ -1070,10 +1084,10 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { } else { vduModel = vduMapper.mapVfModuleCustVolumeToVdu(vfModuleCust); } - + // Invoke the VduPlugin to instantiate the VF Module vduInstance = vduPlugin.instantiateVdu(cloudInfo, vfModuleName, goldenInputs, vduModel, backout); - + LOGGER.recordMetricEvent (instantiateVduStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from VduPlugin", "VDU", "instantiateVdu", vfModuleName); } catch (VduException me) { @@ -1100,7 +1114,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.UnknownError, error); LOGGER.debug("Unhandled exception at vduPlugin.instantiateVdu", e); throw new VnfException("Exception during instantiateVdu: " + e.getMessage()); - } + } // Reach this point if create is successful. @@ -1108,7 +1122,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { vfRollback.setVnfCreated (true); vfRollback.setVnfId (vduInstance.getVduInstanceId()); vnfId.value = vduInstance.getVduInstanceId(); - outputs.value = copyStringOutputs (vduInstance.getOutputs ()); + outputs.value = copyStringOutputs (vduInstance.getOutputs ()); rollback.value = vfRollback; @@ -1117,7 +1131,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { return; } - + public void deleteVfModule (String cloudSiteId, String tenantId, String vfModuleId, @@ -1126,15 +1140,15 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { { MsoLogger.setLogContext (msoRequest); MsoLogger.setServiceName ("DeleteVfModule"); - + LOGGER.debug ("Deleting VF Module " + vfModuleId + " in " + cloudSiteId + "/" + tenantId); // Will capture execution time for metrics long startTime = System.currentTimeMillis (); - + // Capture the output parameters on a delete, so need to query first VduInstance vduInstance = null; CloudInfo cloudInfo = new CloudInfo(cloudSiteId, tenantId, null); - + // Use the VduPlugin. VduPlugin vduPlugin = getVduPlugin(cloudSiteId); @@ -1152,7 +1166,7 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error); throw new VnfException (e); } - + // call method which handles the conversion from Map<String,Object> to Map<String,String> for our expected Object types outputs.value = convertMapStringObjectToStringString(vduInstance.getOutputs()); @@ -1214,16 +1228,18 @@ public class MsoVnfPluginAdapterImpl implements MsoVnfAdapter { if (cloudSiteOp.isPresent()) { CloudSite cloudSite = cloudSiteOp.get(); String orchestrator = cloudSite.getOrchestrator(); - + if (orchestrator.equalsIgnoreCase("CLOUDIFY")) { - return cloudifyUtils; + return cloudifyUtils; } else if (orchestrator.equalsIgnoreCase("HEAT")) { return heatUtils; } + if (orchestrator.equalsIgnoreCase("MULTICLOUD")) { + LOGGER.debug ("Got MulticloudUtils for vduPlugin"); + return multicloudUtils; } } - - // Default - return HEAT plugin, though will fail later + // Default - return HEAT plugin, though will fail later return heatUtils; } -}
\ No newline at end of file +} 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 4da026f454..88f102c2a5 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 @@ -7,9 +7,9 @@ * 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. @@ -32,16 +32,19 @@ import org.springframework.stereotype.Component; public class VnfAdapterRestUtils { private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA, VnfAdapterRestUtils.class); - + @Autowired private CloudConfig cloudConfig; - + @Autowired private MsoVnfCloudifyAdapterImpl cloudifyImpl; - + @Autowired private MsoVnfAdapterImpl vnfImpl; - + + @Autowired + private MsoVnfPluginAdapterImpl vnfPluginImpl; + /* * Choose which implementation of VNF Adapter to use, based on the orchestration mode. * Currently, the two supported orchestrators are HEAT and CLOUDIFY. @@ -72,7 +75,7 @@ public class VnfAdapterRestUtils LOGGER.debug ("GetVnfAdapterImpl: mode=" + mode); MsoVnfAdapter vnfAdapter = null; - + // TODO: Make this more dynamic (e.g. Service Loader) if ("CLOUDIFY".equalsIgnoreCase(mode)) { LOGGER.debug ("GetVnfAdapterImpl: Return Cloudify Adapter"); @@ -82,12 +85,16 @@ public class VnfAdapterRestUtils LOGGER.debug ("GetVnfAdapterImpl: Return Heat Adapter"); vnfAdapter = vnfImpl; } + else if ("MULTICLOUD".equalsIgnoreCase(mode)) { + LOGGER.debug ("GetVnfAdapterImpl: Return Plugin (multicloud) Adapter"); + vnfAdapter = vnfPluginImpl; + } else { // Don't expect this, but default is the HEAT adapter LOGGER.debug ("GetVnfAdapterImpl: Return Default (Heat) Adapter"); vnfAdapter = vnfImpl; } - + return vnfAdapter; } diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/network/NetworkAdapterRestTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/network/NetworkAdapterRestTest.java index 2a4564bcb2..6123415b41 100644 --- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/network/NetworkAdapterRestTest.java +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/network/NetworkAdapterRestTest.java @@ -142,7 +142,7 @@ public class NetworkAdapterRestTest extends BaseRestTestUtils { ResponseEntity<CreateNetworkResponse> response = restTemplate.exchange( createURLWithPort("/services/rest/v1/networks"), HttpMethod.POST, entity, CreateNetworkResponse.class); - + CreateNetworkResponse expectedResponse = jettisonTypeObjectMapper.getMapper().readValue( new File("src/test/resources/__files/CreateNetworkResponse2.json"), CreateNetworkResponse.class); @@ -150,6 +150,8 @@ public class NetworkAdapterRestTest extends BaseRestTestUtils { assertThat(response.getBody(), sameBeanAs(expectedResponse)); } + + @Test public void testDeleteNetwork() throws IOException{ @@ -267,6 +269,33 @@ public class NetworkAdapterRestTest extends BaseRestTestUtils { assertEquals(Response.Status.OK.getStatusCode(), response.getStatusCode().value()); } + @Test + public void testCreateNetworkCNRC_JSON() throws JSONException, JsonParseException, JsonMappingException, IOException { + + mockOpenStackResponseAccess(wireMockPort); + + mockOpenStackPostPublicUrlWithBodyFile_200(); + + mockOpenStackGetStackCreatedAppC_200(); + + mockOpenStackGetStackAppC_404(); + + headers.add("Content-Type", MediaType.APPLICATION_JSON); + headers.add("Accept", MediaType.APPLICATION_JSON); + + String request = readJsonFileAsString("src/test/resources/CreateNetwork3.json"); + HttpEntity<String> entity = new HttpEntity<String>(request, headers); + + ResponseEntity<CreateNetworkResponse> response = restTemplate.exchange( + createURLWithPort("/services/rest/v1/networks"), HttpMethod.POST, entity, CreateNetworkResponse.class); + + CreateNetworkResponse expectedResponse = jettisonTypeObjectMapper.getMapper().readValue( + new File("src/test/resources/__files/CreateNetworkResponse3.json"), CreateNetworkResponse.class); + + assertEquals(Response.Status.OK.getStatusCode(), response.getStatusCode().value()); + assertThat(response.getBody(), sameBeanAs(expectedResponse)); + } + @Override protected String readJsonFileAsString(String fileLocation) throws JsonParseException, JsonMappingException, IOException{ return new String(Files.readAllBytes(Paths.get(fileLocation))); 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 b21f1f3db2..77ef8d4776 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 @@ -7,9 +7,9 @@ * 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. @@ -20,15 +20,31 @@ 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; @@ -36,11 +52,15 @@ 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 { @@ -52,6 +72,53 @@ 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); @@ -88,18 +155,52 @@ public class MsoVnfPluginAdapterImplTest extends BaseRestTestUtils { new Holder<VnfRollback>()); } - @Test + /* @Test public void createVfModule_INSTANTIATED() throws Exception { mockOpenStackResponseAccess(wireMockPort); mockOpenStackGetStackVfModule_200(); + MsoRequest msoRequest = getMsoRequest(); Map<String, String> map = new HashMap<>(); map.put("key1", "value1"); - msoVnfPluginAdapter.createVfModule("mtn13", "88a6ca3ee0394ade9403f075db23167e", "vnf", "1", vnfName, "VFMOD", - "volumeGroupHeatStackId|1", "baseVfHeatStackId", "9b339a61-69ca-465f-86b8-1c72c582b8e8", map, + 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_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/java/org/onap/so/bpmn/mock/StubOpenStack.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/bpmn/mock/StubOpenStack.java index 98d5f7eb5f..569a845caa 100644 --- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/bpmn/mock/StubOpenStack.java +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/bpmn/mock/StubOpenStack.java @@ -49,6 +49,12 @@ public class StubOpenStack { .withStatus(HttpStatus.SC_OK))); } + public static void mockOpenStackResponseAccessMulticloud(int port) throws IOException { + stubFor(post(urlPathEqualTo("/v2.0/tokens")).willReturn(aResponse().withHeader("Content-Type", "application/json") + .withBody(getBodyFromFile("OpenstackResponse_AccessMulticloud.json", port, "/mockPublicUrl")) + .withStatus(HttpStatus.SC_OK))); + } + public static void mockOpenStackResponseAccessQueryNetwork(int port) throws IOException { stubFor(post(urlPathEqualTo("/v2.0/tokens")) .withRequestBody(containing("tenantId")) diff --git a/adapters/mso-openstack-adapters/src/test/resources/CreateNetwork3.json b/adapters/mso-openstack-adapters/src/test/resources/CreateNetwork3.json new file mode 100644 index 0000000000..accd9e9a54 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/CreateNetwork3.json @@ -0,0 +1,42 @@ +{ + "createNetworkRequest": { + "skipAAI": true, + "messageId": "c4c44af4-4310-4d8b-a1eb-656fc99fe709", + "synchronous": true, + "cloudSiteId": "mtn13", + "tenantId": "ba38bc24a2ef4fb2ad2810c894f1938f", + "networkId": "da886914-efb2-4917-b335-c8381528d90b", + "networkName": "APP-C-24595-T-IST-04AShared_untrusted_vDBE_net_3", + "networkType": "CONTRAIL30_BASIC", + "modelCustomizationUuid": "3bdbb104-ffff-483e-9f8b-c095b3d30844", + "networkTechnology": "NEUTRON", + "subnets": [{ + "subnetName": "APP-C-24595-T-IST-04AShared_untrusted_vDBE_net_3_subnet_1", + "subnetId": "da60501d-9aa8-48d2-99b7-26644fa01093", + "cidr": "20", + "gatewayIp": "", + "ipVersion": "4", + "enableDHCP": false, + "addrFromStart": true, + "hostRoutes": [] + }], + "providerVlanNetwork": { + "physicalNetworkName": "FALSE", + "vlans": [] + }, + "contrailNetwork": { + "shared": "false", + "external": "false", + "routeTargets": [], + "policyFqdns": [], + "routeTableFqdns": [] + }, + "failIfExists": true, + "backout": false, + "msoRequest": { + "requestId": "5349f419-b3e9-4546-b3a1-094bd568d6b7", + "serviceInstanceId": "cf965caf-a003-4189-abf9-e0ed77056dd6" + }, + "contrailRequest": false + } +}
\ No newline at end of file diff --git a/adapters/mso-openstack-adapters/src/test/resources/__files/CreateNetworkResponse3.json b/adapters/mso-openstack-adapters/src/test/resources/__files/CreateNetworkResponse3.json new file mode 100644 index 0000000000..2e5517cebb --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/__files/CreateNetworkResponse3.json @@ -0,0 +1,25 @@ +{ + "createNetworkResponse": { + "networkId": "da886914-efb2-4917-b335-c8381528d90b", + "neutronNetworkId": null, + "networkStackId": "stackname/stackId", + "networkFqdn": null, + "networkCreated": true, + "subnetMap": { + + }, + "rollback": { + "networkStackId": "stackname/stackId", + "tenantId": "ba38bc24a2ef4fb2ad2810c894f1938f", + "cloudId": "mtn13", + "networkType": "CONTRAIL30_BASIC", + "modelCustomizationUuid": "3bdbb104-ffff-483e-9f8b-c095b3d30844", + "networkCreated": true, + "msoRequest": { + "requestId": "5349f419-b3e9-4546-b3a1-094bd568d6b7", + "serviceInstanceId": "cf965caf-a003-4189-abf9-e0ed77056dd6" + } + }, + "messageId": "c4c44af4-4310-4d8b-a1eb-656fc99fe709" + } +}
\ No newline at end of file diff --git a/adapters/mso-openstack-adapters/src/test/resources/__files/OpenstackResponse_AccessMulticloud.json b/adapters/mso-openstack-adapters/src/test/resources/__files/OpenstackResponse_AccessMulticloud.json new file mode 100644 index 0000000000..23fbe840e4 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/resources/__files/OpenstackResponse_AccessMulticloud.json @@ -0,0 +1,40 @@ +{ + "access": { + "token": { + "id": "tokenId1234", + "issued_at": null, + "expires": "1517418429142", + "tenant": null + }, + "serviceCatalog": [ + { + "type": "orchestration", + "name": null, + "endpoints": [ + { + "region": "MTN13", + "publicURL": "port", + "internalURL": null, + "adminURL": null + } + ], + "endpointsLinks": null + }, + { + "type": "network", + "name": null, + "endpoints": [ + { + "region": "MTN13", + "publicURL": "port", + "internalURL": null, + "adminURL": null + } + ], + "endpointsLinks": null + } + ], + "user": null, + "metadata": null + } +} diff --git a/adapters/mso-openstack-adapters/src/test/resources/data.sql b/adapters/mso-openstack-adapters/src/test/resources/data.sql index d16ca4528c..960f483e46 100644 --- a/adapters/mso-openstack-adapters/src/test/resources/data.sql +++ b/adapters/mso-openstack-adapters/src/test/resources/data.sql @@ -71,6 +71,20 @@ insert into network_resource_customization(model_customization_uuid, model_insta ('3bdbb104-476c-483e-9f8b-c095b3d30844', 'CONTRAIL30_BASIC', '', 'CONTRAIL30_BASIC', '', '', '2017-04-19 14:28:32', '10b36f65-f4e6-4be6-ae49-9596dc1c4789'), ('3bdbb104-476c-483e-9f8b-c095b3d3068c', 'CONTRAIL31_BASIC', '', 'CONTRAIL31_BASIC', '', '', '2017-04-19 14:28:32', '10b36f65-f4e6-4be6-ae49-9596dc1c4790'); +insert into instance_group(model_uuid, model_name, model_invariant_uuid, model_version, tosca_node_type, role, object_type, cr_model_uuid, instance_group_type) values +('21e43a7c-d823-4f5b-a427-5235f63035ff', 'dror_cr_network_resource_1806..NetworkCollection..0', '81c94263-c01e-4046-b0c7-51878d658eab', '1', 'org.openecomp.groups.NetworkCollection', 'SUB_INTERFACE', 'L3_NETWORK', '5e3fca45-e2d8-4987-bef1-016d9bda1a8c', 'L3_NETWORK'); + +insert into collection_resource(model_uuid, model_name, model_invariant_uuid, model_version, tosca_node_type, description) values +('5e3fca45-e2d8-4987-bef1-016d9bda1a8c', 'Dror_CR_Network_Resource_1806', 'fe243154-ac18-405f-94c2-ef629d26b8bb', '2.0', 'org.openecomp.resource.cr.DrorCrNetworkResource1806', 'Creation date: 07/25/18'); + +insert into collection_resource_customization(model_customization_uuid, model_instance_name, role, object_type, function, collection_resource_type, cr_model_uuid) values +('c51096a4-6081-41f4-a540-3ed015a8064a', 'Dror_CR_Network_Resource_1806', 'Dror2', 'NetworkCollection', 'Dror1', 'Dror3', '5e3fca45-e2d8-4987-bef1-016d9bda1a8c'); + +insert into collection_network_resource_customization(model_customization_uuid, model_instance_name, network_technology, network_type, network_role, network_scope, network_resource_model_uuid, instance_group_model_uuid, crc_model_customization_uuid) values +('3bdbb104-ffff-483e-9f8b-c095b3d30844', 'ExtVL 0', 'CONTRAIL', 'L3-NETWORK', '', '', '10b36f65-f4e6-4be6-ae49-9596dc1c4789', '21e43a7c-d823-4f5b-a427-5235f63035ff', 'c51096a4-6081-41f4-a540-3ed015a8064a'), +('3bdbb104-ffff-483e-9f8b-c095b3d3068c', 'ExtVL 0', 'CONTRAIL', 'L3-NETWORK', '', '', '10b36f65-f4e6-4be6-ae49-9596dc1c4790', '21e43a7c-d823-4f5b-a427-5235f63035ff', 'c51096a4-6081-41f4-a540-3ed015a8064a'); + + insert into vnf_resource(orchestration_mode, description, creation_timestamp, model_uuid, aic_version_min, aic_version_max, model_invariant_uuid, model_version, model_name, tosca_node_type, heat_template_artifact_uuid) values ('HEAT', '1607 vSAMP10a - inherent network', '2017-04-14 21:46:28', 'ff2ae348-214a-11e7-93ae-92361f002672', '', '', '2fff5b20-214b-11e7-93ae-92361f002671', '2.0', 'vSAMP10a', 'VF', null); diff --git a/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/adapters/HealthCheckHandlerTest.java b/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/adapters/HealthCheckHandlerTest.java index 21ec8f7518..fc12120166 100644 --- a/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/adapters/HealthCheckHandlerTest.java +++ b/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/adapters/HealthCheckHandlerTest.java @@ -68,7 +68,7 @@ public class HealthCheckHandlerTest { assertEquals(Response.Status.OK.getStatusCode(),response.getStatusCode().value()); for(ILoggingEvent logEvent : TestAppender.events) if(logEvent.getLoggerName().equals("org.onap.so.logging.spring.interceptor.LoggingInterceptor") && - logEvent.getMarker().getName().equals("ENTRY") + logEvent.getMarker() != null && logEvent.getMarker().getName().equals("ENTRY") ){ Map<String,String> mdc = logEvent.getMDCPropertyMap(); assertNotNull(mdc.get(ONAPLogConstants.MDCs.INSTANCE_UUID)); @@ -78,7 +78,7 @@ public class HealthCheckHandlerTest { assertEquals("/manage/health",mdc.get(ONAPLogConstants.MDCs.SERVICE_NAME)); assertEquals("INPROGRESS",mdc.get(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE)); }else if(logEvent.getLoggerName().equals("org.onap.so.logging.spring.interceptor.LoggingInterceptor") && - logEvent.getMarker()!= null && logEvent.getMarker().getName().equals("EXIT")){ + logEvent.getMarker() != null && logEvent.getMarker()!= null && logEvent.getMarker().getName().equals("EXIT")){ Map<String,String> mdc = logEvent.getMDCPropertyMap(); assertNotNull(mdc.get(ONAPLogConstants.MDCs.REQUEST_ID)); assertNotNull(mdc.get(ONAPLogConstants.MDCs.INVOCATION_ID)); diff --git a/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/client/RequestsDbClientTest.java b/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/client/RequestsDbClientTest.java index f1269f412b..7c037e4885 100644 --- a/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/client/RequestsDbClientTest.java +++ b/adapters/mso-requests-db-adapter/src/test/java/org/onap/so/adapters/requestsdb/client/RequestsDbClientTest.java @@ -7,9 +7,9 @@ * 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. @@ -26,6 +26,9 @@ import org.junit.runner.RunWith; import org.onap.so.adapters.requestsdb.application.MSORequestDBApplication; import org.onap.so.db.request.beans.InfraActiveRequests; import org.onap.so.db.request.beans.OperationStatus; +import org.onap.so.db.request.beans.OperationalEnvDistributionStatus; +import org.onap.so.db.request.beans.OperationalEnvServiceModelStatus; +import org.onap.so.db.request.beans.RequestProcessingData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; @@ -41,6 +44,8 @@ import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertFalse; @RunWith(SpringRunner.class) @SpringBootTest(classes = MSORequestDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -90,6 +95,7 @@ public class RequestsDbClientTest { assertThat(request, sameBeanAs(response).ignoring("operateAt").ignoring("finishedAt")); } + private void verifyInfraActiveRequests(InfraActiveRequests infraActiveRequestsResponse) { assertThat(infraActiveRequestsResponse, sameBeanAs(infraActiveRequests).ignoring("modifyTime").ignoring("log")); } @@ -189,4 +195,37 @@ public class RequestsDbClientTest { assertNull(requestsDbClient.getOneByServiceIdAndOperationId(UUID.randomUUID().toString(),operationStatus.getOperationId())); } + + + @Test + public void getRequestProcessingDataBySoRequestIdTest(){ + List<RequestProcessingData> requestProcessingDataList = requestsDbClient + .getRequestProcessingDataBySoRequestId("00032ab7-na18-42e5-965d-8ea592502018"); + assertNotNull(requestProcessingDataList); + assertFalse(requestProcessingDataList.isEmpty()); + assertEquals(2,requestProcessingDataList.size()); + } + + @Test + public void findOneByOperationalEnvIdAndServiceModelVersionIdTest(){ + OperationalEnvServiceModelStatus operationalEnvServiceModelStatus =requestsDbClient.findOneByOperationalEnvIdAndServiceModelVersionId("1234","TEST1234"); + assertNotNull(operationalEnvServiceModelStatus); + assertEquals("1234",operationalEnvServiceModelStatus.getOperationalEnvId()); + assertEquals("TEST1234",operationalEnvServiceModelStatus.getServiceModelVersionId()); + } + + @Test + public void getAllByOperationalEnvIdAndRequestId(){ + List<OperationalEnvServiceModelStatus> operationalEnvServiceModelStatuses =requestsDbClient.getAllByOperationalEnvIdAndRequestId("1234","00032ab7-3fb3-42e5-965d-8ea592502017"); + assertNotNull(operationalEnvServiceModelStatuses); + assertFalse(operationalEnvServiceModelStatuses.isEmpty()); + assertEquals(2,operationalEnvServiceModelStatuses.size()); + } + + @Test + public void getDistributionStatusByIdTest(){ + OperationalEnvDistributionStatus operationalEnvDistributionStatus =requestsDbClient.getDistributionStatusById("111"); + assertNotNull(operationalEnvDistributionStatus); + assertEquals("111",operationalEnvDistributionStatus.getDistributionId()); + } } diff --git a/adapters/mso-requests-db-adapter/src/test/resources/db/migration/afterMigrate.sql b/adapters/mso-requests-db-adapter/src/test/resources/db/migration/afterMigrate.sql index ae5f5e9124..fcfd1483da 100644 --- a/adapters/mso-requests-db-adapter/src/test/resources/db/migration/afterMigrate.sql +++ b/adapters/mso-requests-db-adapter/src/test/resources/db/migration/afterMigrate.sql @@ -36,3 +36,14 @@ VALUES (1, '00032ab7-na18-42e5-965d-8ea592502018', '7d2e8c07-4d10-456d-bddc-37abf38ca714', 'requestAction', 'assign', 'pincFabricConfigRequest'), (2, '00032ab7-na18-42e5-965d-8ea592502018', '7d2e8c07-4d10-456d-bddc-37abf38ca715', 'configurationId', '52234bc0-d6a6-41d4-a901-79015e4877e2', 'pincFabricConfigRequest'), (3, '5ffbabd6-b793-4377-a1ab-082670fbc7ac', '5ffbabd6-b793-4377-a1ab-082670fbc7ac', 'configId', '52234bc0-d6a6-41d4-a901-79015e4877e2', 'pincFabricConfig'); + +INSERT INTO activate_operational_env_service_model_distribution_status (OPERATIONAL_ENV_ID, SERVICE_MODEL_VERSION_ID, REQUEST_ID,SERVICE_MOD_VER_FINAL_DISTR_STATUS,RECOVERY_ACTION,RETRY_COUNT_LEFT,WORKLOAD_CONTEXT, CREATE_TIME, MODIFY_TIME) +VALUES +('1234', 'TEST1234', '00032ab7-3fb3-42e5-965d-8ea592502017', "Test", "Test", 1, 'DEFAULT', '2018-08-14 16:50:59', '2018-08-14 16:50:59'); +INSERT INTO activate_operational_env_service_model_distribution_status (OPERATIONAL_ENV_ID, SERVICE_MODEL_VERSION_ID, REQUEST_ID,SERVICE_MOD_VER_FINAL_DISTR_STATUS,RECOVERY_ACTION,RETRY_COUNT_LEFT,WORKLOAD_CONTEXT, CREATE_TIME, MODIFY_TIME) +VALUES +('1234', 'TEST1235', '00032ab7-3fb3-42e5-965d-8ea592502017', "Test", "Test", 2, 'DEFAULT', '2018-08-14 16:50:59', '2018-08-14 16:50:59'); + +INSERT INTO `activate_operational_env_per_distributionid_status` (`DISTRIBUTION_ID`, `DISTRIBUTION_ID_STATUS`, `DISTRIBUTION_ID_ERROR_REASON`, `CREATE_TIME`, `MODIFY_TIME`, `OPERATIONAL_ENV_ID`, `SERVICE_MODEL_VERSION_ID`, `REQUEST_ID`) +VALUES +('111', 'TEST', 'ERROR', '2018-09-12 19:29:24', '2018-09-12 19:29:25', '1234', 'TEST1234', '00032ab7-3fb3-42e5-965d-8ea592502017');
\ No newline at end of file diff --git a/adapters/mso-sdnc-adapter/src/main/java/org/onap/so/adapters/sdnc/SDNCAdapterApplication.java b/adapters/mso-sdnc-adapter/src/main/java/org/onap/so/adapters/sdnc/SDNCAdapterApplication.java index 3d88a1467a..f88aab08a6 100644 --- a/adapters/mso-sdnc-adapter/src/main/java/org/onap/so/adapters/sdnc/SDNCAdapterApplication.java +++ b/adapters/mso-sdnc-adapter/src/main/java/org/onap/so/adapters/sdnc/SDNCAdapterApplication.java @@ -22,6 +22,8 @@ package org.onap.so.adapters.sdnc; import java.util.concurrent.Executor; +import org.onap.so.logging.jaxrs.filter.MDCTaskDecorator; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -35,6 +37,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @EntityScan({ "org.onap.so.db.request.beans"}) public class SDNCAdapterApplication { + @Value("${mso.async.core-pool-size}") private int corePoolSize; @@ -61,7 +64,7 @@ public class SDNCAdapterApplication { @Bean public Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - + executor.setTaskDecorator(new MDCTaskDecorator()); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); |