diff options
Diffstat (limited to 'dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl')
5 files changed, 392 insertions, 278 deletions
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java index 6779257..6b0ec93 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java @@ -25,7 +25,13 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.util.Base64Utils; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; @Component public class BaseBusinessLogic { @@ -130,7 +136,7 @@ public class BaseBusinessLogic { } - public void checkUserIfResourceCheckedOut(String userId, Asset asset) { + void checkUserIfResourceCheckedOut(String userId, Asset asset) { if (DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(asset.getLifecycleState())) { String lastUpdaterUserId = asset.getLastUpdaterUserId(); if (lastUpdaterUserId != null && !lastUpdaterUserId.equals(userId)) { @@ -141,11 +147,11 @@ public class BaseBusinessLogic { } } - public boolean isNeedToCheckOut(String lifecycleState) { + boolean isNeedToCheckOut(String lifecycleState) { return DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(lifecycleState); } - public void checkVfcmtType(ResourceDetailed vfcmt) { + void checkVfcmtType(ResourceDetailed vfcmt) { if (AssetType.VFCMT != getValidAssetTypeOrNull(vfcmt.getResourceType()) || !"Template".equals(vfcmt.getCategory())) { ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.RESOURCE_NOT_VFCMT_ERROR, null, vfcmt.getUuid()); throw new DcaeException(HttpStatus.BAD_REQUEST, responseFormat.getRequestError()); @@ -161,4 +167,15 @@ public class BaseBusinessLogic { } } + + byte[] extractFile(ZipInputStream zis) throws IOException { + byte[] buffer = new byte[1024]; + try (ByteArrayOutputStream os = new ByteArrayOutputStream()){ + int len; + while ((len = zis.read(buffer)) > 0) { + os.write(buffer, 0, len); + } + return os.toByteArray(); + } + } } 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; + } + } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/CompositionCatalogBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/CompositionCatalogBusinessLogic.java index ff596b5..d970778 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/CompositionCatalogBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/CompositionCatalogBusinessLogic.java @@ -1,205 +1,119 @@ package org.onap.sdc.dcae.composition.impl; -import org.json.JSONArray; -import org.json.JSONException; import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.common.onaplog.OnapLoggerError; import org.onap.sdc.dcae.catalog.Catalog; -import org.onap.sdc.dcae.catalog.engine.*; +import org.onap.sdc.dcae.catalog.commons.Future; +import org.onap.sdc.dcae.catalog.engine.CatalogController; +import org.onap.sdc.dcae.catalog.engine.CatalogResponse; +import org.onap.sdc.dcae.catalog.engine.ElementRequest; +import org.onap.sdc.dcae.composition.restmodels.canvas.DcaeComponentCatalog; +import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; +import org.onap.sdc.dcae.composition.restmodels.sdc.Resource; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; +import org.onap.sdc.dcae.enums.AssetType; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.utils.SdcRestClientUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; -import org.springframework.web.context.request.async.DeferredResult; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; @Component -public class CompositionCatalogBusinessLogic { +public class CompositionCatalogBusinessLogic extends BaseBusinessLogic { @Autowired private CatalogController catalogController; protected OnapLoggerError errLogger = OnapLoggerError.getInstance(); - public DeferredResult<CatalogResponse> getItems(ItemsRequest theRequest) { - - final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout()); + public ResponseEntity getModelById(String requestId, String theItemId) { - catalog.rootsByLabel(request.getStartingLabel()).setHandler(catalogController.new CatalogHandler<Catalog.Folders>(request, result) { - public CatalogResponse handleData(Catalog.Folders theFolders) { - JSONArray ja = new JSONArray(); - if (theFolders != null) { - for (Catalog.Folder folder : theFolders) { - ja.put(catalogController.patchData(catalog, folder.data())); - } - } - CatalogResponse response = new CatalogResponse(this.request); - try { - response.data().put("elements", ja); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting json elements to response {}", e); - } - return response; + try { + ResourceDetailed resourceDetailed = fetchAndExtractTemplateAndSchema(theItemId, requestId); + Future<Catalog.Template> modelFuture = catalogController.getCatalog().template(resourceDetailed).withInputs().withOutputs().withNodes().withNodeProperties().withNodePropertiesAssignments().withNodeRequirements().withNodeCapabilities().withNodeCapabilityProperties() + .withNodeCapabilityPropertyAssignments().withPolicies().withPolicyProperties().withPolicyPropertiesAssignments().execute(); + if(modelFuture.succeeded()) { + CatalogResponse response = new CatalogResponse(ElementRequest.EMPTY_REQUEST); + response.data().put("model", modelFuture.result().data()); + return ResponseEntity.ok().body(response); } - }); - return result; - } + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERAL_ERROR, modelFuture.cause().getMessage()); - public DeferredResult<CatalogResponse> getItemById(ItemsRequest theRequest, String theItemId) { - - final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout()); - - catalog.folder(theItemId).withParts().withPartAnnotations().withItems().withItemAnnotations().withItemModels().execute().setHandler(new FolderHandler(catalog, request, result)); - return result; + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error fetching catalog model with id {}. Message: {}", theItemId, e); + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_MODEL, theItemId); + } } - public DeferredResult getModelById(ElementRequest theRequest, String theItemId) { - final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout()); -// try { - catalog.item(theItemId).withModels().execute().setHandler(new ItemHandler(catalog, request, result)); -// } catch (IllegalArgumentException e) { -// errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error fetching catalog model with id {}. Message: {}", theItemId, e); -// result.setErrorResult(new CatalogError(request, "Catalog API failed", e)); -// } - return result; - } + public ResponseEntity getTypeInfo(String theItemId, String theTypeName) { - public DeferredResult<CatalogResponse> getTypeInfo(ElementRequest theRequest, String theItemId, String theTypeName) { - final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout()); - - catalog.type(theItemId, theTypeName).withHierarchy().withCapabilities().withRequirements().execute().setHandler(catalogController.new CatalogHandler<Catalog.Type>(request, result) { - public CatalogResponse handleData(Catalog.Type theType) { - CatalogResponse response = new CatalogResponse(this.request); - if (theType != null) { - try { - response.data().put("type", catalogController.patchData(catalog, theType.data())); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", e); - } - } - return response; + try { + Future<Catalog.Type> theTypeInfoFuture = catalogController.getCatalog().type(theItemId, theTypeName).withHierarchy().withCapabilities().withRequirements().execute(); + if(theTypeInfoFuture.succeeded()) { + CatalogResponse response = new CatalogResponse(ElementRequest.EMPTY_REQUEST); + response.data().put("type", theTypeInfoFuture.result().data()); + return ResponseEntity.ok().body(response); } - }); - return result; - } - - /// Nested Catalog Data Handlers /// - - private class FolderHandler extends CatalogController.CatalogHandler<Catalog.Folder> { - - private Catalog catalog; + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERAL_ERROR, theTypeInfoFuture.cause().getMessage()); - private FolderHandler(Catalog catalog, ItemsRequest request, DeferredResult result) { - catalogController.super(request, result); - this.catalog = catalog; - } - - private void patchCatalogData(Catalog.Elements folders, Catalog catalog) { - if (folders != null) { - folders.forEach(folder -> { - catalogController.patchData(catalog, ((Catalog.Element) folder).data()); - // lots of ephemere proxies created here .. - Catalog.Elements annotations = ((Catalog.Element) folder).elements("annotations", Catalog.Annotations.class); - if (annotations != null) { - annotations.forEach(a -> catalogController.patchData(catalog, ((Catalog.Annotation) a).data())); - } - }); - } - } - - public CatalogResponse handleData(Catalog.Folder theFolder) { - CatalogResponse response = new CatalogResponse(this.request); - if (theFolder == null) { - return response; - } - try { - Catalog.Elements folders = theFolder.elements("parts", Catalog.Folders.class); - patchCatalogData(folders, catalog); - Catalog.Elements items = theFolder.elements("items", Catalog.Items.class); - patchCatalogData(items, catalog); - } catch (Exception x) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", x); - return new CatalogError(this.request, "", x); - } - try { - response.data().put("element", theFolder.data()); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting element to response {}", e); - } - return response; + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", e); + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_MODEL, theItemId); } } - private class ItemHandler extends CatalogController.CatalogHandler<Catalog.Item> { - - private Catalog catalog; - - private ItemHandler(Catalog catalog, ElementRequest request, DeferredResult result) { - catalogController.super(request, result); - this.catalog = catalog; - } - - public CatalogResponse handleData(Catalog.Item theItem) { - if (theItem == null) { - return new CatalogError(this.request, "No such item"); - } - Catalog.Templates models; - try { - models = (Catalog.Templates) theItem.elements("models", Catalog.Templates.class); - } catch (Exception x) { - return new CatalogError(this.request, "Failed to decode templates from result", x); - } - if (models == null || models.isEmpty()) { - return new CatalogError(this.request, "Item has no models"); - } - if (models.size() > 1) { - return new CatalogError(this.request, "Item has more than one model !?"); - } - try { - catalog.template(models.get(0).id()).withInputs().withOutputs().withNodes().withNodeProperties().withNodePropertiesAssignments().withNodeRequirements().withNodeCapabilities().withNodeCapabilityProperties() - .withNodeCapabilityPropertyAssignments().withPolicies().withPolicyProperties().withPolicyPropertiesAssignments().execute().setHandler(new TemplateHandler(this.catalog, this.request, this.result)); - } catch (Exception e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception caught during Catalog Item Handler: {}", e); - } - return null; - } + public DcaeComponentCatalog getCatalog(String requestId) { + List<DcaeComponentCatalog.SubCategoryFolder> folders = sdcRestClient.getResources(AssetType.VF.name(), "DCAE Component", null, requestId).stream() + .filter(r -> DcaeBeConstants.LifecycleStateEnum.CERTIFIED == DcaeBeConstants.LifecycleStateEnum.findState(r.getLifecycleState())) + .collect(Collectors.groupingBy(Resource::getSubCategory)).entrySet().stream() + .map(e -> new DcaeComponentCatalog.SubCategoryFolder(e.getKey(), e.getValue())).collect(Collectors.toList()); + DcaeComponentCatalog catalog = new DcaeComponentCatalog(); + catalog.setElements(folders); + return catalog; } - private class TemplateHandler extends CatalogController.CatalogHandler<Catalog.Template> { - - private Catalog catalog; - private TemplateHandler(Catalog catalog, CatalogRequest request, DeferredResult result) { - catalogController.super(request, result); - this.catalog = catalog; + private ResourceDetailed fetchAndExtractTemplateAndSchema(String uuid, String requestId) throws IOException { + String toscaModelPath = "/sdc/v1/catalog/resources/".concat(uuid).concat("/toscaModel/"); + if(!catalogController.getCatalog().hasCachedItem(uuid)){ + ResourceDetailed resourceDetailed = new ResourceDetailed(); + resourceDetailed.setUuid(uuid); + resourceDetailed.setToscaModelURL(toscaModelPath); + resourceDetailed.setArtifacts(extractToscaArtifactsFromCsar(sdcRestClient.getResourceToscaModel(uuid, requestId), toscaModelPath)); + return resourceDetailed; } + ResourceDetailed cachedVf = sdcRestClient.getResource(uuid, requestId); + cachedVf.getArtifacts().forEach(a -> a.setArtifactURL(toscaModelPath.concat(a.getArtifactName()))); + return cachedVf; + } - public CatalogResponse handleData(Catalog.Template theTemplate) { - CatalogResponse response = new CatalogResponse(this.request); - if (theTemplate != null) { - try { - response.data().put("model", catalogController.patchData(catalog, theTemplate.data())); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting model to response {}", e); + private List<Artifact> extractToscaArtifactsFromCsar(byte[] csar, String toscaModelPath) throws IOException { + //we are only interested in unzipping files under Artifacts/Deployment/DCAE_TOSCA/ + String dcaeToscaDir = "Artifacts/Deployment/DCAE_TOSCA/"; + List<Artifact> extracted = new ArrayList<>(); + try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(csar))) { + ZipEntry ze = zis.getNextEntry(); + while (ze != null) { + if(ze.getName().startsWith(dcaeToscaDir)) { + String artifactName = ze.getName().replace(dcaeToscaDir,""); + extracted.add(SdcRestClientUtils.generateCatalogDcaeToscaArtifact(artifactName, toscaModelPath.concat(artifactName), extractFile(zis))); } + ze = zis.getNextEntry(); } - return response; + return extracted; } } -} - - - - +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java index 9c950b6..224fc24 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java @@ -2,9 +2,13 @@ package org.onap.sdc.dcae.composition.impl; import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent; +import org.onap.sdc.dcae.composition.restmodels.ReferenceUUID; +import org.onap.sdc.dcae.composition.restmodels.VfcmtData; import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceInstance; import org.onap.sdc.dcae.composition.restmodels.sdc.ServiceDetailed; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; import org.onap.sdc.dcae.errormng.ActionStatus; import org.onap.sdc.dcae.errormng.ErrConfMgr; import org.onap.sdc.dcae.utils.Normalizers; @@ -74,4 +78,26 @@ public class ReferenceBusinessLogic extends BaseBusinessLogic { return result; } + + // defect fix/workaround - rule editor may perform lazy checkout on a certified MC without binding it to the service. This is a preemptive measure + public ResponseEntity checkoutAndBindToServiceIfCertified(String userId, String contextType, String serviceUuid, String vfiName, String vfcmtUuid, String requestId) { + try { + ResourceDetailed vfcmt = sdcRestClient.getResource(vfcmtUuid, requestId); + DcaeBeConstants.LifecycleStateEnum initialState = DcaeBeConstants.LifecycleStateEnum.findState(vfcmt.getLifecycleState()); + if(DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != initialState) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "about to checkout vfcmt {} {} version {}", vfcmtUuid, vfcmt.getLifecycleState(), vfcmt.getVersion()); + vfcmt = checkoutVfcmt(userId, vfcmtUuid, requestId); + } + //this is the only case in which the uuid will change. This UI call is followed by a save/import/delete rule request. + if(DcaeBeConstants.LifecycleStateEnum.CERTIFIED == initialState) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "about to create reference for new vfcmt {} version {}", vfcmt.getUuid(), vfcmt.getVersion()); + sdcRestClient.addExternalMonitoringReference(userId, contextType, serviceUuid, vfiName, new ReferenceUUID(vfcmt.getUuid()), requestId); + } + return new ResponseEntity<>(new VfcmtData(vfcmt), HttpStatus.OK); + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(),"Failed to during getLatestMcUuid request for vfcmt {}. message: {}", vfcmtUuid, e); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED, e.getMessage()); + } + } + } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogic.java index 298ffac..94133e4 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogic.java @@ -3,10 +3,8 @@ package org.onap.sdc.dcae.composition.impl; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.gson.JsonParseException; import org.apache.commons.collections.ListUtils; -import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.onap.sdc.common.onaplog.Enums.LogLevel; -import org.onap.sdc.dcae.composition.CompositionConfig; import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; @@ -17,6 +15,7 @@ import org.onap.sdc.dcae.errormng.ErrConfMgr; import org.onap.sdc.dcae.errormng.ServiceException; import org.onap.sdc.dcae.rule.editor.impl.RulesBusinessLogic; import org.onap.sdc.dcae.rule.editor.utils.RulesPayloadUtils; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; import org.onap.sdc.dcae.utils.Normalizers; import org.onap.sdc.dcae.utils.SdcRestClientUtils; import org.onap.sdc.dcae.ves.VesDataItemsDefinition; @@ -24,7 +23,9 @@ import org.onap.sdc.dcae.ves.VesDataTypeDefinition; import org.onap.sdc.dcae.ves.VesSimpleTypesEnum; import org.onap.sdc.dcae.ves.VesStructureLoader; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.Base64Utils; @@ -39,8 +40,6 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { @Autowired private RulesBusinessLogic rulesBusinessLogic; - @Autowired - private CompositionConfig compositionConfig; private static final String EXCEPTION = "Exception {}"; @@ -49,7 +48,7 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { try { Rule rule = RulesPayloadUtils.parsePayloadToRule(json); if (null == rule) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT, "", ""); } List<ServiceException> errors = rulesBusinessLogic.validateRule(rule); @@ -71,19 +70,18 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))) .findAny().orElse(null); - // exception thrown if vfcmt is checked out and current user is not its owner - // performs checkoutVfcmt if required - String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId); // new mappingRules artifact, validate nid exists in composition before creating new artifact if (null == artifactFound) { if (cdumpContainsNid(vfcmt, nid, requestId)) { - return saveNewRulesArtifact(rule, vfcmtId, generateMappingRulesFileName(dcaeCompLabel, nid, configParam), artifactLabel, userId, requestId); + MappingRules body = new MappingRules(rule); + saveNewRulesArtifact(body, vfcmtUuid, generateMappingRulesFileName(dcaeCompLabel, nid, configParam), artifactLabel, userId, requestId); + return checkInAndReturnSaveArtifactResult(rule.toJson(), vfcmtUuid, userId, requestId); } return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.NODE_NOT_FOUND, "", dcaeCompLabel); } //update artifact flow - append new rule or edit existing rule - return addOrEditRuleInArtifact(rule, vfcmtId, userId, artifactFound, requestId); + return addOrEditRuleInArtifact(rule, vfcmtUuid, userId, artifactFound, requestId); } catch (JsonParseException je) { errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error: Rule format is invalid: {}", je); @@ -91,35 +89,59 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { } catch (Exception e) { return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); } - } - public ResponseEntity getRules(String vfcmtUuid, String dcaeCompLabel, String nid, String configParam, String requestId) { + public ResponseEntity getRulesAndSchema(String vfcmtUuid, String dcaeCompLabel, String nid, String configParam, String requestId) { try { - ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); - if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { - return new ResponseEntity<>("{}", HttpStatus.OK); - } - String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); - - // check for MappingRules artifact in existing artifacts - Artifact artifactListed = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null); - if (null == artifactListed) { - return new ResponseEntity<>("{}", HttpStatus.OK); - } - String ruleFile = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactListed.getArtifactUUID(), requestId); - + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + Artifact rulesArtifact = fetchRulesArtifact(vfcmt, dcaeCompLabel, nid, configParam, requestId); + if(null == rulesArtifact) { + return new ResponseEntity<>("{}", HttpStatus.OK); + } // To avoid opening the file for reading we search for the eventType and SchemaVer from the artifact metadata's description - SchemaInfo schemainfo = RulesPayloadUtils.extractInfoFromDescription(artifactListed); + SchemaInfo schemainfo = RulesPayloadUtils.extractInfoFromDescription(rulesArtifact); List<EventTypeDefinitionUI> schema = null == schemainfo ? new ArrayList<>() : getEventTypeDefinitionUIs(schemainfo.getVersion(), schemainfo.getEventType()); - return new ResponseEntity<>(RulesPayloadUtils.buildSchemaAndRulesResponse(ruleFile, schema), HttpStatus.OK); + return new ResponseEntity<>(RulesPayloadUtils.buildSchemaAndRulesResponse(rulesArtifact.getPayloadData(), schema), HttpStatus.OK); } catch (Exception e) { return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_RULE_ARTIFACT); } - } + //1810 US423581 export rules + public ResponseEntity downloadRules(String vfcmtUuid, String dcaeCompLabel, String nid, String configParam, String requestId) { + + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + Artifact rulesArtifact = fetchRulesArtifact(vfcmt, dcaeCompLabel, nid, configParam, requestId); + if(null == rulesArtifact) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"requested rules artifact not found"); + return new ResponseEntity(HttpStatus.NOT_FOUND); + } + return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM) + .header(HttpHeaders.CONTENT_DISPOSITION, generateMappingRulesFileNameHeader(vfcmt.getName(), dcaeCompLabel, configParam)) + .body(rulesArtifact.getPayloadData()); + } catch (Exception e) { + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_RULE_ARTIFACT); + } + } + + private Artifact fetchRulesArtifact(ResourceDetailed vfcmt, String dcaeCompLabel, String nid, String configParam, String requestId) { + + if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { + return null; + } + String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + + // check for MappingRules artifact in existing artifacts + Artifact artifactListed = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null); + if (null == artifactListed) { + return null; + } + artifactListed.setPayloadData(getSdcRestClient().getResourceArtifact(vfcmt.getUuid(), artifactListed.getArtifactUUID(), requestId)); + return artifactListed; + } + public ResponseEntity deleteRule(String userId, String vfcmtUuid, String dcaeCompLabel, String nid, String configParam, String ruleUid, String requestId) { try { @@ -140,8 +162,7 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); } - String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId); - String payload = getSdcRestClient().getResourceArtifact(vfcmtId, mappingRuleFile.getArtifactUUID(), requestId); + String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, mappingRuleFile.getArtifactUUID(), requestId); MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); Rule removedRule = rulesBusinessLogic.deleteRule(rules, ruleUid); if (null == removedRule) { @@ -149,55 +170,89 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); } if (rules.isEmpty()) { // if file doesn't contain any rules after last deletion -> let's delete the file - getSdcRestClient().deleteResourceArtifact(userId, vfcmtId, mappingRuleFile.getArtifactUUID(), requestId); + getSdcRestClient().deleteResourceArtifact(userId, vfcmtUuid, mappingRuleFile.getArtifactUUID(), requestId); } else { - updateRulesArtifact(vfcmtId, userId, mappingRuleFile, rules, requestId); + updateRulesArtifact(vfcmtUuid, userId, mappingRuleFile, rules, requestId); } - return checkInAndReturnSaveArtifactResult(removedRule, vfcmtId, userId, requestId); + return checkInAndReturnSaveArtifactResult(removedRule.toJson(), vfcmtUuid, userId, requestId); } catch (Exception e) { return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); } - } - public ResponseEntity translateRules(String vfcmtUuid, String requestId, String dcaeCompLabel, String nid, String configParam, String flowType) { + public ResponseEntity deleteGroupOfRules(String userId, String vfcmtUuid, String dcaeCompLabel, String nid, String configParam, String groupId, String requestId) { + + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + if (null == vfcmt.getArtifacts()) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "VFCMT {} doesn't have artifacts", vfcmtUuid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); + } + String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + + // check for MappingRules artifact in existing artifacts + Artifact mappingRuleFile = vfcmt.getArtifacts().stream() + .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))) + .findAny().orElse(null); + + if (null == mappingRuleFile) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't exist for VFCMT {}", artifactLabel, vfcmtUuid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); + } + + String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, mappingRuleFile.getArtifactUUID(), requestId); + MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); + List<Rule> removedRules = rulesBusinessLogic.deleteGroupOfRules(rules, groupId); + if (removedRules.isEmpty()) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Group {} not found.", groupId); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); + } + if (rules.isEmpty()) { // if file doesn't contain any rules after last deletion -> let's delete the file + getSdcRestClient().deleteResourceArtifact(userId, vfcmtUuid, mappingRuleFile.getArtifactUUID(), requestId); + } else { + updateRulesArtifact(vfcmtUuid, userId, mappingRuleFile, rules, requestId); + } + return checkInAndReturnSaveArtifactResult(removedRules, vfcmtUuid, userId, requestId); + } catch (Exception e) { + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); + } + + } + + public ResponseEntity translateRules(TranslateRequest request, String requestId) { try { - - if (StringUtils.isBlank(flowType) || MapUtils.isEmpty(compositionConfig.getFlowTypesMap()) || null == compositionConfig.getFlowTypesMap().get(flowType)) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "Flow type " + flowType + " not found"); + if(!rulesBusinessLogic.validateTranslateRequestFields(request)) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Invalid translate request. request: {}", request); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "please enter valid request parameters"); } - - // extract entry phase name and last phase name from configuration: - String entryPointPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getEntryPointPhaseName(); - String lastPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getLastPhaseName(); - - ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + ResourceDetailed vfcmt = getSdcRestClient().getResource(request.getVfcmtUuid(), requestId); checkVfcmtType(vfcmt); if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "No rules found on VFCMT " + vfcmtUuid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "No rules found on VFCMT " + request.getVfcmtUuid()); } - String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + String artifactLabel = Normalizers.normalizeArtifactLabel(request.getDcaeCompLabel() + request.getNid() + request.getConfigParam()); // check for MappingRules artifact in existing artifacts Artifact rulesArtifact = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null); if (rulesArtifact == null) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", artifactLabel + " doesn't exist on VFCMT " + vfcmtUuid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", artifactLabel + " doesn't exist on VFCMT " + request.getVfcmtUuid()); } - String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId); + String payload = getSdcRestClient().getResourceArtifact(request.getVfcmtUuid(), rulesArtifact.getArtifactUUID(), requestId); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Retrieved mapping rules artifact {}, start parsing rules...", artifactLabel); MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); + rulesBusinessLogic.updateGlobalTranslationFields(rules, request, vfcmt.getName()); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished parsing rules, calling validator..."); - List<ServiceException> errors = rulesBusinessLogic.validateRules(rules); + List<ServiceException> errors = rulesBusinessLogic.validateRulesBeforeTranslate(rules); if (!errors.isEmpty()) { return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors); } debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Validation completed successfully, calling translator..."); - String translateJson = rulesBusinessLogic.translateRules(rules, entryPointPhaseName, lastPhaseName, vfcmt.getName()); + String translateJson = rulesBusinessLogic.translateRules(rules); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translation completed successfully"); return new ResponseEntity<>(translateJson, HttpStatus.OK); } catch (Exception e) { @@ -205,6 +260,50 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { } } + public ResponseEntity importRules(String json, String requestId, String userId, String vfcmtUuid, String dcaeCompLabel, String nid, String configParam) { + try { + MappingRulesResponse mappingRules = RulesPayloadUtils.parsePayloadToMappingRules(json); + List<ServiceException> errors = rulesBusinessLogic.validateImportedRules(mappingRules); + if (!errors.isEmpty()) { + // this will return the first violation found by the validator to the UI view as a regular error and all violations to the console view + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT, errors.stream().map(ServiceException::getFormattedErrorMessage).collect(Collectors.joining(", ")), errors.get(0).getFormattedErrorMessage()); + } + + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + checkVfcmtType(vfcmt); + + if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED); + } + + String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + + // check for MappingRules artifact in existing artifacts + Artifact artifactFound = vfcmt.getArtifacts().stream() + .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))) + .findAny().orElse(null); + + // new mappingRules artifact, validate nid exists in composition before creating new artifact + if (null == artifactFound) { + if (!cdumpContainsNid(vfcmt, nid, requestId)) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.NODE_NOT_FOUND, "", dcaeCompLabel); + } + saveNewRulesArtifact(mappingRules, vfcmtUuid, generateMappingRulesFileName(dcaeCompLabel, nid, configParam), artifactLabel, userId, requestId); + } else { + updateRulesArtifact(vfcmtUuid, userId, artifactFound, mappingRules, requestId); + } + mappingRules.setSchema(getEventTypeDefinitionUIs(mappingRules.getVersion(), mappingRules.getEventType())); + return checkInAndReturnSaveArtifactResult(mappingRules, vfcmtUuid, userId, requestId); + + } catch (JsonParseException je) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error: Rule format is invalid: {}", je); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT, "", je.getMessage()); + } catch (Exception e) { + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); + } + + } + public ResponseEntity getExistingRuleTargets(String vfcmtUuid, String requestId, String dcaeCompLabel, String nid) { try { @@ -260,19 +359,6 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { ///////////////////PRIVATE METHODS//////////////////////////////////////////////////////////////////////// - private String assertOwnershipOfVfcmtId(String userId, ResourceDetailed vfcmt, String requestId) { - checkUserIfResourceCheckedOut(userId, vfcmt); - String newVfcmtId = vfcmt.getUuid(); // may change after checking out a certified vfcmt - if (isNeedToCheckOut(vfcmt.getLifecycleState())) { - ResourceDetailed result = checkoutVfcmt(userId, newVfcmtId, requestId); - if (result != null) { - newVfcmtId = result.getUuid(); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkoutVfcmt is: {}", newVfcmtId); - } - } - return newVfcmtId; - } - // called after validating vfcmt.getArtifacts() is not null private boolean cdumpContainsNid(ResourceDetailed vfcmt, String nid, String requestId) { Artifact cdump = vfcmt.getArtifacts().stream() @@ -295,40 +381,44 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { return true; } - private ResponseEntity<String> saveNewRulesArtifact(Rule rule, String vfcmtUuid, String artifactFileName, String artifactLabel, String userId, String requestId) throws JsonProcessingException { - MappingRules body = new MappingRules(rule); - Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact(body.describe(), artifactFileName, ArtifactType.OTHER.name(), artifactLabel, body.convertToPayload()); - getSdcRestClient().createResourceArtifact(userId, vfcmtUuid, artifact, requestId); - return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId); - } + + private void saveNewRulesArtifact(MappingRules mappingRules, String vfcmtUuid, String artifactFileName, String artifactLabel, String userId, String requestId) throws JsonProcessingException { + Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact(mappingRules.describe(), artifactFileName, ArtifactType.OTHER.name(), artifactLabel, mappingRules.convertToPayload()); + getSdcRestClient().createResourceArtifact(userId, vfcmtUuid, artifact, requestId); + } private ResponseEntity addOrEditRuleInArtifact(Rule rule, String vfcmtUuid, String userId, Artifact rulesArtifact, String requestId) throws JsonProcessingException { String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId); MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); - // in case the rule id is passed but the rule doesn't exist on the mapping rule file: - if (!rulesBusinessLogic.addOrEditRule(rules, rule)) { + // 1810 US427299 support user defined phase names + boolean supportGroups = ValidationUtils.validateNotEmpty(rule.getGroupId()); + if(!rulesBusinessLogic.validateGroupDefinitions(rules, supportGroups)) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT, "", "invalid group definitions"); + } + // in case the rule id is passed but the rule doesn't exist on the mapping rule file or if there's a mismatch in group definitions: + if (!rulesBusinessLogic.addOrEditRule(rules, rule, supportGroups)) { return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED); } updateRulesArtifact(vfcmtUuid, userId, rulesArtifact, rules, requestId); - return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId); + return checkInAndReturnSaveArtifactResult(rule.toJson(), vfcmtUuid, userId, requestId); } // regardless of check in result, return save artifact success - private ResponseEntity<String> checkInAndReturnSaveArtifactResult(Rule rule, String vfcmtUuid, String userId, String requestId) { + private ResponseEntity checkInAndReturnSaveArtifactResult(Object response, String vfcmtUuid, String userId, String requestId) { try { checkinVfcmt(userId, vfcmtUuid, requestId); } catch (Exception e) { // swallowing the exception intentionally since it is on the check in action errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred while performing check in on VFCMT {}:{}", vfcmtUuid, e); } - return new ResponseEntity<>(rule.toJson(), HttpStatus.OK); + return new ResponseEntity<>(response, HttpStatus.OK); } private void updateRulesArtifact(String vfcmtUuid, String userId, Artifact artifactInfo, MappingRules rules, String requestId) throws JsonProcessingException { artifactInfo.setPayloadData(Base64Utils.encodeToString(rules.convertToPayload())); // POST must contain 'description' while GET returns 'artifactDescription' - artifactInfo.setDescription(artifactInfo.getArtifactDescription()); + artifactInfo.setDescription(rules.describe()); getSdcRestClient().updateResourceArtifact(userId, vfcmtUuid, artifactInfo, requestId); } @@ -378,6 +468,17 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { return dcaeCompLabel + "_" + nid + "_" + configParam + DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX; } + private String generateMappingRulesFileNameHeader(String vfcmtName, String dcaeCompLabel, String configParam) { + return "attachment; filename=\"" + .concat(vfcmtName) + .concat("_") + .concat(dcaeCompLabel) + .concat("_") + .concat(configParam) + .concat(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX) + .concat("\""); + } + private List<EventTypeDefinitionUI> getEventTypeDefinitionUIs(String version, String eventType) { List<String> eventNamesToReturn = ListUtils.union(EventTypesByVersionUI.DEFAULT_EVENTS, Arrays.asList(eventType)); Map<String, VesDataTypeDefinition> eventDefs = VesStructureLoader.getEventListenerDefinitionByVersion(version); @@ -385,4 +486,6 @@ public class RuleEditorBusinessLogic extends BaseBusinessLogic { return convertToEventTypeDefinition(filteredEvents, null, "event"); } + + } |