* ================================================================================
* Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
* ================================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ================================================================================
* 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.
package org.onap.so.bpmn.common.resource;
-import java.io.File;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
import java.io.IOException;
+import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
-
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
-
+import org.apache.commons.lang.StringUtils;
import org.camunda.bpm.engine.runtime.Execution;
-import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
-import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException;
-import org.onap.sdc.tosca.parser.impl.SdcToscaParserFactory;
-import org.onap.sdc.toscaparser.api.NodeTemplate;
-import org.onap.sdc.toscaparser.api.Property;
-import org.onap.sdc.toscaparser.api.functions.GetInput;
-import org.onap.sdc.toscaparser.api.parameters.Input;
import org.onap.so.bpmn.core.UrnPropertiesReader;
import org.onap.so.bpmn.core.json.JsonUtils;
import org.onap.so.client.HttpClient;
-import org.onap.so.logger.MessageEnum;
-import org.onap.so.logger.MsoLogger;
+import org.onap.so.client.HttpClientFactory;
import org.onap.so.utils.TargetEntity;
-
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ResourceRequestBuilder {
- private static String CUSTOMIZATION_UUID = "customizationUUID";
+ private static String CUSTOMIZATION_UUID = "cuserviceResourcesstomizationUUID";
- private static String SERVICE_URL_TOSCA_CSAR = "/v3/serviceToscaCsar";
+ private static String SERVICE_URL_SERVICE_INSTANCE = "/v2/serviceResources";
- private static MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA, ResourceRequestBuilder.class);
+ private static Logger logger = LoggerFactory.getLogger(ResourceRequestBuilder.class);
static JsonUtils jsonUtil = new JsonUtils();
- /**
- * build the resource Parameters detail.
- * It's a json string for resource instantiant
- * {
- * "locationConstraints":[...]
- * "requestInputs":{K,V}
- * }
- * <br>
- *
+ public static List<String> getResourceSequence(String serviceUuid) {
+
+ List<String> resourceSequence = new ArrayList();
+ try {
+ Map<String, Object> serviceResponse = getServiceInstnace(serviceUuid);
+
+ if (serviceResponse.containsKey("serviceResources")) {
+ Map<String, Object> serviceResources = (Map<String, Object>) serviceResponse.get("serviceResources");
+
+ if (serviceResources.containsKey("resourceOrder")) {
+ String resourceOrder = (String) serviceResources.get("resourceOrder");
+ if (resourceOrder != null) {
+ resourceSequence.addAll(Arrays.asList(resourceOrder.split(",")));
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("not able to retrieve service order.");
+ }
+ return resourceSequence;
+ }
+
+ /*
+ * build the resource Parameters detail. It's a json string for resource instantiant { "locationConstraints":[...]
+ * "requestInputs":{K,V} } <br>
+ *
* @param execution Execution context
+ *
* @param serviceUuid The service template uuid
+ *
* @param resourceCustomizationUuid The resource customization uuid
+ *
* @param serviceParameters the service parameters passed from the API
+ *
* @return the resource instantiate parameters
+ *
* @since ONAP Beijing Release
*/
@SuppressWarnings("unchecked")
- public static String buildResourceRequestParameters(Execution execution, String serviceUuid, String resourceCustomizationUuid, String serviceParameters) {
- List<String> resourceList = jsonUtil.StringArrayToList(execution, (String)JsonUtils.getJsonValue(serviceParameters, "resources"));
- //Get the right location str for resource. default is an empty array.
- String locationConstraints ="[]";
+ public static String buildResourceRequestParameters(Execution execution, String serviceUuid,
+ String resourceCustomizationUuid, String serviceParameters, Map<String, Object> currentVFData) {
+ List<String> resourceList =
+ jsonUtil.StringArrayToList(execution, (String) JsonUtils.getJsonValue(serviceParameters, "resources"));
+ // Get the right location str for resource. default is an empty array.
+ String locationConstraints = "[]";
String resourceInputsFromUui = "";
- for(String resource: resourceList){
- String resCusUuid = (String)JsonUtils.getJsonValue(resource, "resourceCustomizationUuid");
- if(resourceCustomizationUuid.equals(resCusUuid)){
+ for (String resource : resourceList) {
+ String resCusUuid = (String) JsonUtils.getJsonValue(resource, "resourceCustomizationUuid");
+ if (resourceCustomizationUuid.equals(resCusUuid)) {
String resourceParameters = JsonUtils.getJsonValue(resource, "parameters");
locationConstraints = JsonUtils.getJsonValue(resourceParameters, "locationConstraints");
resourceInputsFromUui = JsonUtils.getJsonValue(resourceParameters, "requestInputs");
}
Map<String, Object> serviceInput = null;
if (JsonUtils.getJsonValue(serviceParameters, "requestInputs") != null) {
- serviceInput = getJsonObject((String)JsonUtils.getJsonValue(serviceParameters, "requestInputs"), Map.class);
+ serviceInput =
+ getJsonObject((String) JsonUtils.getJsonValue(serviceParameters, "requestInputs"), Map.class);
}
Map<String, Object> resourceInputsFromUuiMap = getJsonObject(resourceInputsFromUui, Map.class);
resourceInputsFromUuiMap = new HashMap();
}
- try {
- Map<String, Object> resourceInputsFromServiceDeclaredLevel = buildResouceRequest(serviceUuid, resourceCustomizationUuid, serviceInput);
- resourceInputsFromUuiMap.putAll(resourceInputsFromServiceDeclaredLevel);
- } catch(SdcToscaParserException e) {
- LOGGER.error("SdcToscaParserException", e);
- }
+ Map<String, Object> resourceInputsFromServiceDeclaredLevel =
+ buildResouceRequest(serviceUuid, resourceCustomizationUuid, serviceInput, currentVFData);
+ resourceInputsFromUuiMap.putAll(resourceInputsFromServiceDeclaredLevel);
String resourceInputsStr = getJsonString(resourceInputsFromUuiMap);
- String result = "{\n"
- + "\"locationConstraints\":" + locationConstraints +",\n"
- + "\"requestInputs\":" + resourceInputsStr +"\n"
- +"}";
+ String result = "{\n" + "\"locationConstraints\":" + locationConstraints + ",\n" + "\"requestInputs\":"
+ + resourceInputsStr + "\n" + "}";
return result;
}
- public static Map<String, Object> buildResouceRequest(String serviceUuid, String resourceCustomizationUuid, Map<String, Object> serviceInputs)
- throws SdcToscaParserException {
+ @SuppressWarnings("unchecked")
+ public static Map<String, Object> buildResouceRequest(String serviceUuid, String resourceCustomizationUuid,
+ Map<String, Object> serviceInputs, Map<String, Object> currentVFData) {
+ try {
+ Map<String, Object> serviceInstnace = getServiceInstnace(serviceUuid);
+ // find match of customization uuid in vnf
+ Map<String, Map<String, Object>> serviceResources =
+ (Map<String, Map<String, Object>>) serviceInstnace.get("serviceResources");
+
+ List<Map<String, Object>> serviceVnfCust = (List<Map<String, Object>>) serviceResources.get("serviceVnfs");
+ Map<String, String> resourceInputData = getResourceInputStr(serviceVnfCust, resourceCustomizationUuid);
+
+ // find match in network resource
+ if (resourceInputData.size() == 0) {
+ List<Map<String, Object>> serviceNetworkCust =
+ (List<Map<String, Object>>) serviceResources.get("serviceNetworks");
+ resourceInputData = getResourceInputStr(serviceNetworkCust, resourceCustomizationUuid);
+
+ // find match in AR resource
+ if (resourceInputData == null) {
+ List<Map<String, Object>> serviceArCust =
+ (List<Map<String, Object>>) serviceResources.get("serviceAllottedResources");
+ resourceInputData = getResourceInputStr(serviceArCust, resourceCustomizationUuid);
+ }
+ }
+
+ String resourceInputStr = resourceInputData.get("resourceInput");
+ ResourceLevel resourceLevel = ResourceLevel.valueOf(resourceInputData.get("nodeType"));
- Map<String, Object> resouceRequest = new HashMap<>();
+ if (resourceInputStr != null && !resourceInputStr.isEmpty()) {
+ return getResourceInput(resourceInputStr, serviceInputs, resourceLevel, currentVFData);
+ }
- String csarpath = null;
- try {
- csarpath = getCsarFromUuid(serviceUuid);
- } catch(Exception e) {
- LOGGER.debug("csar file is not available for service uuid:" + serviceUuid, e);
- return resouceRequest;
+ } catch (Exception e) {
+ logger.error("not able to retrieve service instance");
}
+ return new HashMap();
+ }
- SdcToscaParserFactory toscaParser = SdcToscaParserFactory.getInstance();
- ISdcCsarHelper iSdcCsarHelper = toscaParser.getSdcCsarHelper(csarpath, false);
+ private static Map<String, String> getResourceInputStr(List<Map<String, Object>> resources,
+ String resCustomizationUuid) {
- List<Input> serInput = iSdcCsarHelper.getServiceInputs();
- Optional<NodeTemplate> nodeTemplateOpt = iSdcCsarHelper.getServiceNodeTemplates().stream()
- .filter(e -> e.getMetaData().getValue(CUSTOMIZATION_UUID).equals(resourceCustomizationUuid)).findFirst();
+ Map<String, String> resourceInputMap = new HashMap<>(2);
+ for (Map<String, Object> resource : resources) {
+ Map<String, String> modelInfo = (Map<String, String>) resource.get("modelInfo");
- if(nodeTemplateOpt.isPresent()) {
- NodeTemplate nodeTemplate = nodeTemplateOpt.get();
- LinkedHashMap<String, Property> resourceProperties = nodeTemplate.getProperties();
+ if (modelInfo.get("modelCustomizationUuid").equalsIgnoreCase(resCustomizationUuid)) {
+ resourceInputMap.put("resourceInput", (String) resource.get("resourceInput"));
+ String nodeType = ResourceLevel.FIRST.toString();
+ if (((String) resource.get("toscaNodeType")).contains(".vf.")) {
+ nodeType = ResourceLevel.FIRST.toString();
+ } else if (((String) resource.get("toscaNodeType")).contains(".vfc.")) {
+ nodeType = ResourceLevel.SECOND.toString();
+ }
+ resourceInputMap.put("nodeType", nodeType);
+ return resourceInputMap;
+ }
+ }
+ return null;
+ }
- for(String key : resourceProperties.keySet()) {
- Property property = resourceProperties.get(key);
+ // this method combines resource input with service input
+ private static Map<String, Object> getResourceInput(String resourceInputStr, Map<String, Object> serviceInputs,
+ ResourceLevel resourceLevel, Map<String, Object> currentVFData) {
+ Gson gson = new Gson();
+ Type type = new TypeToken<Map<String, String>>() {}.getType();
+ Map<String, Object> resourceInput = gson.fromJson(resourceInputStr, type);
+ JsonParser parser = new JsonParser();
+
+ Map<String, Object> uuiServiceInput = serviceInputs;
+
+ int firstLevelIndex = 0;
+ int secondLevelIndex = 0;
+ String firstLevelKey = null;
+ String secondLevelKey = null;
+ boolean levelKeyNameUpdated = false;
+ int indexToPick = 0;
+
+ if (null != currentVFData) {
+ firstLevelIndex = getIntValue(currentVFData.get("currentFirstLevelIndex"), 0);
+ secondLevelIndex = getIntValue(currentVFData.get("currentSecondLevelIndex"), 0);
+ final String lastFirstLevelKey = firstLevelKey = (String) currentVFData.get("currentFirstLevelKey");
+ final String lastSecondLevelKey = secondLevelKey = (String) currentVFData.get("currentSecondLevelKey");
+
+ if (null != currentVFData.get("lastNodeTypeProcessed")) {
+ ResourceLevel lastResourceLevel =
+ ResourceLevel.valueOf(currentVFData.get("lastNodeTypeProcessed").toString());
+ switch (resourceLevel) {
+ case FIRST:
+ // if it is next request for same group then increment first level index
+ switch (lastResourceLevel) {
+ case FIRST:
+ boolean isSameLevelRequest = resourceInput.values().stream().anyMatch(item -> {
+ JsonElement tree = parser.parse(((String) item).split("\\|")[0]);
+ return tree.isJsonArray() && tree.getAsJsonArray().get(0).getAsString()
+ .equalsIgnoreCase(lastFirstLevelKey);
+ });
+ if (isSameLevelRequest) {
+ firstLevelIndex++;
+ }
+ break;
+ case SECOND:
+ firstLevelIndex = 0;
+ secondLevelKey = null;
+ break;
+
+ }
+ indexToPick = firstLevelIndex;
+ break;
+ case SECOND:
+ // if it is next request for same group then increment second level index
+ switch (lastResourceLevel) {
+ case FIRST:
+ secondLevelIndex = 0;
+ break;
+ case SECOND:
+ boolean isSameLevelRequest = resourceInput.values().stream().anyMatch(item -> {
+ JsonElement tree = parser.parse(((String) item).split("\\|")[0]);
+ return tree.isJsonArray() && tree.getAsJsonArray().get(0).getAsString()
+ .equalsIgnoreCase(lastSecondLevelKey);
+ });
+ if (isSameLevelRequest) {
+ secondLevelIndex++;
+ }
+ break;
+ }
+ // get actual parent object to search for second level objects
+ if (null != lastFirstLevelKey) {
+ Object currentObject = serviceInputs.get(lastFirstLevelKey);
+ if ((null != currentObject) && (currentObject instanceof List)) {
+ List currentFirstLevelList = (List) currentObject;
+ if (currentFirstLevelList.size() > firstLevelIndex) {
+ uuiServiceInput = (Map<String, Object>) currentFirstLevelList.get(firstLevelIndex);
+ }
+
+ }
+ }
+ indexToPick = secondLevelIndex;
+ break;
- Object value = getValue(property.getValue(), serviceInputs, serInput);
- resouceRequest.put(key, value);
+ }
}
+
+
}
- return resouceRequest;
- }
- private static Object getValue(Object value, Map<String, Object> serviceInputs, List<Input> servInputs) {
- if(value instanceof Map) {
- Map<String, Object> valueMap = new HashMap<>();
+ // replace value if key is available in service input
+ for (String key : resourceInput.keySet()) {
+ String value = (String) resourceInput.get(key);
+
+ if (value.contains("|")) {
+
+ // check which level
+
+ // node it type of getinput
+ String[] split = value.split("\\|");
+ String tmpKey = split[0];
+
+ JsonElement jsonTree = parser.parse(tmpKey);
+
+ // check if it is a list type
+ if (jsonTree.isJsonArray()) {
+ JsonArray jsonArray = jsonTree.getAsJsonArray();
+ boolean matchFound = false;
+ if (jsonArray.size() == 3) {
+ String keyName = jsonArray.get(0).getAsString();
+ String keyType = jsonArray.get(2).getAsString();
+ if (!levelKeyNameUpdated) {
+ switch (resourceLevel) {
+ case FIRST:
+ firstLevelKey = keyName;
+ break;
+ case SECOND:
+ secondLevelKey = keyName;
+ break;
+ }
+ levelKeyNameUpdated = true;
+ }
+
+ if (uuiServiceInput.containsKey(keyName)) {
+ Object vfcLevelObject = uuiServiceInput.get(keyName);
+ // it will be always list
+ if (vfcLevelObject instanceof List) {
+ List vfcObject = (List) vfcLevelObject;
+ if (vfcObject.size() > indexToPick) {
+ Map<String, Object> vfMap = (Map<String, Object>) vfcObject.get(indexToPick);
+ if (vfMap.containsKey(keyType)) {
+ if (vfMap.get(keyType) instanceof String) {
+ value = (String) vfMap.get(keyType);
+ } else {
+ value = getJsonString(vfMap.get(keyType));
+ }
+ matchFound = true;
+ }
+ }
+ }
+ }
+ }
- Map<String, Object> propertyMap = (Map<String, Object>)value;
+ if (!matchFound) {
+ if (split.length == 1) { // means value is empty e.g. "a":"key1|"
+ value = "";
+ } else {
+ value = split[1];
+ }
+ }
- for(String key : propertyMap.keySet()) {
- valueMap.put(key, getValue(propertyMap.get(key), serviceInputs, servInputs));
- }
- return valueMap; // return if the value is nested hashmap
- } else if(value instanceof GetInput) {
- String inputName = ((GetInput)value).getInputName();
-
- if(serviceInputs.get(inputName) != null) {
- value = serviceInputs.get(inputName);
- } else {
- for(Input input : servInputs) {
- if(input.getName().equals(inputName)) {
- return input.getDefault(); // return default value
+ } else {
+
+ // if not a list type
+ if (uuiServiceInput.containsKey(tmpKey)) {
+ value = (String) uuiServiceInput.get(tmpKey);
+ } else {
+ if (split.length == 1) { // means value is empty e.g. "a":"key1|"
+ value = "";
+ } else {
+ value = split[1];
+ }
}
}
+
}
+ resourceInput.put(key, value);
+ }
+ // store current processed details into map
+ if (null != currentVFData) {
+ currentVFData.put("currentFirstLevelKey", firstLevelKey);
+ currentVFData.put("currentFirstLevelIndex", firstLevelIndex);
+ currentVFData.put("currentSecondLevelKey", secondLevelKey);
+ currentVFData.put("currentSecondLevelIndex", secondLevelIndex);
+ currentVFData.put("lastNodeTypeProcessed", resourceLevel.toString());
}
- return value; // return property value
+
+ return resourceInput;
}
- private static String getCsarFromUuid(String uuid) throws Exception {
- String catalogEndPoint = UrnPropertiesReader.getVariable("mso.catalog.db.endpoint");
- HttpClient client = new HttpClient(UriBuilder.fromUri(catalogEndPoint).path(SERVICE_URL_TOSCA_CSAR).queryParam("serviceModelUuid", uuid).build().toURL(), "application/json", TargetEntity.CATALOG_DB);
-
- Response response = client.get();
- String value = response.readEntity(String.class);
+ private static int getIntValue(Object inputObj, int defaultValue) {
+ if (null != inputObj) {
+ if (inputObj instanceof Integer) {
+ return ((Integer) inputObj).intValue();
+ }
+ if (StringUtils.isNotEmpty(inputObj.toString())) {
+ try {
+ int val = Integer.parseInt(inputObj.toString());
+ return val;
+ } catch (NumberFormatException e) {
+ logger.warn("Unable to parse to int", e.getMessage());
+ }
+ }
+ }
+ return defaultValue;
+ }
- HashMap<String, String> map = new Gson().fromJson(value, new TypeToken<HashMap<String, String>>() {}.getType());
+ public static Map<String, Object> getServiceInstnace(String uuid) throws Exception {
+ String catalogEndPoint = UrnPropertiesReader.getVariable("mso.catalog.db.endpoint");
- String filePath = System.getProperty("mso.config.path") + "ASDC/" + map.get("version") + "/" + map.get("name");
+ HttpClient client = new HttpClientFactory().newJsonClient(UriBuilder.fromUri(catalogEndPoint)
+ .path(SERVICE_URL_SERVICE_INSTANCE).queryParam("serviceModelUuid", uuid).build().toURL(),
+ TargetEntity.CATALOG_DB);
- File csarFile = new File(filePath);
+ client.addAdditionalHeader("Accept", "application/json");
+ client.addAdditionalHeader("Authorization", UrnPropertiesReader.getVariable("mso.db.auth"));
- if(!csarFile.exists()) {
- throw new Exception("csar file does not exist.");
- }
+ Response apiResponse = client.get();
- return csarFile.getAbsolutePath();
+ String value = apiResponse.readEntity(String.class);
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ HashMap<String, Object> map = objectMapper.readValue(value, HashMap.class);
+ return map;
}
-
+
public static <T> T getJsonObject(String jsonstr, Class<T> type) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
try {
return mapper.readValue(jsonstr, type);
- } catch(IOException e) {
- LOGGER.error(MessageEnum.RA_NS_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "fail to unMarshal json", e);
+ } catch (IOException e) {
+ logger.error("fail to unMarshal json {}", e.getMessage());
}
return null;
}
- public static String getJsonString(Object srcObj) {
+ public static String getJsonString(Object srcObj) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
String jsonStr = null;
try {
jsonStr = mapper.writeValueAsString(srcObj);
- } catch(JsonProcessingException e) {
- LOGGER.error("SdcToscaParserException", e);
+ } catch (JsonProcessingException e) {
+ logger.error("SdcToscaParserException", e);
}
return jsonStr;
}