summaryrefslogtreecommitdiffstats
path: root/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition
diff options
context:
space:
mode:
Diffstat (limited to 'dcaedt_be/src/main/java/org/onap/sdc/dcae/composition')
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java87
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java140
-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
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java49
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java74
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java283
17 files changed, 2529 insertions, 0 deletions
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java
new file mode 100644
index 0000000..ee8f5c6
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java
@@ -0,0 +1,87 @@
+package org.onap.sdc.dcae.composition;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.context.annotation.PropertySources;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+@Component
+@PropertySources({
+ @PropertySource(value="classpath:application-fe.properties", ignoreResourceNotFound=true),
+ @PropertySource(value="file:${jetty.base}/config/dcae-be/application.properties", ignoreResourceNotFound=true)
+})
+
+public class CompositionConfig {
+
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @Value("${compositionConfig.flowTypes}")
+ private String flowTypes;
+ @JsonIgnore
+ private Map<String, FlowType> flowTypesMap;
+ @Value("${compositionConfig.isRuleEditorActive}")
+ private boolean isRuleEditorActive;
+
+ // get flowTypes as the parsed keySet
+ public Set<String> getFlowTypes() {
+ return flowTypesMap.keySet();
+ }
+
+ @JsonProperty("isRuleEditorActive")
+ public boolean isRuleEditorActive() {
+ return isRuleEditorActive;
+ }
+
+ public Map<String, FlowType> getFlowTypesMap() {
+ return flowTypesMap;
+ }
+
+ public static class FlowType {
+
+ private String entryPointPhaseName;
+ private String lastPhaseName;
+
+ public String getEntryPointPhaseName() {
+ return entryPointPhaseName;
+ }
+
+ public void setEntryPointPhaseName(String entryPointPhaseName) {
+ this.entryPointPhaseName = entryPointPhaseName;
+ }
+
+ public String getLastPhaseName() {
+ return lastPhaseName;
+ }
+
+ public void setLastPhaseName(String lastPhaseName) {
+ this.lastPhaseName = lastPhaseName;
+ }
+ }
+
+
+ @PostConstruct
+ public void init() {
+ try {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Reading flow type definitions from configuration");
+ Type map = new TypeToken<Map<String, FlowType>>(){}.getType();
+ flowTypesMap = new Gson().fromJson(flowTypes, map);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error – Failed to read flow type definitions");
+ }
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java
new file mode 100644
index 0000000..186f3f6
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java
@@ -0,0 +1,140 @@
+package org.onap.sdc.dcae.composition;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Properties;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import javax.servlet.ServletContext;
+
+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.util.SystemProperties;
+import org.onap.sdc.dcae.filter.LoggingFilter;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrorConfiguration;
+import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+@EnableScheduling
+@SpringBootApplication
+@ComponentScan("org.onap.sdc.dcae")
+@EnableAutoConfiguration
+@PropertySource("file:${jetty.base}/config/dcae-be/application.properties")
+public class CompositionEngine extends SpringBootServletInitializer implements CommandLineRunner{
+ private static final String SPECIFICATION_VERSION = "Specification-Version";
+ @Autowired
+ ServletContext servletContext;
+ private static final String MANIFEST_FILE_NAME = "/META-INF/MANIFEST.MF";
+ private static String dcaeVersion;
+ private OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ public static void main(String[] args) {
+ SpringApplication.run(CompositionEngine.class, args);
+ }
+
+ /**
+ * Creates and returns a new instance of a {@link SystemProperties} class.
+ *
+ * @return New instance of {@link SystemProperties}.
+ */
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(CompositionEngine.class);
+ }
+
+
+ @Bean
+ public WebMvcConfigurer corsConfigurer() {
+ return new WebMvcConfigurerAdapter() {
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOrigins("*")
+ .allowedHeaders("*")
+ .allowedMethods("GET", "POST", "OPTIONS", "PUT")
+ .allowCredentials(false)
+ .maxAge(3600);
+
+ }
+ };
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+
+ ErrorConfigurationLoader errorConfigurationLoader = new ErrorConfigurationLoader(System.getProperty("jetty.base"));
+ ErrConfMgr instance = ErrConfMgr.INSTANCE;
+ InputStream inputStream = servletContext.getResourceAsStream(MANIFEST_FILE_NAME);
+
+ //setLogbackXmlLocation();
+
+ String version = null;
+ try {
+ Manifest mf = new Manifest(inputStream);
+ Attributes atts = mf.getMainAttributes();
+ version = atts.getValue(SPECIFICATION_VERSION);
+ if (version == null || version.isEmpty()) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "failed to read DCAE version from MANIFEST.");
+ } else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "DCAE version from MANIFEST is {}", version);
+ dcaeVersion = version;
+ }
+
+ } catch (IOException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "failed to read DCAE version from MANIFEST: {}", e.getMessage());
+ }
+
+ }
+
+ private void setLogbackXmlLocation() throws Exception {
+ String jettyBase = System.getProperty("config.home");
+ Properties props = System.getProperties();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Current System Properties are: {}", props);
+ if (jettyBase == null) {
+ String msg = "Couldn't resolve config.home environmental variable";
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new Exception(msg + ". Failed to configure logback.xml location... aborting.");
+ }
+ String logbackXmlLocation = jettyBase+"/dcae-be/logback.xml";
+ props.setProperty("logback.configurationFile", logbackXmlLocation);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Successfuly set the logback.xml location to {}", logbackXmlLocation);
+ }
+
+ @Bean
+ public FilterRegistrationBean contextLifecycleFilter() {
+ Collection<String> urlPatterns = new ArrayList<>();
+ urlPatterns.add("/*");
+
+ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new LoggingFilter());
+ filterRegistrationBean.setUrlPatterns(urlPatterns);
+
+ return filterRegistrationBean;
+ }
+
+ public static String getDcaeVersion() {
+ return dcaeVersion;
+ }
+
+}
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();
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java
new file mode 100644
index 0000000..f26c885
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java
@@ -0,0 +1,49 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.dcae.client.ISdcClient;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+
+@Component
+public class BaseBusinessLogic {
+ @Autowired
+ protected ISdcClient sdcRestClient;
+
+ protected static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ protected static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ public ISdcClient getSdcRestClient() {
+ return sdcRestClient;
+ }
+
+ void setSdcRestClient(ISdcClient sdcRestClient) {
+ this.sdcRestClient = sdcRestClient;
+ }
+
+ Artifact cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, String requestId) throws Exception {
+ Artifact cloned = SdcRestClientUtils.generateDeploymentArtifact(artifactToClone.getArtifactDescription(), artifactToClone.getArtifactName(), artifactToClone.getArtifactType(), artifactToClone.getArtifactLabel(), payload.getBytes());
+ return sdcRestClient.createResourceArtifact(userId, targetId, cloned, requestId);
+ }
+
+ public void cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, Artifact artifactToOverride, String requestId) throws Exception{
+ if (null != artifactToOverride) {
+ artifactToOverride.setDescription(artifactToOverride.getArtifactDescription());
+ artifactToOverride.setPayloadData(Base64Utils.encodeToString(payload.getBytes()));
+ sdcRestClient.updateResourceArtifact(userId, targetId, artifactToOverride, requestId);
+ } else {
+ cloneArtifactToTarget(userId, targetId, payload, artifactToClone, requestId);
+ }
+ }
+
+ Artifact findArtifactDataByArtifactName(ResourceDetailed vfcmt, String artifactName) {
+ return null == vfcmt ? null : CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream()
+ .filter(p -> artifactName.equals(p.getArtifactName())).findAny().orElse(null);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java
new file mode 100644
index 0000000..d229b67
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java
@@ -0,0 +1,74 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceInstance;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ServiceDetailed;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.utils.Normalizers;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+import static org.springframework.util.CollectionUtils.isEmpty;
+
+@Component
+public class ReferenceBusinessLogic extends BaseBusinessLogic {
+
+ public ResponseEntity deleteVfcmtReferenceBlueprint(String userId, String context, String monitoringComponentName, String serviceUuid, String vfiName, String vfcmtUuid, String requestId) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to delete blueprint, monitoringComponentName = {}, vfiName = {}", monitoringComponentName, vfiName);
+ try {
+ String normalizedVfiName = Normalizers.normalizeComponentInstanceName(vfiName);
+ ServiceDetailed serviceDetailed = sdcRestClient.getService(serviceUuid, requestId);
+ Optional<ResourceInstance> resourceInstance = serviceDetailed.getResources().stream().filter(item -> item.getResourceInstanceName().equalsIgnoreCase(vfiName)).findAny();
+ if (resourceInstance.isPresent() && resourceInstance.get().getArtifacts() != null) {
+ Optional<Artifact> artifact = resourceInstance.get().getArtifacts().stream().filter(item -> item.getArtifactName().contains(monitoringComponentName)).findAny();
+ artifact.ifPresent(artifact1 -> sdcRestClient.deleteInstanceResourceArtifact(userId, context, serviceUuid, normalizedVfiName, artifact1.getArtifactUUID(), requestId));
+ }
+ } catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Failed to delete blueprint with serviceUuid {}, vfcmtUuid . message: {} ", serviceUuid, vfcmtUuid, e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_BLUEPRINT_FAILED);
+ }
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ public void deleteVfcmtReference(String userId, String context, String serviceUuid, String vfiName, String vfcmtUuid, String requestId) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to delete vfcmt reference, vfiName = {}", vfiName);
+ String normalizedVfiName = Normalizers.normalizeComponentInstanceName(vfiName);
+ sdcRestClient.deleteExternalMonitoringReference(userId, context, serviceUuid, normalizedVfiName, vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished to delete vfcmt reference. serviceUuid {}, vfcmtUuid {}", serviceUuid, vfcmtUuid);
+ }
+
+ // 1806 US381853 Return a list of monitoring components by external reference id. Support partial success
+ public Map<String, List<MonitoringComponent>> fetchMonitoringComponents(ExternalReferencesMap mcRefs, String requestId) {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to fetch monitoring components metadata for vfis {}", mcRefs.keySet());
+ Map<String, List<MonitoringComponent>> result = new LinkedHashMap<>();
+ List<MonitoringComponent> monitoringComponents = Collections.synchronizedList(new ArrayList<>());
+ List<MonitoringComponent> unavailable = Collections.synchronizedList(new ArrayList<>());
+ mcRefs.entrySet().parallelStream().forEach(entry ->
+ entry.getValue().parallelStream().forEach(id -> {
+ try{
+ monitoringComponents.add(new MonitoringComponent(getSdcRestClient().getResource(id, requestId), entry.getKey()));
+ } catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Failed to fetch monitoring component with uuid {}. message: {} ", id, e);
+ unavailable.add(new MonitoringComponent(id, entry.getKey(), "unavailable"));
+ }
+
+ })
+ );
+ result.put("monitoringComponents", monitoringComponents);
+ if(!isEmpty(unavailable)) {
+ result.put("unavailable", unavailable);
+ }
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished fetching monitoring components metadata for vfis {}", mcRefs.keySet());
+ return result;
+ }
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java
new file mode 100644
index 0000000..e68a8ee
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java
@@ -0,0 +1,283 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.lang.StringUtils;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.*;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+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.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.utils.SdcRestClientUtils;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT;
+import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.findState;
+
+@Component
+public class VfcmtBusinessLogic extends BaseBusinessLogic {
+
+ private static final String VFCMT = "VFCMT";
+ private static final String TEMPLATE = "Template";
+ private static final String MONITORING_TEMPLATE = "Monitoring Template";
+ private static final String DEFAULTICON = "defaulticon";
+ private static final String VENDOR_NAME = "vendorName";
+ private static final String VENDOR_RELEASE = "vendorRelease";
+
+ public ResponseEntity createMcFromTemplate(String userId, CreateVFCMTRequest request, String requestId) {
+ if(!validateMCRequestFields(request)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Missing information");
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_CONTENT);
+ }
+ return cloneMcAndAddServiceReference(userId, request, requestId);
+ }
+
+ //1806 US388513 collect existing VFCMT data - flowType from cdump artifact and external reference from svc_reference artifact. If cdump not found - return error
+
+ public ResponseEntity getVfcmtReferenceData(String vfcmtUuid, String requestId) throws Exception {
+ ResourceDetailed vfcmt = sdcRestClient.getResource(vfcmtUuid, requestId);
+ Artifact artifactData = findCdumpArtifactData(vfcmt);
+ if(null == artifactData) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"No composition found on vfcmt {}", vfcmtUuid);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName());
+ }
+ VfcmtData vfcmtData = new VfcmtData(vfcmt);
+ //fetch cdump payload
+ String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactData.getArtifactUUID(), requestId);
+ //extract and set flowType from cdump payload
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Looking for flowType definition in cdump");
+ vfcmtData.setFlowType(StringUtils.substringBetween(payload,"\"flowType\":\"","\""));
+ //find svc_reference
+ artifactData = findArtifactDataByArtifactName(vfcmt, DcaeBeConstants.Composition.fileNames.SVC_REF);
+ if(null != artifactData) {
+ //fetch svc_reference payload
+ payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactData.getArtifactUUID(), requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Looking for attached service and vfi info in svc_reference");
+ //extract and set serviceUuid from svc_reference payload
+ vfcmtData.setServiceUuid(StringUtils.substringBefore(payload, "/"));
+ //extract and set vfiName from svc_reference payload
+ vfcmtData.setVfiName(StringUtils.substringAfterLast(payload, "/"));
+ }
+ return new ResponseEntity<>(vfcmtData, HttpStatus.OK);
+ }
+
+
+ //1806 US388525 import or clone VFCMT - always pass the flowType - update will only take place if missing from cdump
+ public ResponseEntity importMC(String userId, ImportVFCMTRequest request, String requestId) {
+ if(!validateMCRequestFields(request)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Missing information");
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_CONTENT);
+ }
+ // option 1 - clone
+ if(request.isCloneVFCMT()) {
+ return cloneMcAndAddServiceReference(userId, request, requestId);
+ }
+
+ ResourceDetailed vfcmt = null;
+ boolean undoCheckoutOnFailure = false;
+ // fetch vfcmt and cdump
+ try {
+ vfcmt = sdcRestClient.getResource(request.getTemplateUuid(), requestId);
+ Artifact cdumpArtifactData = fetchCdumpAndSetFlowType(vfcmt, request.getFlowType(), requestId);
+ if (null == cdumpArtifactData) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "No cdump found for monitoring component {}", vfcmt.getUuid());
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName());
+ }
+ String cdumpPayload = cdumpArtifactData.getPayloadData();
+
+ // option 2 - edit original cdump - requires check out
+ if(request.isUpdateFlowType()) {
+ if(DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(vfcmt.getLifecycleState())) {
+ vfcmt = sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKOUT.name(), "checking out VFCMT", requestId);
+ undoCheckoutOnFailure = true;
+ }
+ cdumpArtifactData.setDescription("updating flowType on cdump");
+ cdumpArtifactData.setPayloadData(Base64Utils.encodeToString(cdumpPayload.getBytes()));
+ sdcRestClient.updateResourceArtifact(userId, vfcmt.getUuid(), cdumpArtifactData, requestId);
+ }
+ // option 3 - update service reference only
+ updateReferenceToService(userId, request, vfcmt.getUuid(), requestId);
+ if(DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(vfcmt.getLifecycleState())) {
+ // this will not throw an exception
+ checkinVfcmtAfterClone(userId, vfcmt, requestId);
+ }
+ return new ResponseEntity<>(buildVfcmtAndCdumpResponse(vfcmt, request.getVfiName(), request.getFlowType(), cdumpPayload), HttpStatus.OK);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed updating Monitoring Component:{}", e.getMessage());
+ if(undoCheckoutOnFailure) {
+ rollBack(userId, vfcmt, requestId);
+ }
+ return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.CREATE_NEW_VFCMT);
+ }
+
+ }
+
+ private boolean validateMCRequestFields(CreateVFCMTRequest request) {
+ return Stream.of(request.getFlowType(), request.getTemplateUuid(), request.getName(), request.getDescription(), request.getContextType(), request.getServiceUuid(), request.getVfiName())
+ .allMatch(StringUtils::isNotBlank);
+ }
+
+ private void updateReferenceToService(String userId, CreateVFCMTRequest request, String newVfcmtUuid, String requestId) {
+ String serviceUuid = request.getServiceUuid();
+ String vfiName = request.getVfiName();
+
+ debugLogger.log(LogLevel.INFO, this.getClass().getName(),"About to update service {}/{} to monitoring component {} ", serviceUuid, vfiName, request.getName());
+
+ sdcRestClient.addExternalMonitoringReference(userId, request, new ReferenceUUID(newVfcmtUuid), requestId);
+
+ }
+
+ private void rollBack(String userId, ResourceDetailed newVfcmt, String requestId) {
+ if (null != newVfcmt) {
+ try {
+ getSdcRestClient().changeResourceLifecycleState(userId, newVfcmt.getUuid(), LifecycleOperationType.UNDO_CHECKOUT.getValue(), "DCAE rollback", requestId);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed rolling back Monitoring Component. ID:{}", newVfcmt.getUuid());
+ debugLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed rolling back Monitoring Component:{}", e);
+ }
+ }
+ }
+
+ private ResponseEntity cloneMcAndAddServiceReference(String userId, CreateVFCMTRequest request, String requestId) {
+ addSdcMandatoryFields(request, userId);
+ ResourceDetailed newVfcmt = null;
+ try {
+ // Retrieve the Template VFCMT from SDC - use the template UUID provided from UI
+ ResourceDetailed templateMC = sdcRestClient.getResource(request.getTemplateUuid(), requestId);
+ // Download the CDUMP file from the template VFCMT
+ Artifact cdumpArtifactData = fetchCdumpAndSetFlowType(templateMC, request.getFlowType(), requestId);
+ if (null == cdumpArtifactData) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"No cdump found for template {} while creating monitoring component", templateMC.getUuid());
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", templateMC.getName());
+ }
+ newVfcmt = sdcRestClient.createResource(userId, request, requestId);
+ // The cdump has the original template id. we need to replace it with the new vfcmt id
+ String newVfcmtUuid = newVfcmt.getUuid();
+ String cdumpPayload = cdumpArtifactData.getPayloadData().replaceAll(templateMC.getUuid(), newVfcmtUuid);
+
+ // Upload it to newly created VFCMT
+ cloneArtifactToTarget(userId, newVfcmtUuid, cdumpPayload, cdumpArtifactData, requestId);
+ cloneRuleArtifacts(userId, templateMC, newVfcmtUuid, requestId);
+ createReferenceArtifact(userId, request, newVfcmtUuid, requestId);
+ updateReferenceToService(userId, request, newVfcmtUuid, requestId);
+
+ // this will not throw an exception
+ checkinVfcmtAfterClone(userId, newVfcmt, requestId);
+ return new ResponseEntity<>(buildVfcmtAndCdumpResponse(newVfcmt, request.getVfiName(), request.getFlowType(), cdumpPayload), HttpStatus.OK);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed creating Monitoring Component:{}", e.getMessage());
+ rollBack(userId, newVfcmt, requestId);
+ return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.CREATE_NEW_VFCMT);
+ }
+ }
+
+ private CreateMcResponse buildVfcmtAndCdumpResponse(ResourceDetailed vfcmt, String vfiName, String flowType, String cdumpPayload) throws IOException {
+ return new CreateMcResponse(new VfcmtData(vfcmt, vfiName, flowType), new ObjectMapper().readValue(cdumpPayload, Object.class));
+ }
+
+ private void checkinVfcmtAfterClone(String userId, ResourceDetailed vfcmt, String requestId) {
+ try {
+ vfcmt = sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKIN.getValue(), "check in after clone", requestId);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed to check in Monitoring Component: {}. message: {}", vfcmt.getUuid(), e);
+ }
+ }
+
+
+ private Artifact findCdumpArtifactData(ResourceDetailed vfcmt) {
+ return findArtifactDataByArtifactName(vfcmt, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ }
+
+ private void cloneRuleArtifacts(String userId, ResourceDetailed templateMC, String newVfcmtUuid, String requestId) throws Exception {
+ // handle rule artifacts using java 7 for-loop - exception propagation to calling method
+ for(Artifact artifact : templateMC.getArtifacts()) {
+ if(artifact.getArtifactName().endsWith(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX)) {
+ cloneArtifactToTarget(userId, newVfcmtUuid, sdcRestClient.getResourceArtifact(templateMC.getUuid(), artifact.getArtifactUUID(), requestId), artifact, requestId);
+ }
+ }
+ }
+
+ // fetch the vfcmt cdump artifact payload and insert the flowType. Return the artifact with updated payload or null (artifact doesn't exist)
+ private Artifact fetchCdumpAndSetFlowType(ResourceDetailed vfcmt, String flowType, String requestId) throws Exception {
+ Artifact cdumpArtifactData = findCdumpArtifactData(vfcmt);
+ if (null != cdumpArtifactData) {
+ String cdumpPayload = sdcRestClient.getResourceArtifact(vfcmt.getUuid(), cdumpArtifactData.getArtifactUUID(), requestId);
+ // Add flowType data to cdump if provided
+ if(!cdumpPayload.contains("\"flowType\":\"") && StringUtils.isNotBlank(flowType)) {
+ cdumpPayload = cdumpPayload.replaceFirst("\\{", "{\"flowType\":\"" + flowType + "\",");
+ }
+ cdumpArtifactData.setPayloadData(cdumpPayload);
+ }
+ return cdumpArtifactData;
+ }
+
+ // backward compatibility (very backward)
+ private void createReferenceArtifact(String userId, CreateVFCMTRequest request, String newVfcmtUuid, String requestId) throws Exception {
+ String referencePayload = request.getServiceUuid() + "/resources/" + request.getVfiName();
+ Artifact refArtifact = SdcRestClientUtils.generateDeploymentArtifact("createReferenceArtifact", DcaeBeConstants.Composition.fileNames.SVC_REF, ArtifactType.DCAE_TOSCA.name(), "servicereference", referencePayload.getBytes());
+ sdcRestClient.createResourceArtifact(userId, newVfcmtUuid, refArtifact, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} created with content: {}", DcaeBeConstants.Composition.fileNames.SVC_REF, referencePayload);
+ }
+
+ public ResponseEntity getVfcmtsForMigration(String userId, String contextType, String uuid, String version,
+ String requestId) {
+ List<Resource> resources;
+ ExternalReferencesMap connectedVfcmts;
+ try {
+ connectedVfcmts = getSdcRestClient().getMonitoringReferences(contextType, uuid, version, requestId);
+ resources = getSdcRestClient().getResources(VFCMT, TEMPLATE, MONITORING_TEMPLATE, requestId);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Exception getVfcmtsForMigration {}", e);
+ debugLogger.log(LogLevel.DEBUG,this.getClass().getName(),"Exception getVfcmtsForMigration {}", e);
+ return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_ALL_VFCMTS);
+ }
+
+ List<Resource> vfcmts = resources.stream()
+ .filter(resource -> notCheckedOutOrMine(userId, resource))
+ .filter(resource -> !connected(resource, connectedVfcmts))
+ .collect(Collectors.toList());
+ return new ResponseEntity<>(vfcmts, HttpStatus.OK);
+ }
+
+ private boolean connected(Resource resource, ExternalReferencesMap connectedVfcmts){
+ return connectedVfcmts.values().stream().anyMatch(p -> p.contains(resource.getUuid()));
+ }
+
+ private boolean notCheckedOutOrMine(String userId, Resource resource) {
+ // if the resource belongs to this user then it is kosher
+ // or if it doesn't belong to the user check the lifecycle state is checked out
+
+ return resource.getLastUpdaterUserId().equalsIgnoreCase(userId) ||
+ NOT_CERTIFIED_CHECKOUT != findState(resource.getLifecycleState());
+ }
+
+
+ public void addSdcMandatoryFields(CreateVFCMTRequest createRequest, String user) {
+ createRequest.setContactId(user);
+ createRequest.setIcon(DEFAULTICON);
+ createRequest.setResourceType(VFCMT);
+ createRequest.setVendorName(VENDOR_NAME);
+ createRequest.setVendorRelease(VENDOR_RELEASE);
+ if (StringUtils.isBlank(createRequest.getCategory())) {
+ createRequest.setCategory(TEMPLATE);
+ }
+ if (StringUtils.isBlank(createRequest.getSubcategory())) {
+ createRequest.setSubcategory(MONITORING_TEMPLATE);
+ }
+ createRequest.setTags(new String[]{createRequest.getName()});
+ }
+
+}