summaryrefslogtreecommitdiffstats
path: root/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller
diff options
context:
space:
mode:
authorStone, Avi (as206k) <as206k@att.com>2018-04-12 15:46:31 +0300
committerStone, Avi (as206k) <as206k@att.com>2018-04-12 15:49:38 +0300
commit5032434b101f25fa44d2e1f8dc8393e30af1ed4f (patch)
tree2dc7d37a8048e025c7412af080640da4c9a22b65 /dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller
parent2205633792f95f46a02bbf8f87f0c2637265d924 (diff)
DCAE-D be initial commit
DCAE-D be initial commit Issue-ID: SDC-1218 Change-Id: Id18ba96c499e785aa9ac395fbaf32d57f08c281b Signed-off-by: Stone, Avi (as206k) <as206k@att.com>
Diffstat (limited to 'dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller')
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java80
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java239
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java338
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java63
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java84
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java453
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java230
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java183
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java77
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java97
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java29
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java23
12 files changed, 1896 insertions, 0 deletions
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java
new file mode 100644
index 0000000..8b590ca
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java
@@ -0,0 +1,80 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.impl.BaseBusinessLogic;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.composition.util.SystemProperties;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.DcaeException;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ModelAttribute;
+
+import com.google.gson.Gson;
+
+public abstract class BaseController {
+
+ protected Gson gson = new Gson();
+
+ @Autowired
+ protected SystemProperties systemProperties;
+
+ @Autowired
+ protected BaseBusinessLogic baseBusinessLogic;
+
+ protected OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ protected OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @ModelAttribute("requestId")
+ public String getRequestId(HttpServletRequest request) {
+ return request.getAttribute("requestId").toString();
+ }
+
+ Asset checkout(String userId, String uuid, AssetType assetType, String requestId) throws Exception {
+ return baseBusinessLogic.getSdcRestClient().changeAssetLifecycleState(userId, uuid, LifecycleOperationType.CHECKOUT.name(), null, assetType, requestId);
+ }
+
+ Asset checkin(String userId, String uuid, AssetType assetType, String requestId) throws Exception {
+ return baseBusinessLogic.getSdcRestClient().changeAssetLifecycleState(userId, uuid, LifecycleOperationType.CHECKIN.name(), "checking in " + assetType.name() + uuid, assetType, requestId);
+ }
+
+
+ boolean isNeedToCheckOut(String lifecycleState) {
+ return DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(lifecycleState);
+ }
+
+ void checkUserIfResourceCheckedOut(String userId, Asset asset) throws DcaeException {
+ if (DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(asset.getLifecycleState())) {
+ String lastUpdaterUserId = asset.getLastUpdaterUserId();
+ if (lastUpdaterUserId != null && !lastUpdaterUserId.equals(userId)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "User conflicts. Operation not allowed for user {} on resource checked out by {}", userId, lastUpdaterUserId);
+ ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.USER_CONFLICT, null, userId, asset.getName(), lastUpdaterUserId);
+ throw new DcaeException(HttpStatus.FORBIDDEN, responseFormat.getRequestError());
+ }
+ }
+ }
+
+ void checkVfcmtType(ResourceDetailed vfcmt) {
+ if (!"VFCMT".equals(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());
+ }
+ }
+
+ ResponseEntity handleException(Exception e, ApiType apiType, String... variables){
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage());
+ return ErrConfMgr.INSTANCE.handleException(e, apiType, variables);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java
new file mode 100644
index 0000000..a12c6b8
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java
@@ -0,0 +1,239 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.apache.commons.lang.StringUtils;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.MessageResponse;
+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.composition.restmodels.sdc.*;
+import org.onap.sdc.dcae.utils.Normalizers;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.PostConstruct;
+import java.io.StringReader;
+import java.net.URI;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class BlueprintController extends BaseController{
+
+ @Autowired
+ private Blueprinter blueprinter;
+
+ @Autowired
+ private ASDC asdc;
+
+ private static final String CREATE_DESC = "creating new artifact blueprint on the service vfi";
+ private static final String UPDATE_DESC = "updating artifact blueprint on the service vfi";
+
+
+
+ @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);
+ }
+
+ /***
+ * VFCMT - Resource, blueprint - as an artifact as an service.
+ * @param userId
+ * @param vfcmtUuid
+ * @param serviceUuid
+ * @param serviceInstanceName
+ * @param monitoringFlowType
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/createBluePrint/{VFCMTUuid}/{serviceUuid}/{instanceName}/{monitoringFlowType}", method = RequestMethod.POST)
+ public ResponseEntity createBluePrint(@RequestHeader("USER_ID") String userId,
+ @PathVariable("VFCMTUuid") String vfcmtUuid,
+ @PathVariable("serviceUuid") String serviceUuid,
+ @PathVariable("instanceName") String serviceInstanceName,
+ @PathVariable("monitoringFlowType") String monitoringFlowType,
+ @ModelAttribute("requestId") String requestId) {
+ try {
+
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+ Artifact cdumpArtifactData = findCdumpArtifactData(vfcmt);
+ if (null != cdumpArtifactData) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found the cdump (composition.yml) on top of VFCMT {}", vfcmtUuid);
+ String cdump = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, cdumpArtifactData.getArtifactUUID(), requestId);
+ 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);
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to use python procedure to create a blueprint....");
+ String resultBlueprintCreation;
+ try{
+ resultBlueprintCreation = utils.buildBlueprintViaToscaLab(new StringReader(cdump)).waitForResult().waitForResult();
+ }catch (Exception e){
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, e.getMessage(), vfcmt.getName());
+ }
+ if (StringUtils.isEmpty(resultBlueprintCreation)) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, "", vfcmt.getName());
+ }
+
+ // 1806 US374595 flowType in cdump
+ String flowTypeFromCdump = StringUtils.substringBetween(cdump,"\"flowType\":\"","\"");
+ if(StringUtils.isNotBlank(flowTypeFromCdump)) {
+ monitoringFlowType = flowTypeFromCdump;
+ }
+ // saving to serviceVfInstance
+ Artifact savedBluePrint = saveBluePrint(userId, serviceUuid, serviceInstanceName, resultBlueprintCreation, monitoringFlowType, vfcmt.getName(), requestId);
+ if(savedBluePrint!=null){
+ MessageResponse response = new MessageResponse();
+ response.setSuccessResponse("Blueprint build complete \n. Blueprint="+savedBluePrint.getArtifactName());
+ //1806 US374593 - certify VFCMT after BP generation
+ certifyVfcmt(vfcmt, requestId);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+ else{
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SUBMIT_BLUEPRINT_ERROR);
+ }
+
+ }else{
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName());
+ }
+ } catch (Exception e) {
+ return handleException(e, ApiType.SUBMIT_BLUEPRINT);
+ }
+ }
+
+
+ /********************* private function ********************/
+
+ /**
+ * @param userId
+ * @param serviceUuid
+ * @param resourceInstanceName
+ * @param bluePrint
+ * @param monitoringFlowType
+ * @param vfcmtName
+ * @param requestId
+ * @return
+ * @throws Exception
+ */
+ private Artifact saveBluePrint(String userId, String serviceUuid, String resourceInstanceName, String bluePrint, String monitoringFlowType, String vfcmtName, String requestId) throws Exception {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "BLUEPRINT:\n{}", bluePrint);
+ try {
+ ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(serviceUuid, requestId);
+ //Validations
+ checkUserIfResourceCheckedOut(userId, service);
+ ResourceInstance vfi = findVfiOnService(service, resourceInstanceName);
+ if(null == vfi){
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VF instance {} not found on service {}", resourceInstanceName, serviceUuid);
+ return null;
+ }
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), service.toString());
+
+ String normalizedArtifactLabel = Normalizers.normalizeArtifactLabel("blueprint-" + monitoringFlowType);
+ Artifact blueprintArtifact = CollectionUtils.isEmpty(vfi.getArtifacts()) ? null : vfi.getArtifacts().stream()
+ .filter(p -> normalizedArtifactLabel.equals(Normalizers.normalizeArtifactLabel(p.getArtifactLabel())))
+ .findAny()
+ .orElse(null);
+
+ boolean isNeed2Checkout = isNeedToCheckOut(service.getLifecycleState());
+ if (isNeed2Checkout) {
+ Asset result = checkout(userId, serviceUuid, AssetType.SERVICE, requestId);
+ if (result != null) {
+ serviceUuid = result.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New service after checkout is: {}", serviceUuid);
+ }
+ }
+ //update mode
+ if (null != blueprintArtifact) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found that service {} already consist of {} ----> updateMode", serviceUuid, normalizedArtifactLabel);
+ blueprintArtifact.setDescription(UPDATE_DESC);
+ blueprintArtifact.setPayloadData(Base64Utils.encodeToString(bluePrint.getBytes()));
+ blueprintArtifact = baseBusinessLogic.getSdcRestClient().updateVfInstanceArtifact(userId, serviceUuid, Normalizers.normalizeComponentInstanceName(resourceInstanceName), blueprintArtifact, requestId);
+ //create mode
+ } else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Service {} does not consist {} ----> createMode", serviceUuid, normalizedArtifactLabel);
+ blueprintArtifact = SdcRestClientUtils.generateDeploymentArtifact(CREATE_DESC, generateBlueprintFileName(monitoringFlowType, vfcmtName), ArtifactType.DCAE_INVENTORY_BLUEPRINT.name(), normalizedArtifactLabel, bluePrint.getBytes());
+ blueprintArtifact = baseBusinessLogic.getSdcRestClient().createVfInstanceArtifact(userId, serviceUuid, Normalizers.normalizeComponentInstanceName(resourceInstanceName), blueprintArtifact, requestId);
+ }
+
+ //No need to check the service in in 1806
+// Asset blueprintAsJson = checkin(user_id, serviceUuid, AssetType.SERVICE);
+// debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "service result after check-in: {}", blueprintAsJson.toString());
+
+ return blueprintArtifact;
+
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred while trying to save blueprint {}", e.toString());
+ throw e;
+ }
+ }
+
+ /**
+ *
+ * @param monitoringFlowType
+ * @param vfcmtName
+ * @return
+ */
+ private String generateBlueprintFileName(String monitoringFlowType, String vfcmtName) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(monitoringFlowType);
+ sb.append(".");
+ sb.append(Normalizers.normalizeComponentName(vfcmtName));
+ sb.append(".");
+ sb.append(DcaeBeConstants.Composition.fileNames.EVENT_PROC_BP_YAML);
+ return sb.toString();
+ }
+
+ private ResourceInstance findVfiOnService(ServiceDetailed service, String vfiName) {
+ return null == service ? null : CollectionUtils.isEmpty(service.getResources()) ? null : service.getResources().stream().filter(p -> vfiName.equals(p.getResourceInstanceName())).findAny().orElse(null);
+ }
+
+ private Artifact findCdumpArtifactData(ResourceDetailed vfcmt) {
+ return null == vfcmt ? null : CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream()
+ .filter(p -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(p.getArtifactName())).findAny().orElse(null);
+ }
+
+ private void certifyVfcmt(ResourceDetailed vfcmt, String requestId){
+ String state = vfcmt.getLifecycleState();
+ if(null == state) {
+ debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't read Vfcmt lifecycle state");
+ return;
+ }
+ DcaeBeConstants.LifecycleStateEnum lifeCycleState = DcaeBeConstants.LifecycleStateEnum.findState(state);
+ if(null == lifeCycleState) {
+ debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Undefined lifecycle state: {}", state);
+ return;
+ }
+ try{
+ switch (lifeCycleState){
+ case NOT_CERTIFIED_CHECKOUT:
+ baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(vfcmt.getLastUpdaterUserId(), vfcmt.getUuid(), LifecycleOperationType.CHECKIN.name(), "check in VFCMT after blueprint successful submission", requestId);
+ case NOT_CERTIFIED_CHECKIN:
+ baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(vfcmt.getLastUpdaterUserId(), vfcmt.getUuid(), LifecycleOperationType.CERTIFY.name(), "certify VFCMT after blueprint successful submission", requestId);
+ }
+ }
+ catch (Exception e){
+ //informative only. no message to user (TBA)
+ debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred during vfcmt lifecycle operation: {}", e.toString());
+ }
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java
new file mode 100644
index 0000000..5cba14f
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java
@@ -0,0 +1,338 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.MessageResponse;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.catalog.Catalog;
+import org.onap.sdc.dcae.catalog.Catalog.*;
+import org.onap.sdc.dcae.catalog.engine.*;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.async.DeferredResult;
+
+import javax.annotation.PostConstruct;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class CompositionController extends BaseController{
+
+ @Autowired
+ private CatalogController catalogController;
+
+ @PostConstruct
+ public void init() {
+ catalogController.setDefaultCatalog(URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_CATALOG_URL)));
+ }
+
+ @RequestMapping(value = { "/utils/clone/{assetType}/{sourceId}/{targetId}" }, method = {RequestMethod.GET }, produces = { "application/json" })
+ public ResponseEntity clone(@RequestHeader("USER_ID") String userId, @PathVariable("assetType") String theAssetType, @PathVariable("sourceId") String theSourceId, @PathVariable("targetId") String theTargetId,
+ @ModelAttribute("requestId") String requestId) {
+ MessageResponse response = new MessageResponse();
+
+ try {
+ // fetch the source and assert it is a vfcmt containing clone worthy artifacts (composition + rules)
+ ResourceDetailed sourceVfcmt = baseBusinessLogic.getSdcRestClient().getResource(theSourceId, requestId);
+ checkVfcmtType(sourceVfcmt);
+ List<Artifact> artifactsToClone = CollectionUtils.isEmpty(sourceVfcmt.getArtifacts()) ? null : sourceVfcmt.getArtifacts().stream()
+ .filter(p -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(p.getArtifactName()) || p.getArtifactName().endsWith(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX))
+ .collect(Collectors.toList());
+ if(CollectionUtils.isEmpty(artifactsToClone)) {
+ response.setSuccessResponse("Nothing to clone");
+ return new ResponseEntity<>(response ,HttpStatus.NO_CONTENT);
+ }
+
+ // fetch the target
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(theTargetId, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+ boolean isTargetNeed2Checkout = isNeedToCheckOut(vfcmt.getLifecycleState());
+ if (isTargetNeed2Checkout) {
+ ResourceDetailed targetVfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKOUT.name(), "checking out VFCMT before clone", requestId);
+ if(null == targetVfcmt){
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERAL_ERROR);
+ }
+ theTargetId = targetVfcmt.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New targetVfcmt (for artifact clone) after checkout is: {}", theTargetId);
+ }
+
+ Map<String, Artifact> currentArtifacts = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? new HashMap<>() : vfcmt.getArtifacts().stream()
+ .collect(Collectors.toMap(Artifact::getArtifactName, Function.identity()));
+
+ //TODO target VFCMT rule artifacts should be removed
+ for(Artifact artifactToClone : artifactsToClone) {
+ String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(theSourceId, artifactToClone.getArtifactUUID(), requestId);
+ baseBusinessLogic.cloneArtifactToTarget(userId, theTargetId, payload, artifactToClone, currentArtifacts.get(artifactToClone.getArtifactName()), requestId);
+ }
+
+ baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKIN.name(), "check in VFCMT after clone", requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Cloning {} from {} has finished successfully", theSourceId, theTargetId);
+ response.setSuccessResponse("Clone VFCMT complete");
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.CLONE_VFCMT);
+ }
+ }
+
+ @RequestMapping(value = "/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json")
+ public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest) {
+
+ final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout());
+
+ catalog.rootsByLabel(request.getStartingLabel())
+ .setHandler(catalogController.new CatalogHandler<Folders>(request, result) {
+ public CatalogResponse handleData(Folders theFolders) {
+ JSONArray ja = new JSONArray();
+ if (theFolders != null) {
+ for (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;
+ }
+ });
+ return result;
+ }
+
+ @RequestMapping(value = "/{theItemId}/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json")
+ public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest, @PathVariable String theItemId) {
+
+ final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout());
+
+ catalog
+ // .fetchFolderByItemId(theItemId)
+ .folder(theItemId).withParts().withPartAnnotations().withItems().withItemAnnotations().withItemModels()
+ .execute().setHandler(catalogController.new CatalogHandler<Folder>(request, result) {
+ public CatalogResponse handleData(Folder theFolder) {
+ CatalogResponse response = new CatalogResponse(this.request);
+ if (theFolder == null) {
+ return response;
+ }
+
+ try {
+ Elements folders = theFolder.elements("parts", Folders.class);
+ if (folders != null) {
+ for (Object folder : folders) {
+ catalogController.patchData(catalog, ((Element) folder).data());
+ // lots of ephemere proxies created here ..
+ Elements annotations = ((Element) folder).elements("annotations",
+ Annotations.class);
+ if (annotations != null) {
+ for (Object a : annotations) {
+ catalogController.patchData(catalog, ((Annotation) a).data());
+ }
+ }
+ }
+ }
+ Elements items = theFolder.elements("items", Items.class);
+ if (items != null) {
+ for (Object i : items) {
+ catalogController.patchData(catalog, ((Element) i).data());
+ // lots of ephemere proxies created here ..
+ Elements annotations = ((Element) i).elements("annotations", Annotations.class);
+ if (annotations != null) {
+ for (Object a : annotations) {
+ catalogController.patchData(catalog, ((Annotation) a).data());
+ }
+ }
+ }
+ }
+ } 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;
+ }
+ });
+
+ return result;
+ }
+
+ @RequestMapping(value = "/{theItemId}/model", method = { RequestMethod.POST,RequestMethod.GET }, produces = "application/json")
+ public DeferredResult model(@RequestBody(required = false) ElementRequest theRequest,
+ @PathVariable String theItemId) {
+ final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout());
+
+ catalog
+ .item(theItemId).withModels().execute()
+ .setHandler(catalogController.new CatalogHandler<Item>(request, result) {
+ public CatalogResponse handleData(Item theItem) {
+ if (theItem == null) {
+ return new CatalogError(this.request, "No such item");
+ }
+ Templates models = null;
+ try {
+ models = (Templates) theItem.elements("models", Templates.class);
+ 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 !?");
+ }
+ catalog.template(models.get(0).id()).withInputs().withOutputs().withNodes()
+ .withNodeProperties().withNodePropertiesAssignments().withNodeRequirements()
+ .withNodeCapabilities().withNodeCapabilityProperties()
+ .withNodeCapabilityPropertyAssignments().withPolicies().withPolicyProperties()
+ .withPolicyPropertiesAssignments().execute().setHandler(
+ catalogController.new CatalogHandler<Template>(this.request, this.result) {
+ public CatalogResponse handleData(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);
+ }
+ }
+ return response;
+ }
+ });
+ } catch (Exception e) {
+ handleException(e, ApiType.GET_MODEL, models.get(0).name());
+ }
+ return null;
+ }
+ });
+
+ return result;
+ }
+
+ @RequestMapping(value = "/{theItemId}/type/{theTypeName}", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json")
+ public DeferredResult<CatalogResponse> model(@RequestBody(required = false) ElementRequest theRequest, @PathVariable String theItemId, @PathVariable String theTypeName) {
+ final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout());
+
+ catalog.type(theItemId, theTypeName).withHierarchy().withCapabilities().withRequirements().execute()
+ .setHandler(catalogController.new CatalogHandler<Type>(request, result) {
+ public CatalogResponse handleData(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;
+ }
+ });
+
+ return result;
+ }
+
+ @RequestMapping(value = { "/getComposition/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getComposition(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+ MessageResponse response = new MessageResponse();
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+
+ Artifact compositionArtifact = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(a.getArtifactName())).findAny().orElse(null);
+
+ if(null == compositionArtifact){
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Couldn't find {} in VFCMT artifacts", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ response.setErrorResponse("No Artifacts");
+ return new ResponseEntity<>(response, HttpStatus.NO_CONTENT);
+ }
+
+ String artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, compositionArtifact.getArtifactUUID(), requestId);
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT: {}", artifact);
+ response.setSuccessResponse(artifact);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_CDUMP);
+ }
+ }
+
+ @RequestMapping(value = "/saveComposition/{vfcmtUuid}", method = RequestMethod.POST)
+ public ResponseEntity saveComposition(@RequestHeader("USER_ID") String userId, @RequestBody String theCdump, @PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT CDUMP: {}", theCdump);
+
+ try {
+
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT: {}", vfcmt);
+
+ checkVfcmtType(vfcmt);
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+ boolean isNeed2Checkout = isNeedToCheckOut(vfcmt.getLifecycleState());
+ Artifact compositionArtifact = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(a.getArtifactName())).findAny().orElse(null);
+ String resourceUuid = vfcmtUuid; // by default the resource is the original vfcmtId unless a checkout will be done
+ if (isNeed2Checkout) {
+ vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, resourceUuid, LifecycleOperationType.CHECKOUT.name(), null, requestId);
+ if (vfcmt != null) {
+ resourceUuid = vfcmt.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkout is: {}", resourceUuid);
+ }
+ }
+ boolean isUpdateMode = null != compositionArtifact;
+ if (isUpdateMode) {
+ compositionArtifact.setDescription("updating composition file");
+ compositionArtifact.setPayloadData(Base64Utils.encodeToString(theCdump.getBytes()));
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT {} does consist {} ----> updateMode", resourceUuid, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, resourceUuid, compositionArtifact, requestId);
+
+ } else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT {} does not consist {} ----> createMode", resourceUuid, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ compositionArtifact = SdcRestClientUtils.generateDeploymentArtifact("creating composition file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, ArtifactType.DCAE_TOSCA.name(), "composition", theCdump.getBytes());
+ baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, resourceUuid, compositionArtifact, requestId);
+ }
+ Asset result = checkin(userId, resourceUuid, org.onap.sdc.dcae.enums.AssetType.RESOURCE, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "vfcmt check-in result: {}", result);
+
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.SAVE_CDUMP);
+ }
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java
new file mode 100644
index 0000000..4f083ca
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java
@@ -0,0 +1,63 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.CompositionConfig;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.ves.VesStructureLoader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+@RequestMapping("/conf")
+public class ConfigurationController extends BaseController{
+
+ @Autowired
+ private CompositionConfig compositionConfig;
+
+ @ApiOperation(value = "Get a list of available flow types", response = CompositionConfig.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Successfully retrieved available flow types list"),
+ @ApiResponse(code = 500, message = "Flow types couldn't be fetched due to internal error")})
+ @RequestMapping(value = "/composition", method = RequestMethod.GET)
+ public ResponseEntity getCompositionConfig() {
+ try {
+ return new ResponseEntity<>(compositionConfig, HttpStatus.OK);
+ }catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Exception:{}",e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.FLOW_TYPES_CONFIGURATION_ERROR);
+ }
+ }
+
+ @RequestMapping(value = "/ves/schemaversions", method = RequestMethod.GET)
+ public ResponseEntity getCommonEventFormatVersion() {
+ try {
+ Set<String> availableVersionsSet = VesStructureLoader.getAvailableVersionsList();
+ List<String> availableVersionsList = new ArrayList<>(availableVersionsSet.size());
+ availableVersionsList.addAll(availableVersionsSet);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got a request to return available ves schema versions: {}", availableVersionsSet);
+ return new ResponseEntity<>(availableVersionsList, HttpStatus.OK);
+ }catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Exception:{}",e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND);
+ }
+ }
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java
new file mode 100644
index 0000000..3007335
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java
@@ -0,0 +1,84 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.UUID;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class LifecycleController extends BaseController {
+
+ private static final String VFCMT = "vfcmt";
+
+ @RequestMapping(value={"/checkin/{assetType}/{uuid}"}, method={RequestMethod.PUT}, produces={"application/json"})
+ public ResponseEntity putCheckin(
+ @PathVariable("assetType") String assetType,
+ @PathVariable("uuid") UUID uuid,
+ @RequestHeader("USER_ID") String user_id,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ switch (assetType) {
+ case VFCMT:
+ Asset res_checkin = checkin(user_id, uuid.toString(), AssetType.RESOURCE, requestId);
+ return new ResponseEntity<>(res_checkin, HttpStatus.OK);
+
+ default:
+ return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+ }
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.CHECK_IN_RESOURCE);
+ }
+ }
+
+ @RequestMapping(value={"/checkout/{assetType}/{uuid}"}, method={RequestMethod.PUT}, produces={"application/json"})
+ public ResponseEntity putCheckout(
+ @PathVariable("assetType") String assetType,
+ @PathVariable("uuid") UUID uuid,
+ @RequestHeader("USER_ID") String user_id,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ switch (assetType) {
+ case VFCMT:
+ Asset asset = checkout(user_id, uuid.toString(), AssetType.RESOURCE, requestId);
+ return new ResponseEntity<>(asset, HttpStatus.OK);
+
+ default:
+ return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+ }
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.CHECK_OUT_RESOURCE);
+ }
+ }
+
+ @RequestMapping(value={"/certify/{assetType}/{uuid}"}, method={RequestMethod.PUT}, produces={"application/json"})
+ public ResponseEntity putCertify(
+ @PathVariable("assetType") String assetType,
+ @PathVariable("uuid") String uuid,
+ @RequestHeader("USER_ID") String user_id,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ switch (assetType) {
+ case VFCMT:
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(user_id, uuid, LifecycleOperationType.CERTIFY.name(), "certifying VFCMT", requestId);
+ return new ResponseEntity<>(vfcmt, HttpStatus.OK);
+
+ default:
+ return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+ }
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.CHECK_OUT_RESOURCE);
+ }
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java
new file mode 100644
index 0000000..3f5ff1a
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java
@@ -0,0 +1,453 @@
+package org.onap.sdc.dcae.composition.controller;
+
+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.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.composition.CompositionConfig;
+import org.onap.sdc.dcae.utils.Normalizers;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.enums.ArtifactType;
+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.errormng.ErrConfMgr.ApiType;
+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.utils.SdcRestClientUtils;
+import org.onap.sdc.dcae.ves.VesDataItemsDefinition;
+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.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+@RequestMapping("/rule-editor")
+public class RuleEditorController extends BaseController {
+
+ private static final String EXCEPTION = "Exception {}";
+ @Autowired
+ private CompositionConfig compositionConfig;
+
+ @Autowired
+ private RulesBusinessLogic rulesBusinessLogic;
+
+ @RequestMapping(value = "/list-events-by-versions", method = RequestMethod.GET)
+ public ResponseEntity getEventsByVersion() {
+ try {
+
+ Map<String, Set<String>> eventsByVersions = VesStructureLoader.getAvailableVersionsAndEventTypes();
+
+ List<EventTypesByVersionUI> resBody = eventsByVersions.entrySet().stream().map(entry -> {
+ Set<String> events = entry.getValue().stream().filter(event -> !EventTypesByVersionUI.DEFAULT_EVENTS.contains(event)).collect(Collectors.toSet());
+ return new EventTypesByVersionUI(entry.getKey(), events);
+ }).collect(Collectors.toList());
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got a request to return all ves event types by versions {}", eventsByVersions);
+ return new ResponseEntity<>(resBody, HttpStatus.OK);
+
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND);
+ }
+ }
+
+ @RequestMapping(value = { "/definition/{version:.*}/{eventType}" }, method = { RequestMethod.GET }, produces = { "application/json" })
+ public ResponseEntity getDefinition(@PathVariable("version") String version,
+ @PathVariable("eventType") String eventType) {
+
+ try {
+ List<EventTypeDefinitionUI> result = getEventTypeDefinitionUIs(version, eventType);
+
+ return new ResponseEntity<>(result, HttpStatus.OK);
+
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND);
+ }
+ }
+
+ /**
+ * This endpoint functions as a 'create/update' service for the rule editor UI
+ *
+ * @param json - json representing the saved rule
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @return json representing the rule editor UI
+ * Validations:
+ * 1. That the user is able to edit the VFCMT
+ * 2. That the cdump holds a dcae component with such nid (to avoid orphan rules)
+ * 3. Check that the fetched VFCMT is actually a VFCMT and not a regular VF
+ */
+ @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.POST }, produces = "application/json")
+ public ResponseEntity saveRule(@RequestBody String json, @ModelAttribute("requestId") String requestId,
+ @RequestHeader("USER_ID") String userId,
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam) {
+ try {
+ Rule rule = RulesPayloadUtils.parsePayloadToRule(json);
+ if (null == rule) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT);
+ }
+
+ List<ServiceException> errors = rulesBusinessLogic.validateRule(rule);
+ if(!errors.isEmpty()){
+ return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors);
+ }
+
+ ResourceDetailed vfcmt = baseBusinessLogic.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);
+
+ // exception thrown if vfcmt is checked out and current user is not its owner
+ // performs vfcmt checkout 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);
+ }
+ 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);
+
+ } 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 handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT);
+ }
+
+ }
+
+
+ /**
+ * This endpoint functions as a 'fetch' service for the rule editor UI
+ *
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @return json representing the rule editor UI
+ */
+ @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.GET }, produces = "application/json")
+ public ResponseEntity getRules(
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.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 = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactListed.getArtifactUUID(), requestId);
+
+ // 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);
+ List<EventTypeDefinitionUI> schema = null == schemainfo? new ArrayList<>() : getEventTypeDefinitionUIs(schemainfo.getVersion(), schemainfo.getEventType());
+ return new ResponseEntity<>(RulesPayloadUtils.buildSchemaAndRulesResponse(ruleFile, schema), HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_RULE_ARTIFACT);
+ }
+
+ }
+
+ /**
+ * This endpoint functions as a 'delete' service for the rule editor UI
+ *
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @param ruleUid - the unique id of the rule to delete
+ * @return operation result
+ */
+ @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}/{ruleUid}", method = { RequestMethod.DELETE }, produces = "application/json")
+ public ResponseEntity deleteRule(
+ @RequestHeader("USER_ID") String userId,
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam,
+ @PathVariable("ruleUid") String ruleUid,
+ @ModelAttribute("requestId") String requestId){
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.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 vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId);
+ String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtId, mappingRuleFile.getArtifactUUID(), requestId);
+ MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload);
+ Rule removedRule = rulesBusinessLogic.deleteRule(rules, ruleUid);
+ if(null == removedRule){
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Rule {} not found.", ruleUid);
+ 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
+ baseBusinessLogic.getSdcRestClient().deleteResourceArtifact(userId, vfcmtId, mappingRuleFile.getArtifactUUID(), requestId);
+ } else {
+ updateRulesArtifact(vfcmtId, userId, mappingRuleFile, rules, requestId);
+ }
+ return checkInAndReturnSaveArtifactResult(removedRule, vfcmtId, userId, requestId);
+ } catch (Exception e) {
+ return handleException(e, ApiType.SAVE_RULE_ARTIFACT);
+ }
+
+ }
+
+ /**
+ * This endpoint functions as a 'translate' service for the rule editor UI
+ *
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @param flowType - the mapping rules flow type (SNMP,Syslog,FOI)
+ * @return translateJson representing the translated Rules
+ * Validations:
+ * 1. That the user is able to edit the VFCMT
+ * 2. That the cdump holds a dcae component with such nid (to avoid orphan rules)
+ * 3. Check that the fetched VFCMT is actually a VFCMT and not a regular VF
+ * @throws Exception
+ */
+ @RequestMapping(value = "/rule/translate/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.GET }, produces = "application/json")
+ public ResponseEntity translateRules(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam,
+ @RequestParam("flowType") String flowType) throws Exception {
+
+ 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");
+ }
+
+ // 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 = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ checkVfcmtType(vfcmt);
+
+ if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "No rules found on VFCMT " + vfcmtUuid);
+ }
+ String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam);
+
+ // 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);
+ }
+
+ String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Retrieved mapping rules artifact {}, start parsing rules...", artifactLabel);
+ MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished parsing rules, calling validator...");
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(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());
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translation completed successfully");
+ return new ResponseEntity<>(translateJson, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.SAVE_RULE_ARTIFACT);
+ }
+ }
+
+
+ ///////////////////PRIVATE METHODS////////////////////////////////////////////////////////////////////////
+
+ private String assertOwnershipOfVfcmtId(String userId, ResourceDetailed vfcmt, String requestId) throws Exception {
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+ String newVfcmtId = vfcmt.getUuid(); // may change after checking out a certified vfcmt
+ if (isNeedToCheckOut(vfcmt.getLifecycleState())) {
+ Asset result = checkout(userId, newVfcmtId, AssetType.RESOURCE, requestId);
+ if (result != null) {
+ newVfcmtId = result.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkout 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()
+ .filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equalsIgnoreCase(a.getArtifactName()))
+ .findAny().orElse(null);
+ if (null == cdump || null == cdump.getArtifactUUID()) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "No {} found on vfcmt {}", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, vfcmt.getUuid());
+ return false;
+ }
+ try {
+ String artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmt.getUuid(), cdump.getArtifactUUID(), requestId);
+ if (!artifact.contains("\"nid\":\""+nid)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't contain nid {}. Cannot save mapping rule file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, nid);
+ return false;
+ }
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e);
+ return false;
+ }
+ return true;
+ }
+
+ private ResponseEntity<String> saveNewRulesArtifact(Rule rule, String vfcmtUuid, String artifactFileName, String artifactLabel, String userId, String requestId) throws Exception {
+ MappingRules body = new MappingRules(rule);
+ Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact(body.describe(), artifactFileName, ArtifactType.OTHER.name(), artifactLabel, body.convertToPayload());
+ baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, vfcmtUuid, artifact, requestId);
+ return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId);
+ }
+
+ private ResponseEntity addOrEditRuleInArtifact(Rule rule, String vfcmtUuid, String userId, Artifact rulesArtifact, String requestId) throws Exception {
+ String payload = baseBusinessLogic.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)) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED);
+ }
+ updateRulesArtifact(vfcmtUuid, userId, rulesArtifact, rules, requestId);
+ return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId);
+ }
+
+ // regardless of check in result, return save artifact success
+ private ResponseEntity<String> checkInAndReturnSaveArtifactResult(Rule rule, String vfcmtUuid, String userId, String requestId) {
+ try {
+ checkin(userId, vfcmtUuid, AssetType.RESOURCE, 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);
+ }
+
+ private void updateRulesArtifact(String vfcmtUuid, String userId, Artifact artifactInfo, MappingRules rules, String requestId) throws Exception {
+ artifactInfo.setPayloadData(Base64Utils.encodeToString(rules.convertToPayload()));
+ // POST must contain 'description' while GET returns 'artifactDescription'
+ artifactInfo.setDescription(artifactInfo.getArtifactDescription());
+ baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, vfcmtUuid, artifactInfo, requestId);
+ }
+
+
+ /**
+ * @param eventMapStream
+ * @param parent
+ * @param path
+ * @return
+ */
+ private List<EventTypeDefinitionUI> convertToEventTypeDefinition(Stream<Entry<String, VesDataTypeDefinition>> eventMapStream, VesDataTypeDefinition parent, String path) {
+
+ return eventMapStream.map(entry -> {
+ Map<String, VesDataTypeDefinition> properties = entry.getValue().getProperties();
+ VesDataItemsDefinition items = entry.getValue().getItems();
+ String newPath = path + "." + entry.getKey();
+ List<EventTypeDefinitionUI> children = (properties == null) ? null : convertToEventTypeDefinition(properties.entrySet().stream(), entry.getValue(), newPath);
+ if(VesSimpleTypesEnum.ARRAY.getType().equals(entry.getValue().getType())) {
+ newPath += "[]";
+ if(innerTypeIsComplex(items)) {
+ children = convertComplexArrayType(items, newPath);
+ } else if(innerTypeIsArray(items)) {
+ newPath += "[]";
+ }
+ }
+
+ boolean isRequired = (parent != null) ? parent.getRequired().contains(entry.getKey()) : false;
+ return new EventTypeDefinitionUI(entry.getKey(), children, isRequired, newPath);
+ }).collect(Collectors.toList());
+ }
+
+ private boolean innerTypeIsComplex(VesDataItemsDefinition items){
+ return items != null && items.stream().anyMatch(p -> p.getProperties() != null);
+ }
+
+ private boolean innerTypeIsArray(VesDataItemsDefinition items){
+ return items != null && items.stream().anyMatch(p -> p.getItems() != null);
+ }
+
+ private List<EventTypeDefinitionUI> convertComplexArrayType(VesDataItemsDefinition items, String path){
+ return items.stream().map(item -> item.getProperties() != null ? convertToEventTypeDefinition(item.getProperties().entrySet().stream(), item, path) : new ArrayList<EventTypeDefinitionUI>())
+ .flatMap(List::stream).collect(Collectors.toList());
+ }
+
+
+ private String generateMappingRulesFileName(String dcaeCompLabel, String nid, String configParam) {
+ return dcaeCompLabel + "_" + nid + "_" + configParam + DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX;
+ }
+
+ 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);
+ Stream<Entry<String, VesDataTypeDefinition>> filteredEvents = eventDefs.entrySet().stream().filter(entry -> eventNamesToReturn.contains(entry.getKey()));
+
+ return convertToEventTypeDefinition(filteredEvents, null, "event");
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java
new file mode 100644
index 0000000..257d1a9
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java
@@ -0,0 +1,230 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.AttachVFCMTServiceRequest;
+import org.onap.sdc.dcae.composition.restmodels.DcaeMinimizedService;
+import org.onap.sdc.dcae.composition.restmodels.MessageResponse;
+import org.onap.sdc.dcae.composition.restmodels.sdc.*;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.DcaeException;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class ServicesController extends BaseController {
+
+ /***
+ * GET services list by VFCMT
+ * @param userId
+ * @param vfcmtUuid
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/services/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity services(@RequestHeader("USER_ID") String userId, @PathVariable String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET ({}) Vfcmt form SDC: {}", vfcmtUuid, vfcmt);
+ checkVfcmtType(vfcmt);
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+
+ List<Service> services = baseBusinessLogic.getSdcRestClient().getServices(requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET services data from SDC: {}", services);
+ List<Service> uuids = filterServicesByUser(services, userId);
+ return new ResponseEntity<>(uuids, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.GET_SERVICE);
+ }
+ }
+
+ /***
+ * GET a single service
+ * @param theServiceId
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/service/{theServiceId}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity service(@PathVariable String theServiceId, @ModelAttribute("requestId") String requestId) {
+ try {
+ ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(theServiceId, requestId);
+ if (service != null) {
+ if(service.getResources()!=null){
+ List<ResourceInstance> vfResourcesOnly = service.getResources().stream().filter(vfi -> vfi.getResoucreType().equals("VF")).collect(Collectors.toList());
+ service.setResources(vfResourcesOnly);
+ }else{
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Service {} doesn't have any resources (e.g VFi's)", theServiceId);
+ }
+ } else {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't fetch service with uuid {} from SDC", theServiceId);
+ }
+ return new ResponseEntity<>(service, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.GET_SERVICE);
+ }
+ }
+
+
+ /***
+ * Attach service and service instance to VFCMT
+ * @param userId
+ * @param request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/{vfcmtUuid}/attachment", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity attachService(
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @RequestHeader("USER_ID") String userId,
+ @RequestBody AttachVFCMTServiceRequest request,
+ @ModelAttribute("requestId") String requestId) {
+
+ String serviceUuid = request.getServiceUuid();
+ String vfiName = request.getInstanceName();
+ String resourceUuid = vfcmtUuid;
+ MessageResponse response = new MessageResponse();
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+
+ checkVfcmtType(vfcmt);
+ verifyVfiExists(serviceUuid, vfiName, requestId);
+
+ boolean isUpdateMode = false;
+ Artifact artifactObj = null;
+
+ String reference = serviceUuid + "/resources/" + vfiName;
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************");
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Reference between service and vfi {}", reference);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************");
+
+ if(!CollectionUtils.isEmpty(vfcmt.getArtifacts())){
+ artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null);
+ isUpdateMode = null != artifactObj;
+ }
+
+ if (isNeedToCheckOut(vfcmt.getLifecycleState())) {
+ vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, vfcmtUuid, LifecycleOperationType.CHECKOUT.name(), null, requestId);
+ if (vfcmt != null) {
+ resourceUuid = vfcmt.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New vfcmt uuid after checkout is: {}", resourceUuid);
+ }
+ }
+
+ if(isUpdateMode){
+ updateReferenceArtifact(userId, resourceUuid, artifactObj, reference, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} updated with content: {}", reference, DcaeBeConstants.Composition.fileNames.SVC_REF, reference);
+ }else{
+ Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact("createReferenceArtifact", DcaeBeConstants.Composition.fileNames.SVC_REF, ArtifactType.DCAE_TOSCA.name(), "servicereference", reference.getBytes());
+ baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, resourceUuid, artifact, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} created with content: {}", DcaeBeConstants.Composition.fileNames.SVC_REF, reference);
+ }
+ checkin(userId, resourceUuid, org.onap.sdc.dcae.enums.AssetType.RESOURCE, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Attachment of reference={} in VFCMT {} has finished successfully", reference, resourceUuid);
+
+ response.setSuccessResponse("Artifact updated");
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.ATTACH_TO_SERVICE);
+ }
+ }
+
+ @RequestMapping(value = { "/{vfcmtUuid}/attachment" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getAttachedService(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+
+ MessageResponse response = new MessageResponse();
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+ String artifact = "No Artifacts";
+
+ if (!CollectionUtils.isEmpty(vfcmt.getArtifacts())) {
+ Artifact artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null);
+ if (null != artifactObj)
+ artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactObj.getArtifactUUID(), requestId);
+ }
+ response.setSuccessResponse(artifact);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.GET_VFCMT);
+ }
+ }
+
+ /**** PRIVATE METHODS ****/
+
+ private void updateReferenceArtifact(String userId, String VFCMTUuid, Artifact artifactObj, String reference, String requestId) throws Exception {
+ artifactObj.setDescription("updateReferenceArtifact");
+ artifactObj.setPayloadData(Base64Utils.encodeToString(reference.getBytes()));
+ baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, VFCMTUuid, artifactObj, requestId);
+ }
+
+
+ /**
+ *
+ * @param lastUpdaterUserId
+ * @param services
+ * @param userId
+ * @return
+ */
+
+ //TODO move method to ci tests
+ public List<DcaeMinimizedService> parseAndFilterServicesByUser(String lastUpdaterUserId, List<LinkedHashMap<String, String>> services, String userId) {
+ List<DcaeMinimizedService> uuids = null;
+ if (services != null) {
+ //services.stream().filter(predicate)
+ uuids = services.stream()
+ .map(x -> new DcaeMinimizedService(x.get("uuid"), x.get("name"), x.get("lastUpdaterUserId"), x.get("lifecycleState"), x.get("version"), x.get("invariantUUID")))
+ .collect(Collectors.groupingBy(DcaeMinimizedService::getInvariantUUID)).values().stream()
+ .map(p -> p.stream()
+ .sorted(Comparator.comparing(DcaeMinimizedService::getVersionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0))
+ .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifeCycleState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()))))
+ .sorted(Comparator.comparing(DcaeMinimizedService::getName)).collect(Collectors.toList());
+ }
+ return uuids;
+ }
+
+ private List<Service> filterServicesByUser(List<Service> services, String userId) {
+ return CollectionUtils.isEmpty(services) ? new ArrayList<>() : services.stream()
+ .collect(Collectors.groupingBy(Service::getInvariantUUID)).values().stream()
+ .map(p -> p.stream()
+ .sorted(Comparator.comparing(Service::versionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0))
+ .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifecycleState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()))))
+ .sorted(Comparator.comparing(Service::getName)).collect(Collectors.toList());
+ }
+
+ /**
+ *
+ * @param serviceUuid
+ * @param vfiName
+ * @param requestId
+ * @throws Exception
+ */
+ private void verifyVfiExists(String serviceUuid, String vfiName, String requestId) throws Exception {
+ ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(serviceUuid, requestId);
+ boolean isServiceContainsVfi = null != service && !CollectionUtils.isEmpty(service.getResources()) && service.getResources().stream()
+ .filter(vfi -> "VF".equals(vfi.getResoucreType()))
+ .anyMatch(vfi -> vfiName.equals(vfi.getResourceInstanceName()));
+ if (!isServiceContainsVfi) {
+ ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.VFI_FETCH_ERROR, null, serviceUuid, vfiName);
+ throw new DcaeException(HttpStatus.NOT_FOUND, responseFormat.getRequestError());
+ }
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java
new file mode 100644
index 0000000..0e1b209
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java
@@ -0,0 +1,183 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.impl.ReferenceBusinessLogic;
+import org.onap.sdc.dcae.composition.impl.VfcmtBusinessLogic;
+import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.ImportVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Resource;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class VfcmtController extends BaseController{
+
+
+ @Autowired
+ private VfcmtBusinessLogic vfcmtBusinessLogic;
+ @Autowired
+ private ReferenceBusinessLogic referenceBusinessLogic;
+
+ private static final String VFCMT = "VFCMT";
+ private static final String TEMPLATE = "Template";
+ private static final String BASE_MONITORING_TEMPLATE = "Base Monitoring Template";
+
+
+
+ /***
+ * Get one resource information
+ * @param theResourceId retrieved resource id
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/resource/{theResourceId}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity resource(@PathVariable String theResourceId, @ModelAttribute("requestId") String requestId) {
+ try {
+ ResourceDetailed resource = baseBusinessLogic.getSdcRestClient().getResource(theResourceId, requestId);
+ return new ResponseEntity<>(resource, HttpStatus.OK);
+ }catch (Exception e) {
+ return handleException(e, ApiType.GET_VFCMT);
+ }
+ }
+
+ /***
+ * Get All resources
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/getResourcesByCategory" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getResourcesByCategory(@ModelAttribute("requestId") String requestId) {
+ try {
+ List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(VFCMT, null, null, requestId);
+ return new ResponseEntity<>(resources, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_ALL_VFCMTS);
+ }
+ }
+
+ /***
+ * Get All resources by Service
+ * @return ResponseEntity
+ */
+
+ @RequestMapping(value = { "/{contextType}/{uuid}/{version}/getVfcmtsForMigration" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getVfcmtsForMigration(@RequestHeader("USER_ID") String userId,
+ @PathVariable String contextType,
+ @PathVariable String uuid,
+ @PathVariable String version,
+ @ModelAttribute("requestId") String requestId){
+
+ return vfcmtBusinessLogic.getVfcmtsForMigration(userId, contextType, uuid, version, requestId);
+ }
+
+ /***
+ * Get All resources by Monitoring Template Category
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/getResourcesByMonitoringTemplateCategory" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getResourcesByMonitoringTemplateCategory(@ModelAttribute("requestId") String requestId) {
+ try {
+ List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(VFCMT, TEMPLATE, BASE_MONITORING_TEMPLATE, requestId);
+ return new ResponseEntity<>(resources, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_ALL_VFCMTS);
+ }
+ }
+
+ /***
+ * Create new Vfcmt
+ * @param userId retrieved user ID
+ * @param request retrieved request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/createVFCMT", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity createVFCMT(@RequestHeader("USER_ID") String userId, @RequestBody CreateVFCMTRequest request, @ModelAttribute("requestId") String requestId) {
+ vfcmtBusinessLogic.addSdcMandatoryFields(request, userId);
+ try {
+ ResourceDetailed response = baseBusinessLogic.getSdcRestClient().createResource(userId, request, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "createVFCMT after post: {}", response);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.CREATE_NEW_VFCMT);
+ }
+ }
+
+ /***
+ * Create new Vfcmt from general screen
+ * @param userId retrieved user ID
+ * @param request retrieved request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/createMC", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity createMC(@RequestHeader("USER_ID") String userId, @RequestBody CreateVFCMTRequest request, @ModelAttribute("requestId") String requestId) {
+ return vfcmtBusinessLogic.createMcFromTemplate(userId, request, requestId);
+ }
+
+
+ /***
+ * Clone or import existing VFCMT and attach to selected service/resource
+ * @param userId
+ * @param request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/importMC", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity importMC(@RequestHeader("USER_ID") String userId, @RequestBody ImportVFCMTRequest request, @ModelAttribute("requestId") String requestId) {
+ return vfcmtBusinessLogic.importMC(userId, request, requestId);
+ }
+
+ /***
+ * GET a list of Monitoring Components of a service by uuid and version
+ * @param context the context type of this request
+ * @param uuid the uuid of the type requested
+ * @param version the version of the entity requested
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/{context}/{uuid}/{version}/monitoringComponents" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getMonitoringComponents(@PathVariable String context, @PathVariable String uuid, @PathVariable String version, @ModelAttribute("requestId") String requestId) {
+ try {
+ ExternalReferencesMap mcRefs = baseBusinessLogic.getSdcRestClient().getMonitoringReferences(context, uuid, version, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got monitoring references map from SDC: {}", mcRefs.values());
+ return new ResponseEntity<>(referenceBusinessLogic.fetchMonitoringComponents(mcRefs, requestId), HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_SERVICE);
+ }
+ }
+
+ @RequestMapping(value = { "/{context}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" })
+ public ResponseEntity deleteVfcmtReference(@RequestHeader("USER_ID") String userId, @PathVariable String context, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) {
+ try {
+ referenceBusinessLogic.deleteVfcmtReference(userId, context, serviceUuid, vfiName, vfcmtUuid, requestId);
+ return new ResponseEntity<>(HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.DELETE_VFCMT_REFERENCE);
+ }
+ }
+
+ @RequestMapping(value = { "/{context}/{monitoringComponentName}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" })
+ public ResponseEntity deleteVfcmtReferenceWithBlueprint(@RequestHeader("USER_ID") String userId, @PathVariable String context, @PathVariable String monitoringComponentName, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) {
+ try {
+ referenceBusinessLogic.deleteVfcmtReference(userId, context, serviceUuid, vfiName, vfcmtUuid, requestId);
+ } catch (Exception e) {
+ return handleException(e, ApiType.DELETE_VFCMT_REFERENCE);
+ }
+ return referenceBusinessLogic.deleteVfcmtReferenceBlueprint(userId, context, monitoringComponentName, serviceUuid, vfiName, vfcmtUuid, requestId);
+ }
+
+ @RequestMapping(value = { "/getVfcmtReferenceData/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getVfcmtReferenceData(@PathVariable String vfcmtUuid, @ModelAttribute String requestId) {
+ try {
+ return vfcmtBusinessLogic.getVfcmtReferenceData(vfcmtUuid, requestId);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_VFCMT);
+ }
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java
new file mode 100644
index 0000000..eaad1b0
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java
@@ -0,0 +1,77 @@
+package org.onap.sdc.dcae.composition.controller.health;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.health.ComponentsInfo;
+import org.onap.sdc.dcae.composition.restmodels.health.HealthResponse;
+import org.onap.sdc.dcae.composition.CompositionEngine;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.google.gson.Gson;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class HealthController {
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+ Gson gson = new Gson();
+
+ @Autowired
+ ToscaLabHealthState toscaLabHealthState;
+
+ @RequestMapping(value = "/healthCheck", method = RequestMethod.GET)
+ public ResponseEntity<String> healthCheck() {
+ HttpStatus httpSts = HttpStatus.OK;
+ try{
+ HealthResponse healthResponse = new HealthResponse();
+ healthResponse.setHealthCheckComponent(DcaeBeConstants.Health.APP_NAME);
+ healthResponse.setHealthCheckStatus(DcaeBeConstants.Health.UP);
+ healthResponse.setSdcVersion(CompositionEngine.getDcaeVersion());
+ healthResponse.setDescription(DcaeBeConstants.Health.OK);
+
+ List<ComponentsInfo> componentsInfoList = new ArrayList<ComponentsInfo>();
+ ComponentsInfo componentsInfo = new ComponentsInfo();
+ componentsInfo.setHealthCheckComponent(DcaeBeConstants.Health.BE);
+ componentsInfo.setHealthCheckStatus(DcaeBeConstants.Health.UP);
+ componentsInfo.setVersion(CompositionEngine.getDcaeVersion());
+ componentsInfo.setDescription(DcaeBeConstants.Health.OK);
+ componentsInfoList.add(componentsInfo);
+
+ ComponentsInfo toscaLab = new ComponentsInfo();
+ ComponentsInfo toscaLabHealthRes = toscaLabHealthState.getToscaLabHealthResponse();
+ if(toscaLabHealthRes.getHealthCheckStatus().equals(DcaeBeConstants.Health.DOWN)){
+ healthResponse.setHealthCheckStatus(DcaeBeConstants.Health.DOWN);
+ healthResponse.setDescription(toscaLabHealthRes.getHealthCheckComponent()+" is down");
+ httpSts = HttpStatus.INTERNAL_SERVER_ERROR;
+ }
+ toscaLab.setHealthCheckComponent(toscaLabHealthRes.getHealthCheckComponent());
+ toscaLab.setHealthCheckStatus(toscaLabHealthRes.getHealthCheckStatus());
+ toscaLab.setVersion(toscaLabHealthRes.getVersion());
+ toscaLab.setDescription(toscaLabHealthRes.getDescription());
+ componentsInfoList.add(toscaLab);
+
+ healthResponse.setComponentsInfo(componentsInfoList);
+ String json = gson.toJson(healthResponse, HealthResponse.class);
+
+ return new ResponseEntity<String>(json, httpSts);
+ }
+ catch(Exception e){
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occured while performing HealthCheck: {}", e.getLocalizedMessage());
+ return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java
new file mode 100644
index 0000000..609480d
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java
@@ -0,0 +1,97 @@
+package org.onap.sdc.dcae.composition.controller.health;
+
+import java.net.URI;
+import java.util.Collections;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.health.ComponentsInfo;
+import org.onap.sdc.dcae.catalog.commons.Future;
+import org.onap.sdc.dcae.catalog.commons.Http;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import com.google.gson.Gson;
+
+@Configuration
+@EnableAsync
+@EnableScheduling
+@ConfigurationProperties(prefix="blueprinter")
+public class HealthPoller {
+ private URI hcuri;
+ private String hcretrynum;
+ private Gson gson;
+
+ private OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @Autowired
+ private ToscaLabHealthState toscaLabHealthState;
+
+ public HealthPoller() {
+ super();
+ gson = new Gson();
+ }
+
+ @Scheduled(fixedDelayString="${healthpoller.fixedDelay}")
+ public void pollToscaLabHealth() {
+ ComponentsInfo toscaLabHealthRes = null;
+ ResponseEntity<String> healthRes = null;
+ try {
+ for(int i=0; i<Integer.valueOf(hcretrynum); i++){ // 3 tries
+ healthRes = sendHealthCheck();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Try #{}: {}", i, healthRes);
+ if(healthRes.getStatusCode()==HttpStatus.OK){
+ String result = (String) healthRes.getBody();
+ toscaLabHealthRes = gson.fromJson(result, ComponentsInfo.class);
+ break;
+ }
+ }
+ } catch (Exception e) {
+ toscaLabHealthRes = getNegativeHealth(e.getMessage());
+ }
+ if(toscaLabHealthRes == null){
+ toscaLabHealthRes = getNegativeHealth(healthRes.getBody() + "-" + healthRes.getStatusCode());
+ }
+ toscaLabHealthState.setToscaLabHealthResponse(toscaLabHealthRes);
+ }
+
+ private ComponentsInfo getNegativeHealth(String msg) {
+ ComponentsInfo toscaLabHealthRes = new ComponentsInfo();
+ String description = "DCAE-D BE failed while trying to fetch Tosca_Lab healthcheck. Exception: " +msg;
+ toscaLabHealthRes.setDescription(description);
+ toscaLabHealthRes.setHealthCheckComponent(DcaeBeConstants.Health.TOSCA_LAB);
+ toscaLabHealthRes.setHealthCheckStatus(DcaeBeConstants.Health.DOWN);
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), description);
+ return toscaLabHealthRes;
+ }
+
+ public ResponseEntity<String> sendHealthCheck() {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+ HttpEntity<String> entity = new HttpEntity<String>(headers);
+ return Http.exchangeSync(hcuri.toString(), HttpMethod.GET, entity, String.class, 5000);
+ }
+
+ public void setHcuri(URI hcuri) {
+ this.hcuri = hcuri;
+ }
+
+ public void setHcretrynum(String hcretrynum) {
+ this.hcretrynum = hcretrynum;
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java
new file mode 100644
index 0000000..6fe469f
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java
@@ -0,0 +1,29 @@
+package org.onap.sdc.dcae.composition.controller.health;
+
+import org.onap.sdc.dcae.composition.restmodels.health.ComponentsInfo;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+@Scope(value = "singleton")
+@Component
+public class ToscaLabHealthState {
+ private ComponentsInfo toscaLabHealthResponse;
+
+ public ToscaLabHealthState() {
+ super();
+ toscaLabHealthResponse = new ComponentsInfo();
+ toscaLabHealthResponse.setDescription("Not up yet");
+ toscaLabHealthResponse.setHealthCheckComponent(DcaeBeConstants.Health.TOSCA_LAB);
+ toscaLabHealthResponse.setHealthCheckStatus(DcaeBeConstants.Health.DOWN);
+ }
+
+ public ComponentsInfo getToscaLabHealthResponse() {
+ return toscaLabHealthResponse;
+ }
+
+ public void setToscaLabHealthResponse(ComponentsInfo toscaLabHealthResponse) {
+ this.toscaLabHealthResponse = toscaLabHealthResponse;
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java
new file mode 100644
index 0000000..48c7153
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java
@@ -0,0 +1,23 @@
+package org.onap.sdc.dcae.composition.controller.swagger;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+ @Bean
+ public Docket productApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("org.onap.sdc.dcae.composition.controller"))
+ .paths(PathSelectors.regex("/*.*"))
+ .build();
+ }
+}