summaryrefslogtreecommitdiffstats
path: root/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java
diff options
context:
space:
mode:
Diffstat (limited to 'dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java')
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java120
1 files changed, 87 insertions, 33 deletions
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java
index 7a6f9a7..fba8245 100644
--- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java
@@ -1,42 +1,42 @@
package org.onap.sdc.dcae.composition.impl;
+import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.onap.sdc.common.onaplog.Enums.LogLevel;
-import org.onap.sdc.dcae.catalog.asdc.ASDC;
-import org.onap.sdc.dcae.catalog.asdc.ASDCUtils;
-import org.onap.sdc.dcae.catalog.asdc.Blueprinter;
+import org.onap.sdc.dcae.catalog.commons.Recycler;
import org.onap.sdc.dcae.composition.restmodels.MessageResponse;
import org.onap.sdc.dcae.composition.restmodels.VfcmtData;
import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
-import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
import org.onap.sdc.dcae.errormng.ActionStatus;
import org.onap.sdc.dcae.errormng.ErrConfMgr;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+import org.springframework.web.client.RestTemplate;
+import org.yaml.snakeyaml.Yaml;
-import javax.annotation.PostConstruct;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.StringReader;
-import java.net.URI;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
@Component
+@ConfigurationProperties(prefix="blueprinter")
public class BlueprintBusinessLogic extends CompositionBusinessLogic {
- @Autowired
- private Blueprinter blueprinter;
- @Autowired
- private ASDC asdc;
-
-
- @PostConstruct
- public void init() {
- URI sdcUri = URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.URI));
- asdc.setUri(sdcUri);
- debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "SDC uri: {}", sdcUri);
- }
+ private String uri;
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
public ResponseEntity generateAndSaveBlueprint(String userId, String context, String vfcmtUuid, String serviceUuid, String vfiName, String flowType, String requestId) {
try {
@@ -50,7 +50,13 @@ public class BlueprintBusinessLogic extends CompositionBusinessLogic {
debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found the cdump (composition.yml) on top of VFCMT {}", vfcmtUuid);
String cdump = cdumpArtifactData.getPayloadData();
debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to use python procedure to create a blueprint....");
- String resultBlueprintCreation = generateBlueprintViaToscaLab(cdump);
+
+ String input = prepareInput(cdump, requestId);
+ if (null == input) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SUBMIT_BLUEPRINT_ERROR);
+ }
+ String resultBlueprintCreation = new RestTemplate().postForObject(uri, new HttpEntity<>(input), String.class);
+
if (StringUtils.isEmpty(resultBlueprintCreation)) {
errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred during blueprint generation");
return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, "", vfcmt.getName());
@@ -80,17 +86,65 @@ public class BlueprintBusinessLogic extends CompositionBusinessLogic {
}
}
- private String generateBlueprintViaToscaLab(String cdump) {
- debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------CDUMP: -----------------------------------------------------------------------------");
- debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), cdump);
- debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------------------------------------------------------------------------------------------");
- ASDCUtils utils = new ASDCUtils(asdc, blueprinter);
- String resultBlueprintCreation = null;
- try{
- resultBlueprintCreation = utils.buildBlueprintViaToscaLab(new StringReader(cdump)).waitForResult().waitForResult();
- }catch (Exception e){
- errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Generate blueprint via tosca lab error: {}", e);
- }
- return resultBlueprintCreation;
- }
+ private String prepareInput(String cdump, String requestId) throws IOException {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "fetched cdump payload: {}", cdump);
+ Map cdumpToTosca = new Recycler().recycle(new StringReader(cdump));
+ Set<String> dcaeComponentsUuids = extractComponentUuids(cdumpToTosca);
+ List<Map> extractedModels = Collections.synchronizedSet(dcaeComponentsUuids).parallelStream().map(id -> fetchAndExtractModel(id, requestId)).filter(Objects::nonNull).collect(Collectors.toList());
+ // aggregation of parallel stream fetch results - exceptions are swallowed and we check the final size to verify no errors occurred
+ if(dcaeComponentsUuids.size() != extractedModels.size()) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "error: {} distinct DCAE components were mapped to {} tosca lab input models.", dcaeComponentsUuids.size(), extractedModels.size());
+ return null;
+ }
+ return new Gson().toJson(new ToscaLabInput(Base64Utils.encodeToString(new Yaml().dump(cdumpToTosca).getBytes()), extractedModels));
+ }
+
+ private Set<String> extractComponentUuids(Map cdump) {
+ //the node description contains the UUID of the resource declaring it
+ //if the description is the URI the resource uuid is the 5th path element (backward compatibility)
+ // TODO there has to be a better way
+ Map<String, Map<String, Object>> nodes = (Map<String, Map<String, Object>>)((Map<String, Object>)cdump.get("topology_template")).get("node_templates");
+ return nodes.values().stream()
+ .map(n -> (String)n.get("description"))
+ .filter(StringUtils::isNotBlank)
+ .map(d -> StringUtils.substringBetween(d, "resources/", "/"))
+ .collect(Collectors.toSet());
+ }
+
+
+ private class ToscaLabInput {
+ private String template;
+ private List<Map> models;
+
+ ToscaLabInput(String template, List<Map> models){
+ this.template = template;
+ this.models = models;
+ }
+ }
+
+ private Map<String, String> fetchAndExtractModel(String uuid, String requestId) {
+ try {
+ return extractModelFromCsar(sdcRestClient.getResourceToscaModel(uuid, requestId));
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "model extraction error: {}", e);
+ return null;
+ }
+ }
+
+ private Map<String, String> extractModelFromCsar(byte[] csar) throws IOException {
+ //we are only interested in unzipping the 3 files under Artifacts/Deployment/DCAE_TOSCA/
+ String dcaeToscaDir = "Artifacts/Deployment/DCAE_TOSCA/";
+ Map<String, String> extracted = new HashMap<>();
+ try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(csar))) {
+ ZipEntry ze = zis.getNextEntry();
+ while (ze != null && 3 != extracted.size()) {
+ if(ze.getName().startsWith(dcaeToscaDir)) {
+ extracted.put(ze.getName().replace(dcaeToscaDir,"").split("\\.")[0], Base64Utils.encodeToString(extractFile(zis)));
+ }
+ ze = zis.getNextEntry();
+ }
+ return extracted;
+ }
+ }
}