diff options
author | mukesh.paliwal1@huawei.com <mukesh.paliwal1@huawei.com> | 2020-07-30 15:40:38 +0530 |
---|---|---|
committer | mukesh.paliwal1@huawei.com <mukesh.paliwal1@huawei.com> | 2020-07-30 15:40:38 +0530 |
commit | 0ac251b9e195871663f40d88c4b8ccd010d64966 (patch) | |
tree | dce3d9089b271b68cb2e427e7b23b7c194b7e80c /bpmn/mso-infrastructure-bpmn/src/main | |
parent | 852b16f2d60356becf222d2360ac85c977601b8c (diff) |
Dynamic hot onboarding bpmn-infra
Issue-ID: SO-3104
Signed-off-by: mukesh.paliwal1@huawei.com <mukesh.paliwal1@huawei.com>
Change-Id: If91d9141d9273f926145301a25a8dcec6ac5f8bf
Diffstat (limited to 'bpmn/mso-infrastructure-bpmn/src/main')
7 files changed, 1021 insertions, 54 deletions
diff --git a/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/common/workflow/service/WorkflowOnboardingSupport.java b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/common/workflow/service/WorkflowOnboardingSupport.java new file mode 100644 index 0000000000..d3539f88e6 --- /dev/null +++ b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/common/workflow/service/WorkflowOnboardingSupport.java @@ -0,0 +1,526 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Modifications Copyright (c) 2019 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.bpmn.common.workflow.service; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.activation.DataHandler; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; + +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.onap.so.db.catalog.beans.NetworkRecipe; +import org.onap.so.db.catalog.beans.NetworkResource; +import org.onap.so.db.catalog.beans.ServiceRecipe; +import org.onap.so.db.catalog.client.CatalogDbClient; +import org.onap.so.rest.catalog.beans.Service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.CrossOrigin; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.minidev.json.JSONObject; +import org.onap.so.db.catalog.beans.VnfRecipe; +import org.onap.so.db.catalog.beans.VnfResource; + +/** + * + * @version 1.0 Support SO workflow/script onboarding and recipe update + */ +@Path("/hotmanagement") +@Api(value = "/hotmanage", description = "Provides support for the workflow hot onboarding and recipe update") +@Provider +@Component +public class WorkflowOnboardingSupport extends ProcessEngineAwareService { + + protected static final Logger logger = LoggerFactory.getLogger(WorkflowOnboardingSupport.class); + protected static final long DEFAULT_WAIT_TIME = 60000; // default wait time + private static final String SERVICE = "SERVICE"; + private static final String NETWORK = "NETWORK"; + private static final String VNF = "VNF"; + + @Autowired + private CatalogDbClient catalogDbClient; + + /** + * Get all service recipes. + * + * @return + */ + @GET + @ApiOperation(value = "Get all service recipes", notes = "Get all service recipes") + @Path("/serviceRecipes") + public Response getServiceRecipes() { + List<ServiceRecipe> serviceRecipes = catalogDbClient.getServiceRecipes(); + List<Service> services = catalogDbClient.getServices(); + Map<String, String> idToName = new HashMap<String, String>(); + for (Service service : services) { + idToName.put(service.getModelVersionId(), service.getModelName()); + } + Map<String, String> flowToName = new HashMap<String, String>(); + Map<String, List<String>> packages = getPackages(); + for (Entry<String, List<String>> entry : packages.entrySet()) { + for (String flow : entry.getValue()) { + flowToName.put(flow, entry.getKey()); + } + } + Map<String, List<Map<String, String>>> mapServiceRecipes = new HashMap<String, List<Map<String, String>>>(); + List<Map<String, String>> recipeList = new ArrayList<Map<String, String>>(); + for (ServiceRecipe serviceRecipe : serviceRecipes) { + Map<String, String> recipeObj = new HashMap<String, String>(); + recipeObj.put("id", String.valueOf(serviceRecipe.getId())); + recipeObj.put("modelVersionId", serviceRecipe.getServiceModelUUID()); + recipeObj.put("modelName", idToName.get(serviceRecipe.getServiceModelUUID())); + recipeObj.put("operation", serviceRecipe.getAction()); + recipeObj.put("orchestrationPackageName", flowToName.get(serviceRecipe.getOrchestrationUri())); + recipeObj.put("orchestrationFlow", serviceRecipe.getOrchestrationUri()); + recipeList.add(recipeObj); + } + mapServiceRecipes.put("serviceRecipes", recipeList); + String resp = JSONObject.toJSONString(mapServiceRecipes); + + return Response.status(200).header("Access-Control-Allow-Origin", "*").entity(resp).build(); + } + + /** + * Add new recipe for service + * + * @param request + * @return + */ + @SuppressWarnings("unchecked") + @POST + @Path("/serviceRecipes") + @ApiOperation(value = "Add a new service recipe", notes = "Add a new service recipe") + @Produces("application/json") + @Consumes("application/json") + public Response addServiceRecipDese(String request) { + Map<String, String> mapRecipeInfo; + ObjectMapper mapper = new ObjectMapper(); + + try { + + try { + mapRecipeInfo = mapper.readValue(request, Map.class); + + } catch (Exception e) { + logger.debug("Mapping of request to JSON object failed : ", e); + return Response.status(200).header("Access-Control-Allow-Origin", "*").build(); + } + + String type = mapRecipeInfo.get("modelType"); + String modelVersionId = mapRecipeInfo.get("modelVersionId"); + String action = mapRecipeInfo.get("operation"); + String orchestrationFlow = "/mso/async/services/" + mapRecipeInfo.get("orchestrationFlow"); + String modelName = mapRecipeInfo.get("modelName"); + String description = action + " orchestration flow for template " + mapRecipeInfo.get("modelName"); + + String[] validTypes = { SERVICE, NETWORK, VNF }; + + if (org.springframework.util.StringUtils.isEmpty(type) + || !Arrays.asList(validTypes).contains(type.toUpperCase())) { + return Response.status(200).header("Access-Control-Allow-Origin", "*") + .entity("{\"errMsg\":\"type is invalid.\"}").build(); + + } + int assignedId = 0; + boolean isModelVersionExists = false; + Object[] conflictAndIdCheck; + + if (type.equalsIgnoreCase(SERVICE)) { + isModelVersionExists = isServiceModelVersionIdExists(modelVersionId); + if (!isModelVersionExists) { + return Response.status(200).header("Access-Control-Allow-Origin", "*") + .entity("{\"errMsg\":\"The service template does not exist.\"}").build(); + } + + conflictAndIdCheck = isServiceActionConflict(modelVersionId, action); + if ((boolean) conflictAndIdCheck[0]) { + return Response.status(200).header("Access-Control-Allow-Origin", "*").entity( + "{\"errMsg\":\"The recipe for this action of the service template already exists.\"}") + .build(); + } + assignedId = (int) conflictAndIdCheck[1] + 1; + ServiceRecipe serviceRecipe = new ServiceRecipe(); + serviceRecipe.setId(assignedId); + serviceRecipe.setServiceModelUUID(modelVersionId); + serviceRecipe.setAction(action); + serviceRecipe.setOrchestrationUri(orchestrationFlow); + serviceRecipe.setRecipeTimeout(180); + serviceRecipe.setDescription(description); + catalogDbClient.postServiceRecipe(serviceRecipe); + } else if (type.equalsIgnoreCase(NETWORK)) { + + isModelVersionExists = isNetworkVersionIdValid(modelVersionId); + if (!isModelVersionExists) { + return Response.status(200).header("Access-Control-Allow-Origin", "*") + .entity("{\"errMsg\":\"The network template does not exist.\"}").build(); + } + + conflictAndIdCheck = isNetworkActionConflict(modelVersionId, action); + if ((boolean) conflictAndIdCheck[0]) { + return Response.status(200).header("Access-Control-Allow-Origin", "*").entity( + "{\"errMsg\":\"The recipe for this action of the network template already exists.\"}") + .build(); + } + + assignedId = (int) conflictAndIdCheck[1] + 1; + NetworkRecipe nwrecipe = new NetworkRecipe(); + nwrecipe.setId(assignedId); + nwrecipe.setModelName(modelName); + nwrecipe.setAction(action); + nwrecipe.setOrchestrationUri(orchestrationFlow); + nwrecipe.setDescription(description); + nwrecipe.setRecipeTimeout(180); + nwrecipe.setVersionStr(modelVersionId); + catalogDbClient.postNetworkRecipe(nwrecipe); + + } else if (type.equalsIgnoreCase(VNF)) { + + isModelVersionExists = isVnfVersionIdValid(modelVersionId); + if (!isModelVersionExists) { + return Response.status(200).header("Access-Control-Allow-Origin", "*") + .entity("{\"errMsg\":\"The Vnf template does not exist.\"}").build(); + + } + + conflictAndIdCheck = isVfActionConflict(modelVersionId, action); + if ((boolean) conflictAndIdCheck[0]) { + return Response.status(200).header("Access-Control-Allow-Origin", "*") + .entity("{\"errMsg\":\"The recipe for this action of the vnf template already exists.\"}") + .build(); + } + + assignedId = (int) conflictAndIdCheck[1] + 1; + VnfRecipe vnfRecipe = new VnfRecipe(); + vnfRecipe.setId(assignedId); + vnfRecipe.setAction(action); + vnfRecipe.setDescription(description); + vnfRecipe.setVersionStr(modelVersionId); + vnfRecipe.setOrchestrationUri(orchestrationFlow); + vnfRecipe.setRecipeTimeout(180); + catalogDbClient.postVnfRecipe(vnfRecipe); + + } + + mapRecipeInfo.put("id", String.valueOf(assignedId)); + } catch (Exception e) { + logger.debug("WorkflowOnboardingSupport addServiceRecipDese error {} : ", e); + return Response.status(200).header("Access-Control-Allow-Origin", "*") + .entity("{\"errMsg\":\"Unable to process.\"}").build(); + } + String resp = JSONObject.toJSONString(mapRecipeInfo); + return Response.status(201).header("Access-Control-Allow-Origin", "*").entity(resp).build(); + } + + private boolean isServiceModelVersionIdExists(String modelVersionId) { + List<Service> services = catalogDbClient.getServices(); + boolean isExists = false; + for(Service service: services) { + if(service.getModelVersionId().equals(modelVersionId)){ + isExists = true; + break; + } + } + return isExists; + } + + private Object[] isServiceActionConflict(String modelVersionId,String action) { + List<ServiceRecipe> serviceRecipes = catalogDbClient.getServiceRecipes(); + boolean isConflict = false; + Object[] data= new Object[2]; + int maxId = serviceRecipes.get(0)!=null? serviceRecipes.get(0).getId(): 1; + for (ServiceRecipe recipe : serviceRecipes) { + maxId = recipe.getId() > maxId ? recipe.getId() : maxId; + if (recipe.getServiceModelUUID().equals(modelVersionId) + && recipe.getAction().equals(action)) { + isConflict = true; + } + } + data[0]=isConflict; + data[1]=maxId; + return data; + } + + private Object[] isNetworkActionConflict(String modelVersionId,String action) { + List<NetworkRecipe> recipes = catalogDbClient.getNetworkRecipes(); + boolean isConflict = false; + Object[] data= new Object[2]; + int maxId = recipes.get(0)!=null ? recipes.get(0).getId() : 1; + for (NetworkRecipe recipe : recipes) { + maxId = recipe.getId() > maxId ? recipe.getId() : maxId; + if (recipe.getVersionStr().equals(modelVersionId) + && recipe.getAction().equals(action)) { + isConflict = true; + + } + + } + data[0]=isConflict; + data[1]=maxId; + return data; + } + + private Object[] isVfActionConflict(String modelVersionId,String action) { + List<VnfRecipe> vnfRecipes = catalogDbClient.getVnfRecipes(); + boolean isConflict = false; + Object[] data= new Object[2]; + int maxId = vnfRecipes.get(0) !=null ? vnfRecipes.get(0).getId() : 1; + for (VnfRecipe recipe : vnfRecipes) { + maxId = recipe.getId() > maxId ? recipe.getId() : maxId; + if (recipe.getVersionStr().equals(modelVersionId) + && recipe.getAction().equals(action)) { + isConflict = true; + } + } + data[0]=isConflict; + data[1]=maxId; + return data; + } + + + + private boolean isNetworkVersionIdValid(String modelVersionId) { + List<NetworkResource> networkResources = catalogDbClient.getNetworkResources(); + boolean isExists = false; + for(NetworkResource networkResource: networkResources) { + if(networkResource.getModelVersion().equals(modelVersionId)){ + isExists = true; + break; + } + } + return isExists; + } + + private boolean isVnfVersionIdValid(String modelVersionId) { + List<VnfResource> vnfResources = catalogDbClient.getVnfResources(); + boolean isExists = false; + for(VnfResource vnfResource: vnfResources) { + if(vnfResource.getModelVersion().equals(modelVersionId)){ + isExists = true; + break; + } + } + return isExists; + } + + /** + * delete service recipe + * + * @param request the body of the request + * @return + */ + @DELETE + @Path("/serviceRecipes/{id}") + @ApiOperation(value = "delete a service recipe", notes = "delete a service recipe") + @Produces("application/json") + @Consumes("application/json") + public Response delServiceRecipe(String request, @PathParam("id") String id) { + catalogDbClient.deleteServiceRecipe(id); + return Response.status(200).header("Access-Control-Allow-Origin", "*").build(); + } + + /** + * Get service templates + * + * @return + */ + @GET + @ApiOperation(value = "query all service templates", notes = "query all service templates") + @Path("/serviceTemplates") + public Response getServices() { + List<Service> services = catalogDbClient.getServices(); + Map<String, List<Map<String, String>>> mapServices = new HashMap<String, List<Map<String, String>>>(); + List<Map<String, String>> serviceList = new ArrayList<Map<String, String>>(); + for (Service service : services) { + Map<String, String> serviceObj = new HashMap<String, String>(); + serviceObj.put("modelInvariantId", service.getModelInvariantId()); + serviceObj.put("modelVersionId", service.getModelVersionId()); + serviceObj.put("modelName", service.getModelName()); + serviceList.add(serviceObj); + } + mapServices.put("services", serviceList); + String resp = JSONObject.toJSONString(mapServices); + return Response.status(200).header("Access-Control-Allow-Origin", "*").entity(resp).build(); + } + + /** + * Get all workflow packages including all bpmn infos. + * + * @return + */ + @GET + @ApiOperation(value = "Get all workflow packages", notes = "Get all workflow packages") + @Path("/workflowPackages") + public Response getWorkflowPackages() { + Map<String, List<String>> packages = getPackages(); + List<Map<String, Object>> packageList = new ArrayList<Map<String, Object>>(); + for (Entry<String, List<String>> entry : packages.entrySet()) { + Map<String, Object> packageInfo = new HashMap<String, Object>(); + packageInfo.put("packageName", entry.getKey()); + packageInfo.put("orchestrationFlows", entry.getValue()); + packageList.add(packageInfo); + } + Map<String, List<Map<String, Object>>> mapPackages = new HashMap<String, List<Map<String, Object>>>(); + mapPackages.put("workflowPackages", packageList); + String resp = JSONObject.toJSONString(mapPackages); + return Response.status(200).header("Access-Control-Allow-Origin", "*").entity(resp).build(); + } + + /** + * Get the package info from the local system. + * + * @return + */ + private Map<String, List<String>> getPackages() { + String pkgDir = "/camunda/webapps/"; + File packageFile = new File(pkgDir); + String[] packageList = packageFile.list(); + Map<String, List<String>> mapPackage = new HashMap<String, List<String>>(); + for (String strPkgFileName : packageList) { + if (strPkgFileName.endsWith(".war")) { + String fileName = strPkgFileName.substring(0, strPkgFileName.length() - ".war".length()); + String flowsDir = pkgDir + fileName + "/WEB-INF/classes/"; + if ("mso".equals(fileName)) { + flowsDir = pkgDir + fileName + "/WEB-INF/classes/process/"; + } + File flowFile = new File(flowsDir); + if (!flowFile.isDirectory()) { + continue; + } + String[] flowFileNames = flowFile.list(); + List<String> orchestrationFlows = new ArrayList<String>(); + for (String flowFileName : flowFileNames) { + if (flowFileName.endsWith(".bpmn")) { + orchestrationFlows.add(flowFileName.substring(0, flowFileName.length() - ".bpmn".length())); + } + } + mapPackage.put(fileName, orchestrationFlows); + } + } + return mapPackage; + } + + /** + * delete workflow package + * + * @param request the body of the request + * @return + */ + @DELETE + @Path("/workflowPackages/{packageName}") + @ApiOperation(value = "delete a service recipe", notes = "delete a service recipe") + @Produces("application/json") + @Consumes("application/json") + public Response deleteWorkflowPackage(@PathParam("packageName") String packageName) { + String pkgDir = "/camunda/webapps/"; + File packageFile = new File(pkgDir + packageName + ".war"); + if (packageFile.isFile()) { + packageFile.delete(); + } + return Response.status(200).header("Access-Control-Allow-Origin", "*").build(); + } + + /** + * upload a workflow package to the server + * + * @param uploadInputStream upload stream + * @param disposition + * @return + */ + @POST + @Path("/workflowPackages/onboard") + @Consumes("multipart/form-data") + @Produces("application/json") + @ApiOperation(value = "Add a new service recipe", notes = "Add a new service recipe") + public Response onboardWorkflowPackage(@Multipart(value = "file") Attachment file) { + String msg = "Upload package finished."; + boolean isSuccess = false; + DataHandler dh = file.getDataHandler(); + String fileName = "/camunda/webapps/" + dh.getName(); + File saveFile = new File(fileName); + if (saveFile.isFile()) { + msg = "Upload package failed: The Package already exist"; + } else { + try { + isSuccess = saveFile(dh.getInputStream(), fileName); + if (!isSuccess) { + msg = "Upload package failed: write file failed."; + } + } catch (IOException e) { + msg = "Upload package failed: Onboard File Exception!"; + } + } + Map<String, String> result = new HashMap<String, String>(); + result.put("result", String.valueOf(isSuccess)); + result.put("message", msg); + String resp = JSONObject.toJSONString(result); + return Response.status(200).header("Access-Control-Allow-Origin", "*").entity(resp).build(); + } + + /** + * Write the stream to file + * + * @param uploadStream the stream need to writh + * @param file the destination file + */ + private boolean saveFile(InputStream uploadStream, String file) { + try { + OutputStream outStream = new FileOutputStream(new File(file)); + int read = 0; + byte[] bytes = new byte[1024]; + while ((read = uploadStream.read(bytes)) != -1) { + outStream.write(bytes, 0, read); + } + outStream.flush(); + outStream.close(); + } catch (IOException e) { + logger.info("write stream to file failed"); + return false; + } + return true; + } +} diff --git a/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/CXFConfiguration.java b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/CXFConfiguration.java index 03feda6d0f..c6c60c21a6 100644 --- a/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/CXFConfiguration.java +++ b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/CXFConfiguration.java @@ -35,6 +35,7 @@ import org.onap.so.bpmn.common.adapter.sdnc.SDNCCallbackAdapterPortType; import org.onap.so.bpmn.common.adapter.vnf.VnfAdapterNotify; import org.onap.so.bpmn.common.workflow.service.WorkflowAsyncResource; import org.onap.so.bpmn.common.workflow.service.WorkflowMessageResource; +import org.onap.so.bpmn.common.workflow.service.WorkflowOnboardingSupport; import org.onap.so.bpmn.common.workflow.service.WorkflowResource; import org.onap.so.logging.cxf.interceptor.SOAPLoggingInInterceptor; import org.onap.so.logging.cxf.interceptor.SOAPLoggingOutInterceptor; @@ -63,6 +64,9 @@ public class CXFConfiguration { private WorkflowAsyncResource workflowAsyncResource; @Autowired + private WorkflowOnboardingSupport workflowOnboardingSupport; + + @Autowired private SOAuditLogContainerFilter soAuditLogContainerFilter; @Autowired @@ -76,7 +80,7 @@ public class CXFConfiguration { @Bean public ServletRegistrationBean cxfServlet() { - return new ServletRegistrationBean(new CXFServlet(), "/mso/*"); + return new ServletRegistrationBean(new CXFServlet(), "/*"); } @Bean @@ -103,7 +107,7 @@ public class CXFConfiguration { public Server rsServer() { JAXRSServerFactoryBean endpoint = new JAXRSServerFactoryBean(); endpoint.setBus(bus); - endpoint.setServiceBeans(Arrays.<Object>asList(wmr, workflowResource, workflowAsyncResource)); + endpoint.setServiceBeans(Arrays.<Object>asList(wmr, workflowResource, workflowAsyncResource, workflowOnboardingSupport)); endpoint.setAddress("/"); endpoint.setFeatures(Arrays.asList(createSwaggerFeature(), new LoggingFeature())); endpoint.setProviders(Arrays.asList(new JacksonJsonProvider(mapper), soAuditLogContainerFilter)); diff --git a/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/CamundaConfig.java b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/CamundaConfig.java new file mode 100644 index 0000000000..6358524006 --- /dev/null +++ b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/CamundaConfig.java @@ -0,0 +1,39 @@ +package org.onap.so.bpmn.infrastructure; + +import org.camunda.bpm.BpmPlatform; +import org.camunda.bpm.ProcessEngineService; +import org.camunda.bpm.engine.ProcessEngine; +import org.camunda.bpm.engine.RepositoryService; +import org.camunda.bpm.engine.RuntimeService; +import org.camunda.bpm.engine.spring.application.SpringServletProcessApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CamundaConfig { + + @Bean + public SpringServletProcessApplication springServletProcessApplication() { + return new SpringServletProcessApplication(); + } + + @Bean + public ProcessEngineService processEngineService() { + return BpmPlatform.getProcessEngineService(); + } + + @Bean + public ProcessEngine processEngine(ProcessEngineService processEngineService) { + return processEngineService.getDefaultProcessEngine(); + } + + @Bean + public RepositoryService repositoryService(ProcessEngine processEngine) { + return processEngine.getRepositoryService(); + } + + @Bean + public RuntimeService runtimeService(ProcessEngine processEngine) { + return processEngine.getRuntimeService(); + } +} diff --git a/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/MSOInfrastructureApplication.java b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/MSOInfrastructureApplication.java index 477dce1072..0bbe74ec4f 100644 --- a/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/MSOInfrastructureApplication.java +++ b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/MSOInfrastructureApplication.java @@ -39,7 +39,11 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; @@ -48,6 +52,12 @@ import org.springframework.context.annotation.Primary; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import javax.annotation.PostConstruct; +import java.util.List; +import java.util.concurrent.Executor; + +import static java.util.Collections.singletonMap; +import static org.springframework.boot.context.config.ConfigFileApplicationListener.*; /** * @since Version 1.0 * @@ -57,11 +67,21 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @EnableAsync @ComponentScan(basePackages = {"org.onap"}, nameGenerator = DefaultToShortClassNameBeanNameGenerator.class, excludeFilters = {@Filter(type = FilterType.ANNOTATION, classes = SpringBootApplication.class)}) +@EnableAutoConfiguration(exclude= FreeMarkerAutoConfiguration.class) +public class MSOInfrastructureApplication extends SpringBootServletInitializer { -public class MSOInfrastructureApplication { - + private static final String ADDITIONAL_CONFIG = "file:/camunda/app/config/override.yaml"; private static final Logger logger = LoggerFactory.getLogger(MSOInfrastructureApplication.class); - @Autowired + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application + .sources(MSOInfrastructureApplication.class) + .properties(singletonMap(CONFIG_ADDITIONAL_LOCATION_PROPERTY, ADDITIONAL_CONFIG)); + } + + + @Autowired private ProcessEngine processEngine; @Autowired @@ -95,17 +115,18 @@ public class MSOInfrastructureApplication { @PostConstruct public void postConstruct() { - try { - DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment(); - deployCustomWorkflows(deploymentBuilder); - } catch (Exception e) { - logger.warn("Unable to invoke deploymentBuilder ", e); - } + DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment(); +// try { +// DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment(); +// deployCustomWorkflows(deploymentBuilder); +// } catch (Exception e) { +// logger.warn("Unable to invoke deploymentBuilder: " + e.getMessage()); +// } } - @PreUndeploy - public void cleanup(ProcessEngine processEngine, ProcessApplicationInfo processApplicationInfo, - List<ProcessEngine> processEngines) {} +// @PreUndeploy +// public void cleanup(ProcessEngine processEngine, ProcessApplicationInfo processApplicationInfo, +// List<ProcessEngine> processEngines) {} @Bean @Primary @@ -121,9 +142,10 @@ public class MSOInfrastructureApplication { } public void deployCustomWorkflows(DeploymentBuilder deploymentBuilder) { - logger.debug("Attempting to deploy custom workflows"); + logger.info("Attempting to deploy custom workflows"); try { List<Workflow> workflows = catalogDbClient.findWorkflowBySource(SDC_SOURCE); + logger.info("SDC workflows: {}", workflows ); if (workflows != null && !workflows.isEmpty()) { for (Workflow workflow : workflows) { String workflowName = workflow.getName(); @@ -140,7 +162,7 @@ public class MSOInfrastructureApplication { deploymentBuilder.deploy(); } } catch (Exception e) { - logger.warn("Unable to deploy custom workflows ", e); + logger.error("Unable to deploy custom workflows ", e); } } } diff --git a/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/SecurityConfig.java b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/SecurityConfig.java new file mode 100644 index 0000000000..77f35d13d3 --- /dev/null +++ b/bpmn/mso-infrastructure-bpmn/src/main/java/org/onap/so/bpmn/infrastructure/SecurityConfig.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Modifications Copyright (c) 2019 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.bpmn.infrastructure; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + // super.configure(http); + http.authorizeRequests().anyRequest().permitAll().and().logout().permitAll(); + http.csrf().disable(); + } +} diff --git a/bpmn/mso-infrastructure-bpmn/src/main/resources/META-INF/processes.xml b/bpmn/mso-infrastructure-bpmn/src/main/resources/META-INF/processes.xml new file mode 100644 index 0000000000..8b93a4e404 --- /dev/null +++ b/bpmn/mso-infrastructure-bpmn/src/main/resources/META-INF/processes.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<process-application + xmlns="http://www.camunda.org/schema/1.0/ProcessApplication" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <process-archive name="mso_war_poc"> + <process-engine>default</process-engine> + <properties> + <property name="isDeleteUponUndeploy">true</property> + <property name="isScanForProcessDefinitions">true</property> + </properties> + </process-archive> + +</process-application> diff --git a/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml b/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml index e08cf0f578..26b0adbead 100644 --- a/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml +++ b/bpmn/mso-infrastructure-bpmn/src/main/resources/application.yaml @@ -1,12 +1,328 @@ -server: - port: 8080 - tomcat: - max-threads: 50 +# Copyright © 2018 AT&T USA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +aai: + auth: 221187EFA3AD4E33600DE0488F287099934CE65C3D0697BCECC00BB58E784E07CD74A24581DC31DBC086FF63DF116378776E9BE3D1325885 + dme2: + timeout: '30000' + endpoint: https://aai.onap:8443 + workflowAaiDistributionDelay: PT30S + pnfEntryNotificationTimeout: P14D +cds: + endpoint: cds-blueprints-processor-grpc + port: 9111 + auth: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== + timeout: 600 +camunda: + bpm: + admin-user: + id: admin + password: admin + history-level: full + job-execution: + max-pool-size: 30 + core-pool-size: 3 +entitymanager: + packagesToScan: com +pnf: + dmaap: + host: message-router + port: 3904 + protocol: http + uriPathPrefix: events + topicName: unauthenticated.PNF_READY + consumerGroup: consumerGroup + consumerId: consumerId + topicListenerDelayInSeconds: 5 +bpelURL: http://so-bpmn-infra.onap:8081 +msb-ip: msb-iag.onap +msb-port: 80 mso: + rainyDay: + retryDurationMultiplier: 2 + maxRetries: 5 + msoKey: 07a7159d3bf51a0e53be7a8f89699be7 + correlation: + timeout: 60 + logPath: logs + async: + core-pool-size: 50 + max-pool-size: 50 + queue-capacity: 500 + adapters: + completemsoprocess: + endpoint: http://so-openstack-adapter.onap:8087/CompleteMsoProcess + requestDb: + endpoint: http://so-request-db-adapter.onap:8083 + auth: Basic YnBlbDpwYXNzd29yZDEk + db: + auth: A3745B5DBE165EFCF101D85A6FC81C211AB8BF604F8861B6C413D5DC90F8F30E0139DE44B8A342F4EF70AF + password: wLg4sjrAFUS8rfVfdvTXeQ== + endpoint: http://so-request-db-adapter.onap:8083/services/RequestsDbAdapter + spring: + endpoint: http://so-request-db-adapter.onap:8083 + network: + endpoint: http://so-openstack-adapter.onap:8087/services/NetworkAdapter + rest: + endpoint: http://so-openstack-adapter.onap:8087/services/rest/v1/networks + openecomp: + db: + endpoint: http://so-request-db-adapter.onap:8083/services/RequestsDbAdapter + po: + auth: A3745B5DBE165EFCF101D85A6FC81C211AB8BF604F8861B6C413D5DC90F8F30E0139DE44B8A342F4EF70AF + sdnc: + endpoint: http://so-sdnc-adapter.onap:8086/adapters/SDNCAdapter + rest: + endpoint: http://so-sdnc-adapter.onap:8086/adapters/rest/v1/sdnc + timeout: PT60M + tenant: + endpoint: http://so-openstack-adapter.onap:8087/services/TenantAdapter + vnf: + endpoint: http://so-openstack-adapter.onap:8087/services/VnfAdapter + rest: + endpoint: http://so-openstack-adapter.onap:8087/services/rest/v1/vnfs + volume-groups: + rest: + endpoint: http://so-openstack-adapter.onap:8087/services/rest/v1/volume-groups + vnf-async: + endpoint: http://so-openstack-adapter.onap:8087/services/VnfAsync + vfc: + rest: + endpoint: http://so-vfc-adapter.onap:8084/services/v1/vfcadapter + workflow: + message: + endpoint: http://so-bpmn-infra.onap:8081/mso/WorkflowMessage + bpmn: + process: + historyTimeToLive: '30' + callbackRetryAttempts: '5' + catalog: + db: + endpoint: http://so-catalog-db-adapter.onap:8082/ecomp/mso/catalog + spring: + endpoint: http://so-catalog-db-adapter.onap:8082 + db: + auth: Basic YnBlbDpwYXNzd29yZDEk + default: + adapter: + namespace: http://org.onap.mso + healthcheck: + log: + debug: 'false' infra: - auditInventory: false - camundaAuth: AE2E9BE6EF9249085AF98689C4EE087736A5500629A72F35068FFB88813A023581DD6E765071F1C04075B36EA4213A -spring: + customer: + id: testCustIdInfra + po: + timeout: PT60M + request: + db: + endpoint: http://so-request-db-adapter.onap:8083/ + rollback: 'true' + sdnc: + password: 1D78CFC35382B6938A989066A7A7EAEF4FE933D2919BABA99EB4763737F39876C333EE5F + service: + agnostic: + sniro: + endpoint: /sniro/api/v2/placement + host: http://sniro-emulator:80 + site-name: CamundaEngine + sniro: + auth: test:testpwd + callback: http://so-openstack-adapter.onap:8087/adapters/rest/SDNCNotify + endpoint: http://replaceme:28090/optimizationInstance/V1/create + timeout: PT30M + oof: + auth: test:testpwd + callbackEndpoint: http://so-bpmn-infra.onap:8081/mso/WorkflowMessage + endpoint: https://oof-osdf.onap:8698/api/oof/v1/placement + timeout: PT30M + workflow: + CreateGenericVNFV1: + aai: + volume-group: + uri: /aai/v6/cloud-infrastructure/volume-groups/volume-group + default: + aai: + version: '14' + cloud-region: + version: '14' + generic-vnf: + version: '14' + v14: + customer: + uri: /aai/v14/business/customers/customer + generic-query: + uri: /aai/v14/search/generic-query + generic-vnf: + uri: /aai/v14/network/generic-vnfs/generic-vnf + l3-network: + uri: /aai/v14/network/l3-networks/l3-network + network-policy: + uri: /aai/v14/network/network-policies/network-policy + nodes-query: + uri: /aai/v14/search/nodes-query + route-table-reference: + uri: /aai/v14/network/route-table-references/route-table-reference + tenant: + uri: /aai/v14/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant + vce: + uri: /aai/v14/network/vces/vce + vpn-binding: + uri: /aai/v14/network/vpn-bindings/vpn-binding + sp-partner: + uri: /aai/v14/business/sp-partners/sp-partner + device: + uri: /aai/v14/network/devices/device + v11: + customer: + uri: /aai/v11/business/customers/customer + generic-query: + uri: /aai/v11/search/generic-query + generic-vnf: + uri: /aai/v11/network/generic-vnfs/generic-vnf + l3-network: + uri: /aai/v11/network/l3-networks/l3-network + network-policy: + uri: /aai/v11/network/network-policies/network-policy + nodes-query: + uri: /aai/v11/search/nodes-query + route-table-reference: + uri: /aai/v11/network/route-table-references/route-table-reference + tenant: + uri: /aai/v11/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant + vce: + uri: /aai/v11/network/vces/vce + vpn-binding: + uri: /aai/v11/network/vpn-bindings/vpn-binding + v8: + configuration: + uri: /aai/v11/network/configurations/configuration + customer: + uri: /aai/v8/business/customers/customer + generic-query: + uri: /aai/v8/search/generic-query + l3-network: + uri: /aai/v8/network/l3-networks/l3-network + network-policy: + uri: /aai/v8/network/network-policies/network-policy + nodes-query: + uri: /aai/v8/search/nodes-query + route-table-reference: + uri: /aai/v8/network/route-table-references/route-table-reference + tenant: + uri: /aai/v8/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant + vce: + uri: /aai/v8/network/vces/vce + vpn-binding: + uri: /aai/v8/network/vpn-bindings/vpn-binding + v9: + cloud-region: + uri: /aai/v9/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner + generic-vnf: + uri: /aai/v9/network/generic-vnfs/generic-vnf + retry: + attempts: '1' + deleteCinderVolumeV1: + aai: + volume-group: + uri: /aai/v6/cloud-infrastructure/volume-groups/volume-group + global: + default: + aai: + namespace: http://org.onap.aai.inventory/ + version: 14 + message: + endpoint: http://so-bpmn-infra.onap:8081/mso/WorkflowMessage + notification: + name: GenericNotificationServiceATT + sdnc: + replication: + delay: PT60S + sdncadapter: + callback: http://so-bpmn-infra.onap:8081/mso/SDNCAdapterCallbackService + vnfadapter: + create: + callback: http://so-bpmn-infra.onap:8081/mso/vnfAdapterNotify + delete: + callback: http://so-bpmn-infra.onap:8081/mso/vnfAdapterNotify + query: + callback: http://so-bpmn-infra.onap:8081/mso/vnfAdapterNotify + rollback: + callback: http://so-bpmn-infra.onap:8081/mso/vnfAdapterNotify + use: + qualified: + host: false + global: + dmaap: + username: testuser + password: alRyMzJ3NUNeakxl + host: http://10.42.111.36:904 + publisher: + topic: replaceme + naming: + endpoint: http://naming.demo.onap.com:8081/web/service/v1/genNetworkElementName + auth: Basic bTA0NzY4QG5vbi1wcm9kLm1zby5lY29tcC5hdHQuY29tOkF0dG0wNDc2OExpZmUhQA== +policy: + auth: Basic dGVzdHBkcDphbHBoYTEyMw== + default: + disposition: Skip + client: + auth: Basic bTAzNzQzOnBvbGljeVIwY2sk + endpoint: http://pdp.onap:8081/pdp/api/ + environment: TEST +sdnc: + auth: Basic YWRtaW46S3A4Yko0U1hzek0wV1hsaGFrM2VIbGNzZTJnQXc4NHZhb0dHbUp2VXkyVQ== + host: http://sdnc.onap:8282 + path: /restconf/operations/GENERIC-RESOURCE-API + si: + svc: + types: PORT-MIRROR,PPROBE +appc: + client: + topic: + read: + name: APPC-LCM-WRITE + timeout: 360000 + write: APPC-LCM-READ + sdnc: + read: SDNC-LCM-WRITE + write: SDNC-LCM-READ + response: + timeout: 360000 + key: VIlbtVl6YLhNUrtU + secret: 64AG2hF4pYeG2pq7CT6XwUOT + service: ueb + poolMembers: message-router.onap:3904,message-router.onap:3904 +sniro: + conductor: + enabled: true + host: http://sniro-emulator:80 + uri: /v1/release-orders + headers.auth: Basic dGVzdDp0ZXN0cHdk + manager: + timeout: PT30M + host: http://sniro-emulator:80 + uri.v1: /sniro/api/v2/placement + uri.v2: /sniro/api/placement/v2 + headers.auth: Basic dGVzdDp0ZXN0cHdk + headers.patchVersion: 1 + headers.minorVersion: 1 + headers.latestVersion: 2 +server: + port: 8081 + tomcat: + max-threads: 50 +spring: datasource: hikari: jdbcUrl: jdbc:mariadb://${DB_HOST}:${DB_PORT}/camundabpmn @@ -15,37 +331,42 @@ spring: driver-class-name: org.mariadb.jdbc.Driver pool-name: bpmn-pool registerMbeans: true - http: - multipart: - enabled: false - jersey: - application-path: /sobpmnengine - main: - allow-bean-definition-overriding: true -camunda: - bpm: - application: - delete-upon-undeploy: false - scan-for-process-definitions: true - deploy-changed-only: true - job-execution: - deployment-aware: true -#Actuator -management: - endpoints: - web: - base-path: /manage - exposure: - include: "*" - metrics: - se-global-registry: false - export: - prometheus: - enabled: true # Whether exporting of metrics to Prometheus is enabled. - step: 1m # Step size (i.e. reporting frequency) to use. + security: + usercredentials: + - + username: apihBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: sdncaBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: poBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: wmaBpmn + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPMN-Client + - + username: sniro + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: SNIRO-Client + - + username: mso_admin + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: ACTUATOR +so: + vnfm: + adapter: + url: https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/ + auth: Basic dm5mbTpwYXNzd29yZDEk org: onap: so: - adapters: - network: - encryptionKey: 07a7159d3bf51a0e53be7a8f89699be7 + cloud-owner: CloudOwner +logging: + level: + org: + onap: debug |